Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'phy-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Pull phy updates from Vinod Koul:
"Core:

- Add suuport for "rx-polarity" and "tx-polarity" device tree
properties and phy common properties to manage this

New Support:

- Qualcomm Glymur PCIe Gen4 2-lanes PCIe phy, DP and edp phy, USB UNI
PHY and SMB2370 eUSB2 repeater. SC8280xp QMP UFS PHY, Kaanapali
PCIe phy and QMP PHY, QCS615 QMP USB3+DP PHY and driver support for
that.

- SpacemiT PCIe/combo PHY and K1 USB2 PHY driver.

- HDMI 2.1 FRL configuration support and driver enabling for rockchip
samsung-hdptx driver

- TI TCAN1046 phy

- Renesas RZ/V2H(P) and RZ/V2N usb3

- Mediatek MT8188 hdmi-phy

- Google Tensor SoC USB PHY driver

- Apple Type-C PHY

Updates:

- Subsystem conversion for clock round_rate() to determine_rate()

- TI USB3 DT schema conversion

- Samsung ExynosAutov920 usb3, combo hsphy and ssphy support"

* tag 'phy-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (143 commits)
phy: ti: phy-j721e-wiz: convert from divider_round_rate() to divider_determine_rate()
dt-bindings: phy: ti,control-phy-otghs: convert to DT schema
dt-bindings: phy: ti,phy-usb3: convert to DT schema
phy: tegra: xusb: Remove unused powered_on variable
phy: renesas: rcar-gen3-usb2: add regulator dependency
phy: GOOGLE_USB: add TYPEC dependency
phy: enter drivers/phy/Makefile even without CONFIG_GENERIC_PHY
phy: renesas: rcar-gen3-usb2: Use mux-state for phyrst management
phy: renesas: rcar-gen3-usb2: Add regulator for OTG VBUS control
phy: renesas: rcar-gen3-usb2: Use devm_pm_runtime_enable()
phy: renesas: rcar-gen3-usb2: Factor out VBUS control logic
dt-bindings: phy: renesas,usb2-phy: Document RZ/G3E SoC
dt-bindings: phy: renesas,usb2-phy: Document mux-states property
dt-bindings: phy: renesas,usb2-phy: Document USB VBUS regulator
phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support
phy: rockchip: samsung-hdptx: Extend rk_hdptx_phy_verify_hdmi_config() helper
phy: rockchip: samsung-hdptx: Switch to driver specific HDMI config
phy: rockchip: samsung-hdptx: Drop hw_rate driver data
phy: rockchip: samsung-hdptx: Compute clk rate from PLL config
phy: rockchip: samsung-hdptx: Cleanup *_cmn_init_seq lists
...

+11325 -876
+222
Documentation/devicetree/bindings/phy/apple,atcphy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/apple,atcphy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Apple Type-C PHY (ATCPHY) 8 + 9 + maintainers: 10 + - Sven Peter <sven@kernel.org> 11 + 12 + description: > 13 + The Apple Type-C PHY (ATCPHY) is a combined PHY for USB 2.0, USB 3.x, 14 + USB4/Thunderbolt, and DisplayPort connectivity via Type-C ports found in 15 + Apple Silicon SoCs. 16 + 17 + The PHY handles muxing between these different protocols and also provides the 18 + reset controller for the attached DWC3 USB controller. 19 + 20 + It is designed for USB4 operation and does not handle individual differential 21 + pairs as distinct DisplayPort lanes. Any reference to lane in this binding 22 + hence refers to two differential pairs (RX and TX) as used in USB terminology. 23 + 24 + In order to correctly setup these lanes for the various modes calibration 25 + values copied from Apple's firmware and converted to the format described 26 + below by our bootloader m1n1 are required. Without these only USB2 operation 27 + is possible. 28 + 29 + allOf: 30 + - $ref: /schemas/usb/usb-switch.yaml# 31 + 32 + $defs: 33 + apple,tunable: 34 + $ref: /schemas/types.yaml#/definitions/uint32-matrix 35 + items: 36 + items: 37 + - description: Register offset 38 + - description: Mask to be applied to the register value 39 + - description: Bits to be set after applying the mask 40 + description: > 41 + List of (register offset, mask, value) tuples copied from Apple's Device 42 + Tree by our bootloader m1n1 and used to configure the PHY. These values 43 + even vary for a single product/device and likely contain calibration 44 + values determined by Apple at manufacturing time. 45 + Unless otherwise noted these tunables are always applied to the core 46 + register region. 47 + 48 + properties: 49 + compatible: 50 + oneOf: 51 + - items: 52 + - enum: 53 + - apple,t6000-atcphy 54 + - apple,t6020-atcphy 55 + - apple,t8112-atcphy 56 + - const: apple,t8103-atcphy 57 + - const: apple,t8103-atcphy 58 + 59 + reg: 60 + items: 61 + - description: Common controls for all PHYs (USB2/3/4, DisplayPort, TBT) 62 + - description: DisplayPort Alternate Mode PHY specific controls 63 + - description: Type-C PHY AXI to Apple Fabric interconnect controls 64 + - description: USB2 PHY specific controls 65 + - description: USB3 PIPE interface controls 66 + 67 + reg-names: 68 + items: 69 + - const: core 70 + - const: lpdptx 71 + - const: axi2af 72 + - const: usb2phy 73 + - const: pipehandler 74 + 75 + "#phy-cells": 76 + const: 1 77 + 78 + "#reset-cells": 79 + const: 0 80 + 81 + mode-switch: true 82 + orientation-switch: true 83 + 84 + power-domains: 85 + maxItems: 1 86 + 87 + ports: 88 + $ref: /schemas/graph.yaml#/properties/ports 89 + properties: 90 + port@0: 91 + $ref: /schemas/graph.yaml#/properties/port 92 + description: Outgoing connection to the SS port of the Type-C connector. 93 + 94 + port@1: 95 + $ref: /schemas/graph.yaml#/properties/port 96 + description: Incoming endpoint from the USB3 controller. 97 + 98 + port@2: 99 + $ref: /schemas/graph.yaml#/properties/port 100 + description: Incoming endpoint from the DisplayPort controller. 101 + 102 + port@3: 103 + $ref: /schemas/graph.yaml#/properties/port 104 + description: Incoming endpoint from the USB4/Thunderbolt controller. 105 + 106 + apple,tunable-common-a: 107 + $ref: "#/$defs/apple,tunable" 108 + description: > 109 + Common tunables required for all modes, applied before tunable-axi2af. 110 + 111 + apple,tunable-axi2af: 112 + $ref: "#/$defs/apple,tunable" 113 + description: > 114 + AXI to Apple Fabric tunables, required for all modes. Unlike all other 115 + tunables these are applied to the axi2af region. 116 + 117 + apple,tunable-common-b: 118 + $ref: "#/$defs/apple,tunable" 119 + description: > 120 + Common tunables required for all modes, applied after tunable-axi2af. 121 + 122 + apple,tunable-lane0-usb: 123 + $ref: "#/$defs/apple,tunable" 124 + description: USB3 tunables for lane 0. 125 + 126 + apple,tunable-lane1-usb: 127 + $ref: "#/$defs/apple,tunable" 128 + description: USB3 tunables for lane 1. 129 + 130 + apple,tunable-lane0-cio: 131 + $ref: "#/$defs/apple,tunable" 132 + description: USB4/Thunderbolt ("Converged IO") tunables for lane 0. 133 + 134 + apple,tunable-lane1-cio: 135 + $ref: "#/$defs/apple,tunable" 136 + description: USB4/Thunderbolt ("Converged IO") tunables for lane 1. 137 + 138 + apple,tunable-lane0-dp: 139 + $ref: "#/$defs/apple,tunable" 140 + description: > 141 + DisplayPort tunables for lane 0. 142 + 143 + Note that lane here refers to a USB RX and TX pair re-used for DisplayPort 144 + and not to an individual DisplayPort differential lane. 145 + 146 + apple,tunable-lane1-dp: 147 + $ref: "#/$defs/apple,tunable" 148 + description: > 149 + DisplayPort tunables for lane 1. 150 + 151 + Note that lane here refers to a USB RX and TX pair re-used for DisplayPort 152 + and not to an individual DisplayPort differential lane. 153 + 154 + required: 155 + - compatible 156 + - reg 157 + - reg-names 158 + - "#phy-cells" 159 + - "#reset-cells" 160 + - orientation-switch 161 + - mode-switch 162 + - power-domains 163 + - ports 164 + 165 + additionalProperties: false 166 + 167 + examples: 168 + - | 169 + phy@83000000 { 170 + compatible = "apple,t8103-atcphy"; 171 + reg = <0x83000000 0x4c000>, 172 + <0x83050000 0x8000>, 173 + <0x80000000 0x4000>, 174 + <0x82a90000 0x4000>, 175 + <0x82a84000 0x4000>; 176 + reg-names = "core", "lpdptx", "axi2af", "usb2phy", 177 + "pipehandler"; 178 + 179 + #phy-cells = <1>; 180 + #reset-cells = <0>; 181 + 182 + orientation-switch; 183 + mode-switch; 184 + power-domains = <&ps_atc0_usb>; 185 + 186 + ports { 187 + #address-cells = <1>; 188 + #size-cells = <0>; 189 + 190 + port@0 { 191 + reg = <0>; 192 + 193 + endpoint { 194 + remote-endpoint = <&typec_connector_ss>; 195 + }; 196 + }; 197 + 198 + port@1 { 199 + reg = <1>; 200 + 201 + endpoint { 202 + remote-endpoint = <&dwc3_ss_out>; 203 + }; 204 + }; 205 + 206 + port@2 { 207 + reg = <2>; 208 + 209 + endpoint { 210 + remote-endpoint = <&dcp_dp_out>; 211 + }; 212 + }; 213 + 214 + port@3 { 215 + reg = <3>; 216 + 217 + endpoint { 218 + remote-endpoint = <&acio_tbt_out>; 219 + }; 220 + }; 221 + }; 222 + };
+70 -1
Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
··· 20 20 "#phy-cells": 21 21 const: 1 22 22 23 + "#address-cells": 24 + const: 1 25 + 26 + "#size-cells": 27 + const: 0 28 + 29 + patternProperties: 30 + "^phy@[0-7]$": 31 + type: object 32 + description: SerDes lane (single RX/TX differential pair) 33 + 34 + properties: 35 + reg: 36 + minimum: 0 37 + maximum: 7 38 + description: Lane index as seen in register map 39 + 40 + "#phy-cells": 41 + const: 0 42 + 43 + required: 44 + - reg 45 + - "#phy-cells" 46 + 47 + additionalProperties: false 48 + 23 49 required: 24 50 - compatible 25 51 - reg ··· 58 32 soc { 59 33 #address-cells = <2>; 60 34 #size-cells = <2>; 61 - serdes_1: phy@1ea0000 { 35 + 36 + serdes@1ea0000 { 62 37 compatible = "fsl,lynx-28g"; 63 38 reg = <0x0 0x1ea0000 0x0 0x1e30>; 39 + #address-cells = <1>; 40 + #size-cells = <0>; 64 41 #phy-cells = <1>; 42 + 43 + phy@0 { 44 + reg = <0>; 45 + #phy-cells = <0>; 46 + }; 47 + 48 + phy@1 { 49 + reg = <1>; 50 + #phy-cells = <0>; 51 + }; 52 + 53 + phy@2 { 54 + reg = <2>; 55 + #phy-cells = <0>; 56 + }; 57 + 58 + phy@3 { 59 + reg = <3>; 60 + #phy-cells = <0>; 61 + }; 62 + 63 + phy@4 { 64 + reg = <4>; 65 + #phy-cells = <0>; 66 + }; 67 + 68 + phy@5 { 69 + reg = <5>; 70 + #phy-cells = <0>; 71 + }; 72 + 73 + phy@6 { 74 + reg = <6>; 75 + #phy-cells = <0>; 76 + }; 77 + 78 + phy@7 { 79 + reg = <7>; 80 + #phy-cells = <0>; 81 + }; 65 82 }; 66 83 };
+133
Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2025, Google LLC 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/phy/google,lga-usb-phy.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Google Tensor Series G5 (Laguna) USB PHY 9 + 10 + maintainers: 11 + - Roy Luo <royluo@google.com> 12 + 13 + description: 14 + Describes the USB PHY interfaces integrated with the DWC3 USB controller on 15 + Google Tensor SoCs, starting with the G5 generation (laguna). 16 + Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP 17 + and USB3.2/DisplayPort combo PHY IP. 18 + 19 + properties: 20 + compatible: 21 + const: google,lga-usb-phy 22 + 23 + reg: 24 + items: 25 + - description: USB3.2/DisplayPort combo PHY core registers. 26 + - description: USB3.2/DisplayPort combo PHY Type-C Assist registers. 27 + - description: eUSB 2.0 PHY core registers. 28 + - description: Top-level wrapper registers for the integrated PHYs. 29 + 30 + reg-names: 31 + items: 32 + - const: usb3_core 33 + - const: usb3_tca 34 + - const: usb2_core 35 + - const: usbdp_top 36 + 37 + "#phy-cells": 38 + description: | 39 + The phandle's argument in the PHY specifier selects one of the three 40 + following PHY interfaces. 41 + - 0 for USB high-speed. 42 + - 1 for USB super-speed. 43 + - 2 for DisplayPort. 44 + const: 1 45 + 46 + clocks: 47 + items: 48 + - description: USB2 PHY clock. 49 + - description: USB2 PHY APB clock. 50 + - description: USB3.2/DisplayPort combo PHY clock. 51 + - description: USB3.2/DisplayPort combo PHY firmware clock. 52 + 53 + clock-names: 54 + items: 55 + - const: usb2 56 + - const: usb2_apb 57 + - const: usb3 58 + - const: usb3_fw 59 + 60 + resets: 61 + items: 62 + - description: USB2 PHY reset. 63 + - description: USB2 PHY APB reset. 64 + - description: USB3.2/DisplayPort combo PHY reset. 65 + 66 + reset-names: 67 + items: 68 + - const: usb2 69 + - const: usb2_apb 70 + - const: usb3 71 + 72 + power-domains: 73 + maxItems: 1 74 + 75 + orientation-switch: 76 + type: boolean 77 + description: 78 + Indicates the PHY as a handler of USB Type-C orientation changes 79 + 80 + google,usb-cfg-csr: 81 + description: 82 + A phandle to a syscon node used to access the USB configuration 83 + registers. These registers are the top-level wrapper of the USB 84 + subsystem and provide control and status for the integrated USB 85 + controller and USB PHY. 86 + $ref: /schemas/types.yaml#/definitions/phandle-array 87 + items: 88 + - items: 89 + - description: phandle to the syscon node. 90 + - description: USB2 PHY configuration register offset. 91 + 92 + required: 93 + - compatible 94 + - reg 95 + - reg-names 96 + - "#phy-cells" 97 + - clocks 98 + - clock-names 99 + - resets 100 + - reset-names 101 + - power-domains 102 + - orientation-switch 103 + - google,usb-cfg-csr 104 + 105 + additionalProperties: false 106 + 107 + examples: 108 + - | 109 + soc { 110 + #address-cells = <2>; 111 + #size-cells = <2>; 112 + 113 + usb-phy@c410000 { 114 + compatible = "google,lga-usb-phy"; 115 + reg = <0 0x0c410000 0 0x20000>, 116 + <0 0x0c430000 0 0x1000>, 117 + <0 0x0c440000 0 0x10000>, 118 + <0 0x0c637000 0 0xa0>; 119 + reg-names = "usb3_core", "usb3_tca", "usb2_core", "usbdp_top"; 120 + #phy-cells = <1>; 121 + clocks = <&hsion_usb2_phy_clk>, <&hsion_u2phy_apb_clk>, 122 + <&hsion_usb3_phy_clk>, <&hsion_usb3_phy_fw_clk>; 123 + clock-names = "usb2", "usb2_apb", "usb3", "usb3_fw"; 124 + resets = <&hsion_resets_usb2_phy>, 125 + <&hsion_resets_u2phy_apb>, 126 + <&hsion_resets_usb3_phy>; 127 + reset-names = "usb2", "usb2_apb", "usb3"; 128 + power-domains = <&hsio_n_usb_pd>; 129 + orientation-switch; 130 + google,usb-cfg-csr = <&usb_cfg_csr 0x14>; 131 + }; 132 + }; 133 + ...
+29 -1
Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
··· 18 18 compatible: 19 19 oneOf: 20 20 - enum: 21 + - qcom,glymur-dp-phy 21 22 - qcom,sa8775p-edp-phy 22 23 - qcom,sc7280-edp-phy 23 24 - qcom,sc8180x-edp-phy ··· 38 37 - description: PLL register block 39 38 40 39 clocks: 41 - maxItems: 2 40 + minItems: 2 41 + maxItems: 3 42 42 43 43 clock-names: 44 + minItems: 2 44 45 items: 45 46 - const: aux 46 47 - const: cfg_ahb 48 + - const: ref 47 49 48 50 "#clock-cells": 49 51 const: 1 ··· 67 63 - clock-names 68 64 - "#clock-cells" 69 65 - "#phy-cells" 66 + 67 + allOf: 68 + - if: 69 + properties: 70 + compatible: 71 + enum: 72 + - qcom,glymur-dp-phy 73 + - qcom,x1e80100-dp-phy 74 + then: 75 + properties: 76 + clocks: 77 + minItems: 3 78 + maxItems: 3 79 + clock-names: 80 + minItems: 3 81 + maxItems: 3 82 + else: 83 + properties: 84 + clocks: 85 + minItems: 2 86 + maxItems: 2 87 + clock-names: 88 + minItems: 2 89 + maxItems: 2 70 90 71 91 additionalProperties: false 72 92
+7 -3
Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml
··· 15 15 16 16 properties: 17 17 compatible: 18 - items: 19 - - enum: 20 - - qcom,sm8750-m31-eusb2-phy 18 + oneOf: 19 + - items: 20 + - enum: 21 + - qcom,glymur-m31-eusb2-phy 22 + - qcom,kaanapali-m31-eusb2-phy 23 + - const: qcom,sm8750-m31-eusb2-phy 24 + - const: qcom,sm8750-m31-eusb2-phy 21 25 22 26 reg: 23 27 maxItems: 1
+111
Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615) 8 + 9 + maintainers: 10 + - Xiangxu Yin <xiangxu.yin@oss.qualcomm.com> 11 + 12 + description: 13 + The QMP PHY controller supports physical layer functionality for both USB3 14 + and DisplayPort over USB-C. While it enables mode switching between USB3 and 15 + DisplayPort, but does not support combo mode. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - qcom,qcs615-qmp-usb3-dp-phy 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + clocks: 26 + maxItems: 4 27 + 28 + clock-names: 29 + items: 30 + - const: aux 31 + - const: ref 32 + - const: cfg_ahb 33 + - const: pipe 34 + 35 + resets: 36 + maxItems: 2 37 + 38 + reset-names: 39 + items: 40 + - const: phy_phy 41 + - const: dp_phy 42 + 43 + vdda-phy-supply: true 44 + 45 + vdda-pll-supply: true 46 + 47 + "#clock-cells": 48 + const: 1 49 + description: 50 + See include/dt-bindings/phy/phy-qcom-qmp.h 51 + 52 + "#phy-cells": 53 + const: 1 54 + description: 55 + See include/dt-bindings/phy/phy-qcom-qmp.h 56 + 57 + qcom,tcsr-reg: 58 + $ref: /schemas/types.yaml#/definitions/phandle-array 59 + items: 60 + - items: 61 + - description: phandle to TCSR hardware block 62 + - description: offset of the VLS CLAMP register 63 + - description: offset of the PHY mode register 64 + description: Clamp and PHY mode register present in the TCSR 65 + 66 + required: 67 + - compatible 68 + - reg 69 + - clocks 70 + - clock-names 71 + - resets 72 + - reset-names 73 + - vdda-phy-supply 74 + - vdda-pll-supply 75 + - "#clock-cells" 76 + - "#phy-cells" 77 + - qcom,tcsr-reg 78 + 79 + additionalProperties: false 80 + 81 + examples: 82 + - | 83 + #include <dt-bindings/clock/qcom,qcs615-gcc.h> 84 + #include <dt-bindings/clock/qcom,rpmh.h> 85 + 86 + phy@88e8000 { 87 + compatible = "qcom,qcs615-qmp-usb3-dp-phy"; 88 + reg = <0x88e8000 0x2000>; 89 + 90 + clocks = <&gcc GCC_USB2_SEC_PHY_AUX_CLK>, 91 + <&gcc GCC_USB3_SEC_CLKREF_CLK>, 92 + <&gcc GCC_AHB2PHY_WEST_CLK>, 93 + <&gcc GCC_USB2_SEC_PHY_PIPE_CLK>; 94 + clock-names = "aux", 95 + "ref", 96 + "cfg_ahb", 97 + "pipe"; 98 + 99 + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, 100 + <&gcc GCC_USB3_DP_PHY_SEC_BCR>; 101 + reset-names = "phy_phy", 102 + "dp_phy"; 103 + 104 + vdda-phy-supply = <&vreg_l5a>; 105 + vdda-pll-supply = <&vreg_l12a>; 106 + 107 + #clock-cells = <1>; 108 + #phy-cells = <1>; 109 + 110 + qcom,tcsr-reg = <&tcsr 0xbff0 0xb24c>; 111 + };
+6
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
··· 16 16 properties: 17 17 compatible: 18 18 enum: 19 + - qcom,glymur-qmp-gen4x2-pcie-phy 19 20 - qcom,glymur-qmp-gen5x4-pcie-phy 21 + - qcom,kaanapali-qmp-gen3x2-pcie-phy 20 22 - qcom,qcs615-qmp-gen3x1-pcie-phy 21 23 - qcom,qcs8300-qmp-gen4x2-pcie-phy 22 24 - qcom,sa8775p-qmp-gen4x2-pcie-phy ··· 148 146 compatible: 149 147 contains: 150 148 enum: 149 + - qcom,kaanapali-qmp-gen3x2-pcie-phy 151 150 - qcom,qcs615-qmp-gen3x1-pcie-phy 152 151 - qcom,sar2130p-qmp-gen3x2-pcie-phy 153 152 - qcom,sc8180x-qmp-pcie-phy ··· 181 178 compatible: 182 179 contains: 183 180 enum: 181 + - qcom,glymur-qmp-gen4x2-pcie-phy 184 182 - qcom,glymur-qmp-gen5x4-pcie-phy 185 183 - qcom,qcs8300-qmp-gen4x2-pcie-phy 186 184 - qcom,sa8775p-qmp-gen4x2-pcie-phy ··· 206 202 compatible: 207 203 contains: 208 204 enum: 205 + - qcom,glymur-qmp-gen4x2-pcie-phy 209 206 - qcom,glymur-qmp-gen5x4-pcie-phy 207 + - qcom,kaanapali-qmp-gen3x2-pcie-phy 210 208 - qcom,sm8550-qmp-gen4x2-pcie-phy 211 209 - qcom,sm8650-qmp-gen4x2-pcie-phy 212 210 - qcom,x1e80100-qmp-gen3x2-pcie-phy
+6
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
··· 22 22 - const: qcom,sm6115-qmp-ufs-phy 23 23 - items: 24 24 - enum: 25 + - qcom,x1e80100-qmp-ufs-phy 26 + - const: qcom,sm8550-qmp-ufs-phy 27 + - items: 28 + - enum: 25 29 - qcom,qcs8300-qmp-ufs-phy 26 30 - const: qcom,sa8775p-qmp-ufs-phy 27 31 - items: ··· 33 29 - qcom,kaanapali-qmp-ufs-phy 34 30 - const: qcom,sm8750-qmp-ufs-phy 35 31 - enum: 32 + - qcom,milos-qmp-ufs-phy 36 33 - qcom,msm8996-qmp-ufs-phy 37 34 - qcom,msm8998-qmp-ufs-phy 38 35 - qcom,sa8775p-qmp-ufs-phy ··· 103 98 compatible: 104 99 contains: 105 100 enum: 101 + - qcom,milos-qmp-ufs-phy 106 102 - qcom,msm8998-qmp-ufs-phy 107 103 - qcom,sa8775p-qmp-ufs-phy 108 104 - qcom,sc7180-qmp-ufs-phy
+18
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
··· 16 16 properties: 17 17 compatible: 18 18 enum: 19 + - qcom,glymur-qmp-usb3-uni-phy 19 20 - qcom,ipq5424-qmp-usb3-phy 20 21 - qcom,ipq6018-qmp-usb3-phy 21 22 - qcom,ipq8074-qmp-usb3-phy ··· 61 60 vdda-phy-supply: true 62 61 63 62 vdda-pll-supply: true 63 + 64 + refgen-supply: true 64 65 65 66 "#clock-cells": 66 67 const: 0 ··· 116 113 compatible: 117 114 contains: 118 115 enum: 116 + - qcom,glymur-qmp-usb3-uni-phy 119 117 - qcom,qcs8300-qmp-usb3-uni-phy 120 118 - qcom,qdu1000-qmp-usb3-uni-phy 121 119 - qcom,sa8775p-qmp-usb3-uni-phy ··· 160 156 compatible: 161 157 contains: 162 158 enum: 159 + - qcom,glymur-qmp-usb3-uni-phy 163 160 - qcom,sa8775p-qmp-usb3-uni-phy 164 161 - qcom,sc8180x-qmp-usb3-uni-phy 165 162 - qcom,sc8280xp-qmp-usb3-uni-phy ··· 168 163 then: 169 164 required: 170 165 - power-domains 166 + 167 + - if: 168 + properties: 169 + compatible: 170 + contains: 171 + enum: 172 + - qcom,glymur-qmp-usb3-uni-phy 173 + then: 174 + required: 175 + - refgen-supply 176 + else: 177 + properties: 178 + refgen-supply: false 171 179 172 180 additionalProperties: false 173 181
+46 -24
Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
··· 15 15 16 16 properties: 17 17 compatible: 18 - enum: 19 - - qcom,sar2130p-qmp-usb3-dp-phy 20 - - qcom,sc7180-qmp-usb3-dp-phy 21 - - qcom,sc7280-qmp-usb3-dp-phy 22 - - qcom,sc8180x-qmp-usb3-dp-phy 23 - - qcom,sc8280xp-qmp-usb43dp-phy 24 - - qcom,sdm845-qmp-usb3-dp-phy 25 - - qcom,sm6350-qmp-usb3-dp-phy 26 - - qcom,sm8150-qmp-usb3-dp-phy 27 - - qcom,sm8250-qmp-usb3-dp-phy 28 - - qcom,sm8350-qmp-usb3-dp-phy 29 - - qcom,sm8450-qmp-usb3-dp-phy 30 - - qcom,sm8550-qmp-usb3-dp-phy 31 - - qcom,sm8650-qmp-usb3-dp-phy 32 - - qcom,sm8750-qmp-usb3-dp-phy 33 - - qcom,x1e80100-qmp-usb3-dp-phy 18 + oneOf: 19 + - items: 20 + - enum: 21 + - qcom,kaanapali-qmp-usb3-dp-phy 22 + - const: qcom,sm8750-qmp-usb3-dp-phy 23 + - enum: 24 + - qcom,glymur-qmp-usb3-dp-phy 25 + - qcom,sar2130p-qmp-usb3-dp-phy 26 + - qcom,sc7180-qmp-usb3-dp-phy 27 + - qcom,sc7280-qmp-usb3-dp-phy 28 + - qcom,sc8180x-qmp-usb3-dp-phy 29 + - qcom,sc8280xp-qmp-usb43dp-phy 30 + - qcom,sdm845-qmp-usb3-dp-phy 31 + - qcom,sm6350-qmp-usb3-dp-phy 32 + - qcom,sm8150-qmp-usb3-dp-phy 33 + - qcom,sm8250-qmp-usb3-dp-phy 34 + - qcom,sm8350-qmp-usb3-dp-phy 35 + - qcom,sm8450-qmp-usb3-dp-phy 36 + - qcom,sm8550-qmp-usb3-dp-phy 37 + - qcom,sm8650-qmp-usb3-dp-phy 38 + - qcom,sm8750-qmp-usb3-dp-phy 39 + - qcom,x1e80100-qmp-usb3-dp-phy 34 40 35 41 reg: 36 42 maxItems: 1 ··· 68 62 vdda-phy-supply: true 69 63 70 64 vdda-pll-supply: true 65 + 66 + refgen-supply: true 71 67 72 68 "#clock-cells": 73 69 const: 1 ··· 202 194 - if: 203 195 properties: 204 196 compatible: 205 - enum: 206 - - qcom,sar2130p-qmp-usb3-dp-phy 207 - - qcom,sc8280xp-qmp-usb43dp-phy 208 - - qcom,sm6350-qmp-usb3-dp-phy 209 - - qcom,sm8550-qmp-usb3-dp-phy 210 - - qcom,sm8650-qmp-usb3-dp-phy 211 - - qcom,sm8750-qmp-usb3-dp-phy 212 - - qcom,x1e80100-qmp-usb3-dp-phy 197 + contains: 198 + enum: 199 + - qcom,glymur-qmp-usb3-dp-phy 200 + - qcom,sar2130p-qmp-usb3-dp-phy 201 + - qcom,sc8280xp-qmp-usb43dp-phy 202 + - qcom,sm6350-qmp-usb3-dp-phy 203 + - qcom,sm8550-qmp-usb3-dp-phy 204 + - qcom,sm8650-qmp-usb3-dp-phy 205 + - qcom,sm8750-qmp-usb3-dp-phy 206 + - qcom,x1e80100-qmp-usb3-dp-phy 213 207 then: 214 208 required: 215 209 - power-domains 216 210 else: 217 211 properties: 218 212 power-domains: false 213 + 214 + - if: 215 + properties: 216 + compatible: 217 + enum: 218 + - qcom,glymur-qmp-usb3-dp-phy 219 + then: 220 + required: 221 + - refgen-supply 222 + else: 223 + properties: 224 + refgen-supply: false 219 225 220 226 additionalProperties: false 221 227
+9
Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml
··· 24 24 - qcom,pm8550b-eusb2-repeater 25 25 - qcom,pmiv0104-eusb2-repeater 26 26 - qcom,smb2360-eusb2-repeater 27 + - qcom,smb2370-eusb2-repeater 27 28 28 29 reg: 29 30 maxItems: 1 ··· 59 58 description: FS Differential TX Output Resistance Tuning 60 59 minimum: 0 61 60 maximum: 7 61 + 62 + qcom,squelch-detector-bp: 63 + description: 64 + This adjusts the voltage level for the threshold used to detect valid 65 + high-speed data. 66 + minimum: -6000 67 + maximum: 1000 68 + multipleOf: 1000 62 69 63 70 required: 64 71 - compatible
+8 -1
Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml
··· 11 11 12 12 properties: 13 13 compatible: 14 - const: renesas,r9a09g047-usb3-phy 14 + oneOf: 15 + - const: renesas,r9a09g047-usb3-phy # RZ/G3E 16 + 17 + - items: 18 + - enum: 19 + - renesas,r9a09g056-usb3-phy # RZ/V2N 20 + - renesas,r9a09g057-usb3-phy # RZ/V2H(P) 21 + - const: renesas,r9a09g047-usb3-phy 15 22 16 23 reg: 17 24 maxItems: 1
+14 -1
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
··· 41 41 - const: renesas,rzg2l-usb2-phy 42 42 43 43 - items: 44 - - const: renesas,usb2-phy-r9a09g056 # RZ/V2N 44 + - enum: 45 + - renesas,usb2-phy-r9a09g047 # RZ/G3E 46 + - renesas,usb2-phy-r9a09g056 # RZ/V2N 45 47 - const: renesas,usb2-phy-r9a09g057 46 48 47 49 - const: renesas,usb2-phy-r9a09g077 # RZ/T2H ··· 91 89 Phandle to a regulator that provides power to the VBUS. This regulator 92 90 will be managed during the PHY power on/off sequence. 93 91 92 + vbus-regulator: 93 + $ref: /schemas/regulator/regulator.yaml# 94 + description: USB VBUS internal regulator 95 + type: object 96 + unevaluatedProperties: false 97 + 94 98 renesas,no-otg-pins: 95 99 $ref: /schemas/types.yaml#/definitions/flag 96 100 description: | 97 101 specify when a board does not provide proper otg pins. 98 102 99 103 dr_mode: true 104 + 105 + mux-states: 106 + description: 107 + phandle to a mux controller node that select the source for USB VBUS. 108 + maxItems: 1 100 109 101 110 if: 102 111 properties:
+3
Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
··· 36 36 minItems: 1 37 37 maxItems: 4 38 38 39 + power-domains: 40 + maxItems: 1 41 + 39 42 samsung,pmu-syscon: 40 43 $ref: /schemas/types.yaml#/definitions/phandle-array 41 44 maxItems: 1
+51
Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
··· 34 34 - samsung,exynos7870-usbdrd-phy 35 35 - samsung,exynos850-usbdrd-phy 36 36 - samsung,exynos990-usbdrd-phy 37 + - samsung,exynosautov920-usb31drd-combo-ssphy 38 + - samsung,exynosautov920-usbdrd-combo-hsphy 39 + - samsung,exynosautov920-usbdrd-phy 37 40 38 41 clocks: 39 42 minItems: 1 ··· 53 50 associated by phy name. It is used to determine bit values for clock 54 51 settings register. For Exynos5420 this is given as 'sclk_usbphy30' 55 52 in the CMU. It's not needed for Exynos2200. 53 + 54 + power-domains: 55 + maxItems: 1 56 56 57 57 "#phy-cells": 58 58 const: 1 ··· 115 109 116 110 vddh-usbdp-supply: 117 111 description: VDDh power supply for the USB DP phy. 112 + 113 + dvdd-supply: 114 + description: 0.75V power supply for the USB phy. 115 + 116 + vdd18-supply: 117 + description: 1.8V power supply for the USB phy. 118 + 119 + vdd33-supply: 120 + description: 3.3V power supply for the USB phy. 118 121 119 122 required: 120 123 - compatible ··· 236 221 - samsung,exynos7870-usbdrd-phy 237 222 - samsung,exynos850-usbdrd-phy 238 223 - samsung,exynos990-usbdrd-phy 224 + - samsung,exynosautov920-usb31drd-combo-ssphy 225 + - samsung,exynosautov920-usbdrd-combo-hsphy 226 + - samsung,exynosautov920-usbdrd-phy 239 227 then: 240 228 properties: 241 229 clocks: ··· 255 237 256 238 reg-names: 257 239 maxItems: 1 240 + 241 + - if: 242 + properties: 243 + compatible: 244 + contains: 245 + enum: 246 + - samsung,exynosautov920-usb31drd-combo-ssphy 247 + - samsung,exynosautov920-usbdrd-combo-hsphy 248 + - samsung,exynosautov920-usbdrd-phy 249 + then: 250 + required: 251 + - dvdd-supply 252 + - vdd18-supply 253 + 254 + else: 255 + properties: 256 + dvdd-supply: false 257 + vdd18-supply: false 258 + 259 + - if: 260 + properties: 261 + compatible: 262 + contains: 263 + enum: 264 + - samsung,exynosautov920-usbdrd-combo-hsphy 265 + - samsung,exynosautov920-usbdrd-phy 266 + then: 267 + required: 268 + - vdd33-supply 269 + 270 + else: 271 + properties: 272 + vdd33-supply: false 258 273 259 274 unevaluatedProperties: false 260 275
+114
Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: SpacemiT K1 PCIe/USB3 Combo PHY 8 + 9 + maintainers: 10 + - Alex Elder <elder@riscstar.com> 11 + 12 + description: > 13 + Of the three PHYs on the SpacemiT K1 SoC capable of being used for 14 + PCIe, one is a combo PHY that can also be configured for use by a 15 + USB 3 controller. Using PCIe or USB 3 is a board design decision. 16 + 17 + The combo PHY is also the only PCIe PHY that is able to determine 18 + PCIe calibration values to use, and this must be determined before 19 + the other two PCIe PHYs can be used. This calibration must be 20 + performed with the combo PHY in PCIe mode, and is this is done 21 + when the combo PHY is probed. 22 + 23 + The combo PHY uses an external oscillator as a reference clock. 24 + During normal operation, the PCIe or USB port driver is responsible 25 + for ensuring all other clocks needed by a PHY are enabled, and all 26 + resets affecting the PHY are deasserted. However, for the combo 27 + PHY to perform calibration independent of whether it's later used 28 + for PCIe or USB, all PCIe mode clocks and resets must be defined. 29 + 30 + properties: 31 + compatible: 32 + const: spacemit,k1-combo-phy 33 + 34 + reg: 35 + items: 36 + - description: PHY control registers 37 + 38 + clocks: 39 + items: 40 + - description: External oscillator used by the PHY PLL 41 + - description: DWC PCIe Data Bus Interface (DBI) clock 42 + - description: DWC PCIe application AXI-bus Master interface clock 43 + - description: DWC PCIe application AXI-bus slave interface clock 44 + 45 + clock-names: 46 + items: 47 + - const: refclk 48 + - const: dbi 49 + - const: mstr 50 + - const: slv 51 + 52 + resets: 53 + items: 54 + - description: PHY reset; remains deasserted after initialization 55 + - description: DWC PCIe Data Bus Interface (DBI) reset 56 + - description: DWC PCIe application AXI-bus Master interface reset 57 + - description: DWC PCIe application AXI-bus slave interface reset 58 + 59 + reset-names: 60 + items: 61 + - const: phy 62 + - const: dbi 63 + - const: mstr 64 + - const: slv 65 + 66 + spacemit,apmu: 67 + description: 68 + A phandle that refers to the APMU system controller, whose 69 + regmap is used in setting the mode 70 + $ref: /schemas/types.yaml#/definitions/phandle 71 + 72 + "#phy-cells": 73 + const: 1 74 + description: 75 + The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines 76 + whether the PHY operates in PCIe or USB3 mode. 77 + 78 + required: 79 + - compatible 80 + - reg 81 + - clocks 82 + - clock-names 83 + - resets 84 + - reset-names 85 + - spacemit,apmu 86 + - "#phy-cells" 87 + 88 + additionalProperties: false 89 + 90 + examples: 91 + - | 92 + #include <dt-bindings/clock/spacemit,k1-syscon.h> 93 + phy@c0b10000 { 94 + compatible = "spacemit,k1-combo-phy"; 95 + reg = <0xc0b10000 0x1000>; 96 + clocks = <&vctcxo_24m>, 97 + <&syscon_apmu CLK_PCIE0_DBI>, 98 + <&syscon_apmu CLK_PCIE0_MASTER>, 99 + <&syscon_apmu CLK_PCIE0_SLAVE>; 100 + clock-names = "refclk", 101 + "dbi", 102 + "mstr", 103 + "slv"; 104 + resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, 105 + <&syscon_apmu RESET_PCIE0_DBI>, 106 + <&syscon_apmu RESET_PCIE0_MASTER>, 107 + <&syscon_apmu RESET_PCIE0_SLAVE>; 108 + reset-names = "phy", 109 + "dbi", 110 + "mstr", 111 + "slv"; 112 + spacemit,apmu = <&syscon_apmu>; 113 + #phy-cells = <1>; 114 + };
+71
Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/spacemit,k1-pcie-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: SpacemiT K1 PCIe PHY 8 + 9 + maintainers: 10 + - Alex Elder <elder@riscstar.com> 11 + 12 + description: > 13 + Two PHYs on the SpacemiT K1 SoC used for only for PCIe. These 14 + PHYs must be configured using calibration values that are 15 + determined by a third "combo PHY". The combo PHY determines 16 + these calibration values during probe so they can be used for 17 + the two PCIe-only PHYs. 18 + 19 + The PHY uses an external oscillator as a reference clock. During 20 + normal operation, the PCIe host driver is responsible for ensuring 21 + all other clocks needed by a PHY are enabled, and all resets 22 + affecting the PHY are deasserted. 23 + 24 + properties: 25 + compatible: 26 + const: spacemit,k1-pcie-phy 27 + 28 + reg: 29 + items: 30 + - description: PHY control registers 31 + 32 + clocks: 33 + items: 34 + - description: External oscillator used by the PHY PLL 35 + 36 + clock-names: 37 + const: refclk 38 + 39 + resets: 40 + items: 41 + - description: PHY reset; remains deasserted after initialization 42 + 43 + reset-names: 44 + const: phy 45 + 46 + "#phy-cells": 47 + const: 0 48 + 49 + required: 50 + - compatible 51 + - reg 52 + - clocks 53 + - clock-names 54 + - resets 55 + - reset-names 56 + - "#phy-cells" 57 + 58 + additionalProperties: false 59 + 60 + examples: 61 + - | 62 + #include <dt-bindings/clock/spacemit,k1-syscon.h> 63 + phy@c0c10000 { 64 + compatible = "spacemit,k1-pcie-phy"; 65 + reg = <0xc0c10000 0x1000>; 66 + clocks = <&vctcxo_24m>; 67 + clock-names = "refclk"; 68 + resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; 69 + reset-names = "phy"; 70 + #phy-cells = <0>; 71 + };
+40
Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: SpacemiT K1 SoC USB 2.0 PHY 8 + 9 + maintainers: 10 + - Ze Huang <huang.ze@linux.dev> 11 + 12 + properties: 13 + compatible: 14 + const: spacemit,k1-usb2-phy 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + clocks: 20 + maxItems: 1 21 + 22 + "#phy-cells": 23 + const: 0 24 + 25 + required: 26 + - compatible 27 + - reg 28 + - clocks 29 + - "#phy-cells" 30 + 31 + additionalProperties: false 32 + 33 + examples: 34 + - | 35 + usb-phy@c09c0000 { 36 + compatible = "spacemit,k1-usb2-phy"; 37 + reg = <0xc09c0000 0x200>; 38 + clocks = <&syscon_apmu 15>; 39 + #phy-cells = <0>; 40 + };
+99
Documentation/devicetree/bindings/phy/ti,control-phy-otghs.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/ti,control-phy-otghs.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: TI OMAP Control PHY Module 8 + 9 + maintainers: 10 + - Roger Quadros <rogerq@ti.com> 11 + 12 + description: 13 + The TI OMAP Control PHY module is a hardware block within the system 14 + control module (SCM) of Texas Instruments OMAP SoCs. It provides 15 + centralized control over power, configuration, and auxiliary features 16 + for multiple on-chip PHYs. This module is essential for proper PHY 17 + operation in power-constrained embedded systems. 18 + 19 + properties: 20 + $nodename: 21 + pattern: "^phy@[0-9a-f]+$" 22 + 23 + compatible: 24 + enum: 25 + - ti,control-phy-otghs 26 + - ti,control-phy-pcie 27 + - ti,control-phy-pipe3 28 + - ti,control-phy-usb2 29 + - ti,control-phy-usb2-am437 30 + - ti,control-phy-usb2-dra7 31 + 32 + reg: 33 + minItems: 1 34 + maxItems: 3 35 + 36 + reg-names: 37 + minItems: 1 38 + maxItems: 3 39 + items: 40 + enum: [otghs_control, power, pcie_pcs, control_sma] 41 + 42 + allOf: 43 + - if: 44 + properties: 45 + compatible: 46 + contains: 47 + enum: 48 + - ti,control-phy-otghs 49 + then: 50 + properties: 51 + reg-names: 52 + const: otghs_control 53 + 54 + - if: 55 + properties: 56 + compatible: 57 + contains: 58 + enum: 59 + - ti,control-phy-pcie 60 + then: 61 + properties: 62 + reg: 63 + minItems: 3 64 + 65 + reg-names: 66 + items: 67 + - const: power 68 + - const: pcie_pcs 69 + - const: control_sma 70 + 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + enum: 76 + - ti,control-phy-usb2 77 + - ti,control-phy-usb2-dra7 78 + - ti,control-phy-usb2-am437 79 + - ti,control-phy-pipe3 80 + then: 81 + properties: 82 + reg-names: 83 + const: power 84 + 85 + required: 86 + - reg 87 + - compatible 88 + - reg-names 89 + 90 + unevaluatedProperties: false 91 + 92 + examples: 93 + - | 94 + phy@4a00233c { 95 + compatible = "ti,control-phy-otghs"; 96 + reg = <0x4a00233c 0x4>; 97 + reg-names = "otghs_control"; 98 + }; 99 + ...
+138
Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/ti,phy-usb3.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: TI PIPE3 PHY Module 8 + 9 + maintainers: 10 + - Roger Quadros <rogerq@ti.com> 11 + 12 + description: 13 + The TI PIPE3 PHY is a high-speed SerDes (Serializer/Deserializer) 14 + transceiver integrated in OMAP5, DRA7xx/AM57xx, and similar SoCs. 15 + It supports multiple protocols (USB3, SATA, PCIe) using the PIPE3 16 + interface standard, which defines a common physical layer for 17 + high-speed serial interfaces. 18 + 19 + properties: 20 + $nodename: 21 + pattern: "^(pcie-phy|usb3-phy|phy)@[0-9a-f]+$" 22 + 23 + compatible: 24 + enum: 25 + - ti,omap-usb3 26 + - ti,phy-pipe3-pcie 27 + - ti,phy-pipe3-sata 28 + - ti,phy-usb3 29 + 30 + reg: 31 + minItems: 2 32 + maxItems: 3 33 + 34 + reg-names: 35 + minItems: 2 36 + items: 37 + - const: phy_rx 38 + - const: phy_tx 39 + - const: pll_ctrl 40 + 41 + "#phy-cells": 42 + const: 0 43 + 44 + clocks: 45 + minItems: 2 46 + maxItems: 7 47 + 48 + clock-names: 49 + minItems: 2 50 + maxItems: 7 51 + items: 52 + enum: [wkupclk, sysclk, refclk, dpll_ref, 53 + dpll_ref_m2, phy-div, div-clk] 54 + 55 + syscon-phy-power: 56 + $ref: /schemas/types.yaml#/definitions/phandle-array 57 + maxItems: 1 58 + items: 59 + items: 60 + - description: Phandle to the system control module 61 + - description: Register offset controlling PHY power 62 + 63 + syscon-pllreset: 64 + $ref: /schemas/types.yaml#/definitions/phandle-array 65 + maxItems: 1 66 + items: 67 + items: 68 + - description: Phandle to the system control module 69 + - description: Register offset of CTRL_CORE_SMA_SW_0 70 + 71 + syscon-pcs: 72 + $ref: /schemas/types.yaml#/definitions/phandle-array 73 + maxItems: 1 74 + items: 75 + items: 76 + - description: Phandle to the system control module 77 + - description: Register offset for PCS delay programming 78 + 79 + ctrl-module: 80 + $ref: /schemas/types.yaml#/definitions/phandle 81 + description: 82 + Phandle of control module for PHY power on. 83 + deprecated: true 84 + 85 + allOf: 86 + - if: 87 + properties: 88 + compatible: 89 + contains: 90 + const: ti,phy-pipe3-sata 91 + then: 92 + properties: 93 + syscon-pllreset: true 94 + else: 95 + properties: 96 + syscon-pllreset: false 97 + 98 + required: 99 + - reg 100 + - compatible 101 + - reg-names 102 + - "#phy-cells" 103 + - clocks 104 + - clock-names 105 + 106 + unevaluatedProperties: false 107 + 108 + examples: 109 + - | 110 + /* TI PIPE3 USB3 PHY */ 111 + usb3-phy@4a084400 { 112 + compatible = "ti,phy-usb3"; 113 + reg = <0x4a084400 0x80>, 114 + <0x4a084800 0x64>, 115 + <0x4a084c00 0x40>; 116 + reg-names = "phy_rx", "phy_tx", "pll_ctrl"; 117 + #phy-cells = <0>; 118 + clocks = <&usb_phy_cm_clk32k>, 119 + <&sys_clkin>, 120 + <&usb_otg_ss_refclk960m>; 121 + clock-names = "wkupclk", "sysclk", "refclk"; 122 + ctrl-module = <&omap_control_usb>; 123 + }; 124 + 125 + - | 126 + /* TI PIPE3 SATA PHY */ 127 + phy@4a096000 { 128 + compatible = "ti,phy-pipe3-sata"; 129 + reg = <0x4a096000 0x80>, /* phy_rx */ 130 + <0x4a096400 0x64>, /* phy_tx */ 131 + <0x4a096800 0x40>; /* pll_ctrl */ 132 + reg-names = "phy_rx", "phy_tx", "pll_ctrl"; 133 + clocks = <&sys_clkin1>, <&sata_ref_clk>; 134 + clock-names = "sysclk", "refclk"; 135 + syscon-pllreset = <&scm_conf 0x3fc>; 136 + #phy-cells = <0>; 137 + }; 138 + ...
+3
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
··· 20 20 - microchip,ata6561 21 21 - ti,tcan1051 22 22 - const: ti,tcan1042 23 + - items: 24 + - const: ti,tcan1046 25 + - const: nxp,tja1048 23 26 - enum: 24 27 - ti,tcan1042 25 28 - ti,tcan1043
-98
Documentation/devicetree/bindings/phy/ti-phy.txt
··· 1 - TI PHY: DT DOCUMENTATION FOR PHYs in TI PLATFORMs 2 - 3 - OMAP CONTROL PHY 4 - 5 - Required properties: 6 - - compatible: Should be one of 7 - "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. 8 - "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register 9 - e.g. USB2_PHY on OMAP5. 10 - "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control 11 - e.g. USB3 PHY and SATA PHY on OMAP5. 12 - "ti,control-phy-pcie" - for pcie to support external clock for pcie and to 13 - set PCS delay value. 14 - e.g. PCIE PHY in DRA7x 15 - "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on 16 - DRA7 platform. 17 - "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on 18 - AM437 platform. 19 - - reg : register ranges as listed in the reg-names property 20 - - reg-names: "otghs_control" for control-phy-otghs 21 - "power", "pcie_pcs" and "control_sma" for control-phy-pcie 22 - "power" for all other types 23 - 24 - omap_control_usb: omap-control-usb@4a002300 { 25 - compatible = "ti,control-phy-otghs"; 26 - reg = <0x4a00233c 0x4>; 27 - reg-names = "otghs_control"; 28 - }; 29 - 30 - TI PIPE3 PHY 31 - 32 - Required properties: 33 - - compatible: Should be "ti,phy-usb3", "ti,phy-pipe3-sata" or 34 - "ti,phy-pipe3-pcie. "ti,omap-usb3" is deprecated. 35 - - reg : Address and length of the register set for the device. 36 - - reg-names: The names of the register addresses corresponding to the registers 37 - filled in "reg". 38 - - #phy-cells: determine the number of cells that should be given in the 39 - phandle while referencing this phy. 40 - - clocks: a list of phandles and clock-specifier pairs, one for each entry in 41 - clock-names. 42 - - clock-names: should include: 43 - * "wkupclk" - wakeup clock. 44 - * "sysclk" - system clock. 45 - * "refclk" - reference clock. 46 - * "dpll_ref" - external dpll ref clk 47 - * "dpll_ref_m2" - external dpll ref clk 48 - * "phy-div" - divider for apll 49 - * "div-clk" - apll clock 50 - 51 - Optional properties: 52 - - id: If there are multiple instance of the same type, in order to 53 - differentiate between each instance "id" can be used (e.g., multi-lane PCIe 54 - PHY). If "id" is not provided, it is set to default value of '1'. 55 - - syscon-pllreset: Handle to system control region that contains the 56 - CTRL_CORE_SMA_SW_0 register and register offset to the CTRL_CORE_SMA_SW_0 57 - register that contains the SATA_PLL_SOFT_RESET bit. Only valid for sata_phy. 58 - - syscon-pcs : phandle/offset pair. Phandle to the system control module and the 59 - register offset to write the PCS delay value. 60 - 61 - Deprecated properties: 62 - - ctrl-module : phandle of the control module used by PHY driver to power on 63 - the PHY. 64 - 65 - Recommended properties: 66 - - syscon-phy-power : phandle/offset pair. Phandle to the system control 67 - module and the register offset to power on/off the PHY. 68 - 69 - This is usually a subnode of ocp2scp to which it is connected. 70 - 71 - usb3phy@4a084400 { 72 - compatible = "ti,phy-usb3"; 73 - reg = <0x4a084400 0x80>, 74 - <0x4a084800 0x64>, 75 - <0x4a084c00 0x40>; 76 - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; 77 - ctrl-module = <&omap_control_usb>; 78 - #phy-cells = <0>; 79 - clocks = <&usb_phy_cm_clk32k>, 80 - <&sys_clkin>, 81 - <&usb_otg_ss_refclk960m>; 82 - clock-names = "wkupclk", 83 - "sysclk", 84 - "refclk"; 85 - }; 86 - 87 - sata_phy: phy@4a096000 { 88 - compatible = "ti,phy-pipe3-sata"; 89 - reg = <0x4A096000 0x80>, /* phy_rx */ 90 - <0x4A096400 0x64>, /* phy_tx */ 91 - <0x4A096800 0x40>; /* pll_ctrl */ 92 - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; 93 - ctrl-module = <&omap_control_sata>; 94 - clocks = <&sys_clkin1>, <&sata_ref_clk>; 95 - clock-names = "sysclk", "refclk"; 96 - syscon-pllreset = <&scm_conf 0x3fc>; 97 - #phy-cells = <0>; 98 - };
+4
MAINTAINERS
··· 2520 2520 F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml 2521 2521 F: Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml 2522 2522 F: Documentation/devicetree/bindings/pci/apple,pcie.yaml 2523 + F: Documentation/devicetree/bindings/phy/apple,atcphy.yaml 2523 2524 F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml 2524 2525 F: Documentation/devicetree/bindings/power/apple* 2525 2526 F: Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml ··· 2549 2548 F: drivers/nvme/host/apple.c 2550 2549 F: drivers/nvmem/apple-efuses.c 2551 2550 F: drivers/nvmem/apple-spmi-nvmem.c 2551 + F: drivers/phy/apple/ 2552 2552 F: drivers/pinctrl/pinctrl-apple-gpio.c 2553 2553 F: drivers/power/reset/macsmc-reboot.c 2554 2554 F: drivers/pwm/pwm-apple.c ··· 10860 10858 P: Documentation/process/maintainer-soc-clean-dts.rst 10861 10859 C: irc://irc.oftc.net/pixel6-kernel-dev 10862 10860 F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml 10861 + F: Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml 10863 10862 F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml 10864 10863 F: Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml 10865 10864 F: arch/arm64/boot/dts/exynos/google/ 10866 10865 F: drivers/clk/samsung/clk-gs101.c 10866 + F: drivers/phy/phy-google-usb.c 10867 10867 F: drivers/soc/samsung/gs101-pmu.c 10868 10868 F: drivers/phy/samsung/phy-gs101-ufs.c 10869 10869 F: drivers/usb/dwc3/dwc3-google.c
+1 -1
drivers/Makefile
··· 10 10 obj-y += irqchip/ 11 11 obj-y += bus/ 12 12 13 - obj-$(CONFIG_GENERIC_PHY) += phy/ 13 + obj-y += phy/ 14 14 15 15 # GPIO must come after pinctrl as gpios may need to mux pins etc 16 16 obj-$(CONFIG_PINCTRL) += pinctrl/
+25
drivers/phy/Kconfig
··· 47 47 Provides a number of helpers a core functions for MIPI D-PHY 48 48 drivers to us. 49 49 50 + config PHY_GOOGLE_USB 51 + tristate "Google Tensor SoC USB PHY driver" 52 + select GENERIC_PHY 53 + depends on TYPEC 54 + help 55 + Enable support for the USB PHY on Google Tensor SoCs, starting with 56 + the G5 generation (Laguna). This driver provides the PHY interfaces 57 + to interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, 58 + both of which are integrated with the DWC3 USB DRD controller. 59 + This driver currently supports USB high-speed. 60 + 50 61 config PHY_LPC18XX_USB_OTG 51 62 tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" 52 63 depends on OF && (ARCH_LPC18XX || COMPILE_TEST) ··· 134 123 schemes. It supports all three USB 2.0 data rates: Low Speed, Full 135 124 Speed and High Speed. 136 125 126 + config PHY_SPACEMIT_K1_PCIE 127 + tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" 128 + depends on ARCH_SPACEMIT || COMPILE_TEST 129 + depends on COMMON_CLK 130 + depends on HAS_IOMEM 131 + depends on OF 132 + select GENERIC_PHY 133 + default ARCH_SPACEMIT 134 + help 135 + Enable support for the PCIe and USB 3 combo PHY and two 136 + PCIe-only PHYs used in the SpacemiT K1 SoC. 137 + 137 138 source "drivers/phy/allwinner/Kconfig" 138 139 source "drivers/phy/amlogic/Kconfig" 140 + source "drivers/phy/apple/Kconfig" 139 141 source "drivers/phy/broadcom/Kconfig" 140 142 source "drivers/phy/cadence/Kconfig" 141 143 source "drivers/phy/freescale/Kconfig" ··· 169 145 source "drivers/phy/samsung/Kconfig" 170 146 source "drivers/phy/socionext/Kconfig" 171 147 source "drivers/phy/sophgo/Kconfig" 148 + source "drivers/phy/spacemit/Kconfig" 172 149 source "drivers/phy/st/Kconfig" 173 150 source "drivers/phy/starfive/Kconfig" 174 151 source "drivers/phy/sunplus/Kconfig"
+5 -1
drivers/phy/Makefile
··· 8 8 obj-$(CONFIG_GENERIC_PHY) += phy-core.o 9 9 obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o 10 10 obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o 11 + obj-$(CONFIG_PHY_GOOGLE_USB) += phy-google-usb.o 11 12 obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o 12 13 obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 13 14 obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o ··· 16 15 obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o 17 16 obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o 18 17 obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o 19 - obj-y += allwinner/ \ 18 + obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o 19 + obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ 20 20 amlogic/ \ 21 + apple/ \ 21 22 broadcom/ \ 22 23 cadence/ \ 23 24 freescale/ \ ··· 41 38 samsung/ \ 42 39 socionext/ \ 43 40 sophgo/ \ 41 + spacemit/ \ 44 42 st/ \ 45 43 starfive/ \ 46 44 sunplus/ \
+7 -7
drivers/phy/allwinner/phy-sun4i-usb.c
··· 359 359 /* Force ISCR and cable state updates */ 360 360 data->id_det = -1; 361 361 data->vbus_det = -1; 362 - queue_delayed_work(system_wq, &data->detect, 0); 362 + queue_delayed_work(system_percpu_wq, &data->detect, 0); 363 363 } 364 364 365 365 return 0; ··· 482 482 483 483 /* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */ 484 484 if (phy->index == 0 && sun4i_usb_phy0_poll(data)) 485 - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 485 + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); 486 486 487 487 return 0; 488 488 } ··· 503 503 * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan. 504 504 */ 505 505 if (phy->index == 0 && !sun4i_usb_phy0_poll(data)) 506 - mod_delayed_work(system_wq, &data->detect, POLL_TIME); 506 + mod_delayed_work(system_percpu_wq, &data->detect, POLL_TIME); 507 507 508 508 return 0; 509 509 } ··· 542 542 543 543 data->id_det = -1; /* Force reprocessing of id */ 544 544 data->force_session_end = true; 545 - queue_delayed_work(system_wq, &data->detect, 0); 545 + queue_delayed_work(system_percpu_wq, &data->detect, 0); 546 546 547 547 return 0; 548 548 } ··· 654 654 extcon_set_state_sync(data->extcon, EXTCON_USB, vbus_det); 655 655 656 656 if (sun4i_usb_phy0_poll(data)) 657 - queue_delayed_work(system_wq, &data->detect, POLL_TIME); 657 + queue_delayed_work(system_percpu_wq, &data->detect, POLL_TIME); 658 658 } 659 659 660 660 static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id) ··· 662 662 struct sun4i_usb_phy_data *data = dev_id; 663 663 664 664 /* vbus or id changed, let the pins settle and then scan them */ 665 - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 665 + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); 666 666 667 667 return IRQ_HANDLED; 668 668 } ··· 676 676 677 677 /* Properties on the vbus_power_supply changed, scan vbus_det */ 678 678 if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply) 679 - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 679 + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); 680 680 681 681 return NOTIFY_OK; 682 682 }
+13
drivers/phy/apple/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + config PHY_APPLE_ATC 3 + tristate "Apple Type-C PHY" 4 + depends on (ARM64 && ARCH_APPLE) || (COMPILE_TEST && !GENERIC_ATOMIC64) 5 + depends on TYPEC 6 + select GENERIC_PHY 7 + select APPLE_TUNABLE 8 + help 9 + Enable this to add support for the Apple Type-C PHY found in 10 + Apple Silicon M-series SoCs. This PHY supports USB2, 11 + USB3, USB4, Thunderbolt, and DisplayPort. 12 + 13 + If M is selected the module will be called 'phy-apple-atc'.
+4
drivers/phy/apple/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + 3 + obj-$(CONFIG_PHY_APPLE_ATC) += phy-apple-atc.o 4 + phy-apple-atc-y := atc.o
+2295
drivers/phy/apple/atc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + /* 3 + * Apple Type-C PHY driver 4 + * 5 + * The Apple Type-C PHY (ATCPHY) is a combined PHY for USB 2.0, USB 3.x, 6 + * USB4/Thunderbolt, and DisplayPort connectivity via Type-C ports found in 7 + * Apple Silicon SoCs. 8 + * 9 + * The PHY handles muxing between these different protocols and also provides the 10 + * reset controller for the attached DWC3 USB controller. 11 + * 12 + * No documentation for this PHY is available and its operation has been 13 + * reverse engineered by observing the XNU's MMIO access using a thin hypervisor 14 + * and correlating register access to XNU's very verbose debug output. Most 15 + * register names comes from this debug output as well. 16 + * 17 + * In order to correctly setup the high speed lanes for the various modes 18 + * calibration values copied from Apple's firmware by our bootloader m1n1 are 19 + * required. Without these only USB2 operation is possible. 20 + * 21 + * Copyright (C) The Asahi Linux Contributors 22 + * Author: Sven Peter <sven@kernel.org> 23 + */ 24 + 25 + #include <dt-bindings/phy/phy.h> 26 + #include <linux/bitfield.h> 27 + #include <linux/cleanup.h> 28 + #include <linux/delay.h> 29 + #include <linux/iopoll.h> 30 + #include <linux/lockdep.h> 31 + #include <linux/module.h> 32 + #include <linux/mutex.h> 33 + #include <linux/of.h> 34 + #include <linux/of_device.h> 35 + #include <linux/phy/phy.h> 36 + #include <linux/platform_device.h> 37 + #include <linux/reset-controller.h> 38 + #include <linux/soc/apple/tunable.h> 39 + #include <linux/types.h> 40 + #include <linux/usb/pd.h> 41 + #include <linux/usb/typec.h> 42 + #include <linux/usb/typec_altmode.h> 43 + #include <linux/usb/typec_dp.h> 44 + #include <linux/usb/typec_mux.h> 45 + #include <linux/usb/typec_tbt.h> 46 + 47 + #define AUSPLL_FSM_CTRL 0x1014 48 + 49 + #define AUSPLL_APB_CMD_OVERRIDE 0x2000 50 + #define AUSPLL_APB_CMD_OVERRIDE_REQ BIT(0) 51 + #define AUSPLL_APB_CMD_OVERRIDE_ACK BIT(1) 52 + #define AUSPLL_APB_CMD_OVERRIDE_UNK28 BIT(28) 53 + #define AUSPLL_APB_CMD_OVERRIDE_CMD GENMASK(27, 3) 54 + 55 + #define AUSPLL_FREQ_DESC_A 0x2080 56 + #define AUSPLL_FD_FREQ_COUNT_TARGET GENMASK(9, 0) 57 + #define AUSPLL_FD_FBDIVN_HALF BIT(10) 58 + #define AUSPLL_FD_REV_DIVN GENMASK(13, 11) 59 + #define AUSPLL_FD_KI_MAN GENMASK(17, 14) 60 + #define AUSPLL_FD_KI_EXP GENMASK(21, 18) 61 + #define AUSPLL_FD_KP_MAN GENMASK(25, 22) 62 + #define AUSPLL_FD_KP_EXP GENMASK(29, 26) 63 + #define AUSPLL_FD_KPKI_SCALE_HBW GENMASK(31, 30) 64 + 65 + #define AUSPLL_FREQ_DESC_B 0x2084 66 + #define AUSPLL_FD_FBDIVN_FRAC_DEN GENMASK(13, 0) 67 + #define AUSPLL_FD_FBDIVN_FRAC_NUM GENMASK(27, 14) 68 + 69 + #define AUSPLL_FREQ_DESC_C 0x2088 70 + #define AUSPLL_FD_SDM_SSC_STEP GENMASK(7, 0) 71 + #define AUSPLL_FD_SDM_SSC_EN BIT(8) 72 + #define AUSPLL_FD_PCLK_DIV_SEL GENMASK(13, 9) 73 + #define AUSPLL_FD_LFSDM_DIV GENMASK(15, 14) 74 + #define AUSPLL_FD_LFCLK_CTRL GENMASK(19, 16) 75 + #define AUSPLL_FD_VCLK_OP_DIVN GENMASK(21, 20) 76 + #define AUSPLL_FD_VCLK_PRE_DIVN BIT(22) 77 + 78 + #define AUSPLL_DCO_EFUSE_SPARE 0x222c 79 + #define AUSPLL_RODCO_ENCAP_EFUSE GENMASK(10, 9) 80 + #define AUSPLL_RODCO_BIAS_ADJUST_EFUSE GENMASK(14, 12) 81 + 82 + #define AUSPLL_FRACN_CAN 0x22a4 83 + #define AUSPLL_DLL_START_CAPCODE GENMASK(18, 17) 84 + 85 + #define AUSPLL_CLKOUT_MASTER 0x2200 86 + #define AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN BIT(2) 87 + #define AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN BIT(4) 88 + #define AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN BIT(6) 89 + 90 + #define AUSPLL_CLKOUT_DIV 0x2208 91 + #define AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI GENMASK(20, 16) 92 + 93 + #define AUSPLL_BGR 0x2214 94 + #define AUSPLL_BGR_CTRL_AVAIL BIT(0) 95 + 96 + #define AUSPLL_CLKOUT_DTC_VREG 0x2220 97 + #define AUSPLL_DTC_VREG_ADJUST GENMASK(16, 14) 98 + #define AUSPLL_DTC_VREG_BYPASS BIT(7) 99 + 100 + #define AUSPLL_FREQ_CFG 0x2224 101 + #define AUSPLL_FREQ_REFCLK GENMASK(1, 0) 102 + 103 + #define AUS_COMMON_SHIM_BLK_VREG 0x0a04 104 + #define AUS_VREG_TRIM GENMASK(6, 2) 105 + 106 + #define AUS_UNK_A20 0x0a20 107 + #define AUS_UNK_A20_TX_CAL_CODE GENMASK(23, 20) 108 + 109 + #define ACIOPHY_CMN_SHM_STS_REG0 0x0a74 110 + #define ACIOPHY_CMN_SHM_STS_REG0_CMD_READY BIT(0) 111 + 112 + #define CIO3PLL_CLK_CTRL 0x2a00 113 + #define CIO3PLL_CLK_PCLK_EN BIT(1) 114 + #define CIO3PLL_CLK_REFCLK_EN BIT(5) 115 + 116 + #define CIO3PLL_DCO_NCTRL 0x2a38 117 + #define CIO3PLL_DCO_COARSEBIN_EFUSE0 GENMASK(6, 0) 118 + #define CIO3PLL_DCO_COARSEBIN_EFUSE1 GENMASK(23, 17) 119 + 120 + #define CIO3PLL_FRACN_CAN 0x2aa4 121 + #define CIO3PLL_DLL_CAL_START_CAPCODE GENMASK(18, 17) 122 + 123 + #define CIO3PLL_DTC_VREG 0x2a20 124 + #define CIO3PLL_DTC_VREG_ADJUST GENMASK(16, 14) 125 + 126 + #define ACIOPHY_CFG0 0x08 127 + #define ACIOPHY_CFG0_COMMON_BIG_OV BIT(1) 128 + #define ACIOPHY_CFG0_COMMON_SMALL_OV BIT(3) 129 + #define ACIOPHY_CFG0_COMMON_CLAMP_OV BIT(5) 130 + #define ACIOPHY_CFG0_RX_SMALL_OV GENMASK(9, 8) 131 + #define ACIOPHY_CFG0_RX_BIG_OV GENMASK(13, 12) 132 + #define ACIOPHY_CFG0_RX_CLAMP_OV GENMASK(17, 16) 133 + 134 + #define ACIOPHY_CROSSBAR 0x4c 135 + #define ACIOPHY_CROSSBAR_PROTOCOL GENMASK(4, 0) 136 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB4 0x0 137 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED 0x1 138 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB3 0xa 139 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED 0xb 140 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP 0x10 141 + #define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED 0x11 142 + #define ACIOPHY_CROSSBAR_PROTOCOL_DP 0x14 143 + #define ACIOPHY_CROSSBAR_DP_SINGLE_PMA GENMASK(16, 5) 144 + #define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE 0x0000 145 + #define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100 0x100 146 + #define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008 0x008 147 + #define ACIOPHY_CROSSBAR_DP_BOTH_PMA BIT(17) 148 + 149 + #define ACIOPHY_LANE_MODE 0x48 150 + #define ACIOPHY_LANE_MODE_RX0 GENMASK(2, 0) 151 + #define ACIOPHY_LANE_MODE_TX0 GENMASK(5, 3) 152 + #define ACIOPHY_LANE_MODE_RX1 GENMASK(8, 6) 153 + #define ACIOPHY_LANE_MODE_TX1 GENMASK(11, 9) 154 + 155 + enum atcphy_lane_mode { 156 + ACIOPHY_LANE_MODE_USB4 = 0, 157 + ACIOPHY_LANE_MODE_USB3 = 1, 158 + ACIOPHY_LANE_MODE_DP = 2, 159 + ACIOPHY_LANE_MODE_OFF = 3, 160 + }; 161 + 162 + #define ACIOPHY_TOP_BIST_CIOPHY_CFG1 0x84 163 + #define ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN BIT(27) 164 + #define ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN BIT(28) 165 + 166 + #define ACIOPHY_TOP_BIST_OV_CFG 0x8c 167 + #define ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV BIT(13) 168 + #define ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV BIT(25) 169 + 170 + #define ACIOPHY_TOP_BIST_READ_CTRL 0x90 171 + #define ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE BIT(2) 172 + 173 + #define ACIOPHY_TOP_PHY_STAT 0x9c 174 + #define ACIOPHY_TOP_PHY_STAT_LN0_UNK0 BIT(0) 175 + #define ACIOPHY_TOP_PHY_STAT_LN0_UNK23 BIT(23) 176 + 177 + #define ACIOPHY_TOP_BIST_PHY_CFG0 0xa8 178 + #define ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N BIT(0) 179 + 180 + #define ACIOPHY_TOP_BIST_PHY_CFG1 0xac 181 + #define ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN GENMASK(13, 10) 182 + 183 + #define ACIOPHY_SLEEP_CTRL 0x1b0 184 + #define ACIOPHY_SLEEP_CTRL_TX_BIG_OV GENMASK(3, 2) 185 + #define ACIOPHY_SLEEP_CTRL_TX_SMALL_OV GENMASK(7, 6) 186 + #define ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV GENMASK(11, 10) 187 + 188 + #define ACIOPHY_PLL_PCTL_FSM_CTRL1 0x1014 189 + #define ACIOPHY_PLL_APB_REQ_OV_SEL GENMASK(21, 13) 190 + #define ACIOPHY_PLL_COMMON_CTRL 0x1028 191 + #define ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT BIT(24) 192 + 193 + #define ATCPHY_POWER_CTRL 0x20000 194 + #define ATCPHY_POWER_STAT 0x20004 195 + #define ATCPHY_POWER_SLEEP_SMALL BIT(0) 196 + #define ATCPHY_POWER_SLEEP_BIG BIT(1) 197 + #define ATCPHY_POWER_CLAMP_EN BIT(2) 198 + #define ATCPHY_POWER_APB_RESET_N BIT(3) 199 + #define ATCPHY_POWER_PHY_RESET_N BIT(4) 200 + 201 + #define ATCPHY_MISC 0x20008 202 + #define ATCPHY_MISC_RESET_N BIT(0) 203 + #define ATCPHY_MISC_LANE_SWAP BIT(2) 204 + 205 + #define ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0 0x7000 206 + #define DP_PMA_BYTECLK_RESET BIT(0) 207 + #define DP_MAC_DIV20_CLK_SEL BIT(1) 208 + #define DPTXPHY_PMA_LANE_RESET_N BIT(2) 209 + #define DPTXPHY_PMA_LANE_RESET_N_OV BIT(3) 210 + #define DPTX_PCLK1_SELECT GENMASK(6, 4) 211 + #define DPTX_PCLK2_SELECT GENMASK(9, 7) 212 + #define DPRX_PCLK_SELECT GENMASK(12, 10) 213 + #define DPTX_PCLK1_ENABLE BIT(13) 214 + #define DPTX_PCLK2_ENABLE BIT(14) 215 + #define DPRX_PCLK_ENABLE BIT(15) 216 + 217 + #define ACIOPHY_DP_PCLK_STAT 0x7044 218 + #define ACIOPHY_AUSPLL_LOCK BIT(3) 219 + 220 + #define LN0_AUSPMA_RX_TOP 0x9000 221 + #define LN0_AUSPMA_RX_EQ 0xA000 222 + #define LN0_AUSPMA_RX_SHM 0xB000 223 + #define LN0_AUSPMA_TX_TOP 0xC000 224 + #define LN0_AUSPMA_TX_SHM 0xD000 225 + 226 + #define LN1_AUSPMA_RX_TOP 0x10000 227 + #define LN1_AUSPMA_RX_EQ 0x11000 228 + #define LN1_AUSPMA_RX_SHM 0x12000 229 + #define LN1_AUSPMA_TX_TOP 0x13000 230 + #define LN1_AUSPMA_TX_SHM 0x14000 231 + 232 + #define LN_AUSPMA_RX_TOP_PMAFSM 0x0010 233 + #define LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV BIT(0) 234 + #define LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ BIT(9) 235 + 236 + #define LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE 0x00F0 237 + #define LN_RX_TXMODE BIT(0) 238 + 239 + #define LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0 0x00 240 + #define LN_TX_CLK_EN BIT(20) 241 + #define LN_TX_CLK_EN_OV BIT(21) 242 + 243 + #define LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1 0x04 244 + #define LN_RX_DIV20_RESET_N_OV BIT(29) 245 + #define LN_RX_DIV20_RESET_N BIT(30) 246 + 247 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL2 0x08 248 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL3 0x0C 249 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL4 0x10 250 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL5 0x14 251 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL6 0x18 252 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL7 0x1C 253 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL8 0x20 254 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL9 0x24 255 + #define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10 0x28 256 + #define LN_DTVREG_ADJUST GENMASK(31, 27) 257 + 258 + #define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11 0x2C 259 + #define LN_DTVREG_BIG_EN BIT(23) 260 + #define LN_DTVREG_BIG_EN_OV BIT(24) 261 + #define LN_DTVREG_SML_EN BIT(25) 262 + #define LN_DTVREG_SML_EN_OV BIT(26) 263 + 264 + #define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12 0x30 265 + #define LN_TX_BYTECLK_RESET_SYNC_CLR BIT(22) 266 + #define LN_TX_BYTECLK_RESET_SYNC_CLR_OV BIT(23) 267 + #define LN_TX_BYTECLK_RESET_SYNC_EN BIT(24) 268 + #define LN_TX_BYTECLK_RESET_SYNC_EN_OV BIT(25) 269 + #define LN_TX_HRCLK_SEL BIT(28) 270 + #define LN_TX_HRCLK_SEL_OV BIT(29) 271 + #define LN_TX_PBIAS_EN BIT(30) 272 + #define LN_TX_PBIAS_EN_OV BIT(31) 273 + 274 + #define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13 0x34 275 + #define LN_TX_PRE_EN BIT(0) 276 + #define LN_TX_PRE_EN_OV BIT(1) 277 + #define LN_TX_PST1_EN BIT(2) 278 + #define LN_TX_PST1_EN_OV BIT(3) 279 + #define LN_DTVREG_ADJUST_OV BIT(15) 280 + 281 + #define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14A 0x38 282 + #define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14B 0x3C 283 + #define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15A 0x40 284 + #define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15B 0x44 285 + #define LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16 0x48 286 + #define LN_RXTERM_EN BIT(21) 287 + #define LN_RXTERM_EN_OV BIT(22) 288 + #define LN_RXTERM_PULLUP_LEAK_EN BIT(23) 289 + #define LN_RXTERM_PULLUP_LEAK_EN_OV BIT(24) 290 + #define LN_TX_CAL_CODE GENMASK(29, 25) 291 + #define LN_TX_CAL_CODE_OV BIT(30) 292 + 293 + #define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17 0x4C 294 + #define LN_TX_MARGIN GENMASK(19, 15) 295 + #define LN_TX_MARGIN_OV BIT(20) 296 + #define LN_TX_MARGIN_LSB BIT(21) 297 + #define LN_TX_MARGIN_LSB_OV BIT(22) 298 + #define LN_TX_MARGIN_P1 GENMASK(26, 23) 299 + #define LN_TX_MARGIN_P1_OV BIT(27) 300 + #define LN_TX_MARGIN_P1_LSB GENMASK(29, 28) 301 + #define LN_TX_MARGIN_P1_LSB_OV BIT(30) 302 + 303 + #define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18 0x50 304 + #define LN_TX_P1_CODE GENMASK(3, 0) 305 + #define LN_TX_P1_CODE_OV BIT(4) 306 + #define LN_TX_P1_LSB_CODE GENMASK(6, 5) 307 + #define LN_TX_P1_LSB_CODE_OV BIT(7) 308 + #define LN_TX_MARGIN_PRE GENMASK(10, 8) 309 + #define LN_TX_MARGIN_PRE_OV BIT(11) 310 + #define LN_TX_MARGIN_PRE_LSB GENMASK(13, 12) 311 + #define LN_TX_MARGIN_PRE_LSB_OV BIT(14) 312 + #define LN_TX_PRE_LSB_CODE GENMASK(16, 15) 313 + #define LN_TX_PRE_LSB_CODE_OV BIT(17) 314 + #define LN_TX_PRE_CODE GENMASK(21, 18) 315 + #define LN_TX_PRE_CODE_OV BIT(22) 316 + 317 + #define LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19 0x54 318 + #define LN_TX_TEST_EN BIT(21) 319 + #define LN_TX_TEST_EN_OV BIT(22) 320 + #define LN_TX_EN BIT(23) 321 + #define LN_TX_EN_OV BIT(24) 322 + #define LN_TX_CLK_DLY_CTRL_TAPGEN GENMASK(27, 25) 323 + #define LN_TX_CLK_DIV2_EN BIT(28) 324 + #define LN_TX_CLK_DIV2_EN_OV BIT(29) 325 + #define LN_TX_CLK_DIV2_RST BIT(30) 326 + #define LN_TX_CLK_DIV2_RST_OV BIT(31) 327 + 328 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL20 0x58 329 + #define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL21 0x5C 330 + #define LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22 0x60 331 + #define LN_VREF_ADJUST_GRAY GENMASK(11, 7) 332 + #define LN_VREF_ADJUST_GRAY_OV BIT(12) 333 + #define LN_VREF_BIAS_SEL GENMASK(14, 13) 334 + #define LN_VREF_BIAS_SEL_OV BIT(15) 335 + #define LN_VREF_BOOST_EN BIT(16) 336 + #define LN_VREF_BOOST_EN_OV BIT(17) 337 + #define LN_VREF_EN BIT(18) 338 + #define LN_VREF_EN_OV BIT(19) 339 + #define LN_VREF_LPBKIN_DATA GENMASK(29, 28) 340 + #define LN_VREF_TEST_RXLPBKDT_EN BIT(30) 341 + #define LN_VREF_TEST_RXLPBKDT_EN_OV BIT(31) 342 + 343 + #define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0 0x00 344 + #define LN_BYTECLK_RESET_SYNC_EN_OV BIT(2) 345 + #define LN_BYTECLK_RESET_SYNC_EN BIT(3) 346 + #define LN_BYTECLK_RESET_SYNC_CLR_OV BIT(4) 347 + #define LN_BYTECLK_RESET_SYNC_CLR BIT(5) 348 + #define LN_BYTECLK_RESET_SYNC_SEL_OV BIT(6) 349 + 350 + #define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1 0x04 351 + #define LN_TXA_DIV2_EN_OV BIT(8) 352 + #define LN_TXA_DIV2_EN BIT(9) 353 + #define LN_TXA_DIV2_RESET_OV BIT(10) 354 + #define LN_TXA_DIV2_RESET BIT(11) 355 + #define LN_TXA_CLK_EN_OV BIT(22) 356 + #define LN_TXA_CLK_EN BIT(23) 357 + 358 + #define LN_AUSPMA_TX_SHM_TXA_IMP_REG0 0x08 359 + #define LN_TXA_CAL_CTRL_OV BIT(0) 360 + #define LN_TXA_CAL_CTRL GENMASK(18, 1) 361 + #define LN_TXA_CAL_CTRL_BASE_OV BIT(19) 362 + #define LN_TXA_CAL_CTRL_BASE GENMASK(23, 20) 363 + #define LN_TXA_HIZ_OV BIT(29) 364 + #define LN_TXA_HIZ BIT(30) 365 + 366 + #define LN_AUSPMA_TX_SHM_TXA_IMP_REG1 0x0C 367 + #define LN_AUSPMA_TX_SHM_TXA_IMP_REG2 0x10 368 + #define LN_TXA_MARGIN_OV BIT(0) 369 + #define LN_TXA_MARGIN GENMASK(18, 1) 370 + #define LN_TXA_MARGIN_2R_OV BIT(19) 371 + #define LN_TXA_MARGIN_2R BIT(20) 372 + 373 + #define LN_AUSPMA_TX_SHM_TXA_IMP_REG3 0x14 374 + #define LN_TXA_MARGIN_POST_OV BIT(0) 375 + #define LN_TXA_MARGIN_POST GENMASK(10, 1) 376 + #define LN_TXA_MARGIN_POST_2R_OV BIT(11) 377 + #define LN_TXA_MARGIN_POST_2R BIT(12) 378 + #define LN_TXA_MARGIN_POST_4R_OV BIT(13) 379 + #define LN_TXA_MARGIN_POST_4R BIT(14) 380 + #define LN_TXA_MARGIN_PRE_OV BIT(15) 381 + #define LN_TXA_MARGIN_PRE GENMASK(21, 16) 382 + #define LN_TXA_MARGIN_PRE_2R_OV BIT(22) 383 + #define LN_TXA_MARGIN_PRE_2R BIT(23) 384 + #define LN_TXA_MARGIN_PRE_4R_OV BIT(24) 385 + #define LN_TXA_MARGIN_PRE_4R BIT(25) 386 + 387 + #define LN_AUSPMA_TX_SHM_TXA_UNK_REG0 0x18 388 + #define LN_AUSPMA_TX_SHM_TXA_UNK_REG1 0x1C 389 + #define LN_AUSPMA_TX_SHM_TXA_UNK_REG2 0x20 390 + 391 + #define LN_AUSPMA_TX_SHM_TXA_LDOCLK 0x24 392 + #define LN_LDOCLK_BYPASS_SML_OV BIT(8) 393 + #define LN_LDOCLK_BYPASS_SML BIT(9) 394 + #define LN_LDOCLK_BYPASS_BIG_OV BIT(10) 395 + #define LN_LDOCLK_BYPASS_BIG BIT(11) 396 + #define LN_LDOCLK_EN_SML_OV BIT(12) 397 + #define LN_LDOCLK_EN_SML BIT(13) 398 + #define LN_LDOCLK_EN_BIG_OV BIT(14) 399 + #define LN_LDOCLK_EN_BIG BIT(15) 400 + 401 + /* LPDPTX registers */ 402 + #define LPDPTX_AUX_CFG_BLK_AUX_CTRL 0x0000 403 + #define LPDPTX_BLK_AUX_CTRL_PWRDN BIT(4) 404 + #define LPDPTX_BLK_AUX_RXOFFSET GENMASK(25, 22) 405 + 406 + #define LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL 0x0008 407 + 408 + #define LPDPTX_AUX_CFG_BLK_AUX_MARGIN 0x000c 409 + #define LPDPTX_MARGIN_RCAL_RXOFFSET_EN BIT(5) 410 + #define LPDPTX_AUX_MARGIN_RCAL_TXSWING GENMASK(10, 6) 411 + 412 + #define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0 0x0204 413 + #define LPDPTX_CFG_PMA_AUX_SEL_LF_DATA BIT(15) 414 + 415 + #define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1 0x0208 416 + #define LPDPTX_CFG_PMA_PHYS_ADJ GENMASK(22, 20) 417 + #define LPDPTX_CFG_PMA_PHYS_ADJ_OV BIT(19) 418 + 419 + #define LPDPTX_AUX_CONTROL 0x4000 420 + #define LPDPTX_AUX_PWN_DOWN 0x10 421 + #define LPDPTX_AUX_CLAMP_EN 0x04 422 + #define LPDPTX_SLEEP_B_BIG_IN 0x02 423 + #define LPDPTX_SLEEP_B_SML_IN 0x01 424 + #define LPDPTX_TXTERM_CODEMSB 0x400 425 + #define LPDPTX_TXTERM_CODE GENMASK(9, 5) 426 + 427 + /* pipehandler registers */ 428 + #define PIPEHANDLER_OVERRIDE 0x00 429 + #define PIPEHANDLER_OVERRIDE_RXVALID BIT(0) 430 + #define PIPEHANDLER_OVERRIDE_RXDETECT BIT(2) 431 + 432 + #define PIPEHANDLER_OVERRIDE_VALUES 0x04 433 + #define PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 BIT(1) 434 + #define PIPEHANDLER_OVERRIDE_VAL_RXDETECT1 BIT(2) 435 + #define PIPEHANDLER_OVERRIDE_VAL_PHY_STATUS BIT(4) 436 + 437 + #define PIPEHANDLER_MUX_CTRL 0x0c 438 + #define PIPEHANDLER_MUX_CTRL_CLK GENMASK(5, 3) 439 + #define PIPEHANDLER_MUX_CTRL_DATA GENMASK(2, 0) 440 + #define PIPEHANDLER_MUX_CTRL_CLK_OFF 0 441 + #define PIPEHANDLER_MUX_CTRL_CLK_USB3 1 442 + #define PIPEHANDLER_MUX_CTRL_CLK_USB4 2 443 + #define PIPEHANDLER_MUX_CTRL_CLK_DUMMY 4 444 + 445 + #define PIPEHANDLER_MUX_CTRL_DATA_USB3 0 446 + #define PIPEHANDLER_MUX_CTRL_DATA_USB4 1 447 + #define PIPEHANDLER_MUX_CTRL_DATA_DUMMY 2 448 + 449 + #define PIPEHANDLER_LOCK_REQ 0x10 450 + #define PIPEHANDLER_LOCK_ACK 0x14 451 + #define PIPEHANDLER_LOCK_EN BIT(0) 452 + 453 + #define PIPEHANDLER_AON_GEN 0x1C 454 + #define PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN BIT(4) 455 + #define PIPEHANDLER_AON_GEN_DWC3_RESET_N BIT(0) 456 + 457 + #define PIPEHANDLER_NONSELECTED_OVERRIDE 0x20 458 + #define PIPEHANDLER_NATIVE_RESET BIT(12) 459 + #define PIPEHANDLER_DUMMY_PHY_EN BIT(15) 460 + #define PIPEHANDLER_NATIVE_POWER_DOWN GENMASK(3, 0) 461 + 462 + #define PIPEHANDLER_LOCK_ACK_TIMEOUT_US 1000 463 + 464 + /* USB2 PHY regs */ 465 + #define USB2PHY_USBCTL 0x00 466 + #define USB2PHY_USBCTL_RUN 2 467 + #define USB2PHY_USBCTL_ISOLATION 4 468 + 469 + #define USB2PHY_CTL 0x04 470 + #define USB2PHY_CTL_RESET BIT(0) 471 + #define USB2PHY_CTL_PORT_RESET BIT(1) 472 + #define USB2PHY_CTL_APB_RESET_N BIT(2) 473 + #define USB2PHY_CTL_SIDDQ BIT(3) 474 + 475 + #define USB2PHY_SIG 0x08 476 + #define USB2PHY_SIG_VBUSDET_FORCE_VAL BIT(0) 477 + #define USB2PHY_SIG_VBUSDET_FORCE_EN BIT(1) 478 + #define USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL BIT(2) 479 + #define USB2PHY_SIG_VBUSVLDEXT_FORCE_EN BIT(3) 480 + #define USB2PHY_SIG_HOST (7 << 12) 481 + 482 + #define USB2PHY_MISCTUNE 0x1c 483 + #define USB2PHY_MISCTUNE_APBCLK_GATE_OFF BIT(29) 484 + #define USB2PHY_MISCTUNE_REFCLK_GATE_OFF BIT(30) 485 + 486 + enum atcphy_dp_link_rate { 487 + ATCPHY_DP_LINK_RATE_RBR, 488 + ATCPHY_DP_LINK_RATE_HBR, 489 + ATCPHY_DP_LINK_RATE_HBR2, 490 + ATCPHY_DP_LINK_RATE_HBR3, 491 + }; 492 + 493 + /** 494 + * enum atcphy_pipehandler_state - States of the PIPE mux interface ("pipehandler") 495 + * @ATCPHY_PIPEHANDLER_STATE_DUMMY: "Dummy PHY" (disables USB3, USB2 only) 496 + * @ATCPHY_PIPEHANDLER_STATE_USB3: USB3 directly connected to the Type-C port 497 + * @ATCPHY_PIPEHANDLER_STATE_USB4: USB3 tunneled via USB4/Thunderbolt 498 + * 499 + * DWC3's USB3 PIPE interface is connected to a multiplexer inside this PHY 500 + * which can switch between a dummy state (which effectively disables any USB3 501 + * support and falls back to USB2 only operation via the separate ULPI interface), 502 + * a USB3 state (for regular USB3 or USB3+DisplayPort operation) and a USB4 state 503 + * (for USB3 tunneled via USB4/Thunderbolt). 504 + */ 505 + enum atcphy_pipehandler_state { 506 + ATCPHY_PIPEHANDLER_STATE_DUMMY, 507 + ATCPHY_PIPEHANDLER_STATE_USB3, 508 + ATCPHY_PIPEHANDLER_STATE_USB4, 509 + }; 510 + 511 + /** 512 + * enum atcphy_mode - Operating modes of the PHY 513 + * @APPLE_ATCPHY_MODE_OFF: all PHYs powered off 514 + * @APPLE_ATCPHY_MODE_USB2: Nothing on the four SS lanes (i.e. USB2 only on D-/+) 515 + * @APPLE_ATCPHY_MODE_USB3: USB3 on two lanes, nothing on the other two 516 + * @APPLE_ATCPHY_MODE_USB3_DP: USB3 on two lanes and DisplayPort on the other two 517 + * @APPLE_ATCPHY_MODE_TBT: Thunderbolt on all lanes 518 + * @APPLE_ATCPHY_MODE_USB4: USB4 on all lanes 519 + * @APPLE_ATCPHY_MODE_DP: DisplayPort on all lanes 520 + */ 521 + enum atcphy_mode { 522 + APPLE_ATCPHY_MODE_OFF, 523 + APPLE_ATCPHY_MODE_USB2, 524 + APPLE_ATCPHY_MODE_USB3, 525 + APPLE_ATCPHY_MODE_USB3_DP, 526 + APPLE_ATCPHY_MODE_TBT, 527 + APPLE_ATCPHY_MODE_USB4, 528 + APPLE_ATCPHY_MODE_DP, 529 + }; 530 + 531 + enum atcphy_lane { 532 + APPLE_ATCPHY_LANE_0, 533 + APPLE_ATCPHY_LANE_1, 534 + }; 535 + 536 + /* Link rate configuration, field names are taken from XNU debug output or register names */ 537 + struct atcphy_dp_link_rate_configuration { 538 + u16 freqinit_count_target; 539 + u16 fbdivn_frac_den; 540 + u16 fbdivn_frac_num; 541 + u16 pclk_div_sel; 542 + u8 lfclk_ctrl; 543 + u8 vclk_op_divn; 544 + bool plla_clkout_vreg_bypass; 545 + bool txa_ldoclk_bypass; 546 + bool txa_div2_en; 547 + }; 548 + 549 + /* Crossbar and lane configuration */ 550 + struct atcphy_mode_configuration { 551 + u32 crossbar; 552 + u32 crossbar_dp_single_pma; 553 + bool crossbar_dp_both_pma; 554 + enum atcphy_lane_mode lane_mode[2]; 555 + bool dp_lane[2]; 556 + bool set_swap; 557 + }; 558 + 559 + /** 560 + * struct apple_atcphy - Apple Type-C PHY device struct 561 + * @np: Device node pointer 562 + * @dev: Device pointer 563 + * @tunables: Firmware-provided tunable parameters 564 + * @tunables.axi2af: AXI to AF interface tunables 565 + * @tunables.common: Common tunables for all lanes 566 + * @tunables.lane_usb3: USB3 lane-specific tunables 567 + * @tunables.lane_dp: DisplayPort lane-specific tunables 568 + * @tunables.lane_usb4: USB4 lane-specific tunables 569 + * @mode: Current PHY operating mode 570 + * @swap_lanes: True if lanes must be swapped due to cable orientation 571 + * @dp_link_rate: DisplayPort link rate 572 + * @pipehandler_up: True if the PIPE mux ("pipehandler") is set to USB3 or USB4 mode 573 + * @regs: Memory-mapped registers 574 + * @regs.core: Core registers 575 + * @regs.axi2af: AXI to Apple Fabric interface registers 576 + * @regs.usb2phy: USB2 PHY registers 577 + * @regs.pipehandler: USB3 PIPE interface ("pipehandler") registers 578 + * @regs.lpdptx: DisplayPort registers 579 + * @res: Resources for memory-mapped registers, used to verify that tunables aren't out of bounds 580 + * @res.core: Core register resource 581 + * @res.axi2af: AXI to Apple Fabric interface resource 582 + * @phys: PHY instances 583 + * @phys.usb2: USB2 PHY instance 584 + * @phys.usb3: USB3 PHY instance 585 + * @phys.dp: DisplayPort PHY instance 586 + * @phy_provider: PHY provider instance 587 + * @rcdev: Reset controller device 588 + * @sw: Type-C switch instance 589 + * @mux: Type-C mux instance 590 + * @lock: Mutex for synchronizing register access across PHY, Type-C switch/mux and reset controller 591 + */ 592 + struct apple_atcphy { 593 + struct device_node *np; 594 + struct device *dev; 595 + 596 + struct { 597 + struct apple_tunable *axi2af; 598 + struct apple_tunable *common[2]; 599 + struct apple_tunable *lane_usb3[2]; 600 + struct apple_tunable *lane_dp[2]; 601 + struct apple_tunable *lane_usb4[2]; 602 + } tunables; 603 + 604 + enum atcphy_mode mode; 605 + bool swap_lanes; 606 + int dp_link_rate; 607 + bool pipehandler_up; 608 + 609 + struct { 610 + void __iomem *core; 611 + void __iomem *axi2af; 612 + void __iomem *usb2phy; 613 + void __iomem *pipehandler; 614 + void __iomem *lpdptx; 615 + } regs; 616 + 617 + struct { 618 + struct resource *core; 619 + struct resource *axi2af; 620 + } res; 621 + 622 + struct { 623 + struct phy *usb2; 624 + struct phy *usb3; 625 + struct phy *dp; 626 + } phys; 627 + struct phy_provider *phy_provider; 628 + 629 + struct reset_controller_dev rcdev; 630 + 631 + struct typec_switch *sw; 632 + struct typec_mux *mux; 633 + 634 + struct mutex lock; 635 + }; 636 + 637 + static const struct { 638 + const struct atcphy_mode_configuration normal; 639 + const struct atcphy_mode_configuration swapped; 640 + bool enable_dp_aux; 641 + enum atcphy_pipehandler_state pipehandler_state; 642 + } atcphy_modes[] = { 643 + [APPLE_ATCPHY_MODE_OFF] = { 644 + .normal = { 645 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3, 646 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 647 + .crossbar_dp_both_pma = false, 648 + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, 649 + .dp_lane = {false, false}, 650 + .set_swap = false, 651 + }, 652 + .swapped = { 653 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED, 654 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 655 + .crossbar_dp_both_pma = false, 656 + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, 657 + .dp_lane = {false, false}, 658 + .set_swap = false, /* doesn't matter since the SS lanes are off */ 659 + }, 660 + .enable_dp_aux = false, 661 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, 662 + }, 663 + [APPLE_ATCPHY_MODE_USB2] = { 664 + .normal = { 665 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3, 666 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 667 + .crossbar_dp_both_pma = false, 668 + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, 669 + .dp_lane = {false, false}, 670 + .set_swap = false, 671 + }, 672 + .swapped = { 673 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED, 674 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 675 + .crossbar_dp_both_pma = false, 676 + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, 677 + .dp_lane = {false, false}, 678 + .set_swap = false, /* doesn't matter since the SS lanes are off */ 679 + }, 680 + .enable_dp_aux = false, 681 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, 682 + }, 683 + [APPLE_ATCPHY_MODE_USB3] = { 684 + /* 685 + * Setting up the lanes as DP/USB3 is intentional here, USB3/USB3 does not work 686 + * and isn't required since this PHY does not support 20GBps mode anyway. 687 + * The only difference to APPLE_ATCPHY_MODE_USB3_DP is that DP Aux is not enabled. 688 + */ 689 + .normal = { 690 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP, 691 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, 692 + .crossbar_dp_both_pma = false, 693 + .lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_DP}, 694 + .dp_lane = {false, true}, 695 + .set_swap = false, 696 + }, 697 + .swapped = { 698 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED, 699 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, 700 + .crossbar_dp_both_pma = false, 701 + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_USB3}, 702 + .dp_lane = {true, false}, 703 + .set_swap = true, 704 + }, 705 + .enable_dp_aux = false, 706 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3, 707 + }, 708 + [APPLE_ATCPHY_MODE_USB3_DP] = { 709 + .normal = { 710 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP, 711 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, 712 + .crossbar_dp_both_pma = false, 713 + .lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_DP}, 714 + .dp_lane = {false, true}, 715 + .set_swap = false, 716 + }, 717 + .swapped = { 718 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED, 719 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, 720 + .crossbar_dp_both_pma = false, 721 + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_USB3}, 722 + .dp_lane = {true, false}, 723 + .set_swap = true, 724 + }, 725 + .enable_dp_aux = true, 726 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3, 727 + }, 728 + [APPLE_ATCPHY_MODE_TBT] = { 729 + .normal = { 730 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4, 731 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 732 + .crossbar_dp_both_pma = false, 733 + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, 734 + .dp_lane = {false, false}, 735 + .set_swap = false, 736 + }, 737 + .swapped = { 738 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED, 739 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 740 + .crossbar_dp_both_pma = false, 741 + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, 742 + .dp_lane = {false, false}, 743 + .set_swap = false, /* intentionally false */ 744 + }, 745 + .enable_dp_aux = false, 746 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, 747 + }, 748 + [APPLE_ATCPHY_MODE_USB4] = { 749 + .normal = { 750 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4, 751 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 752 + .crossbar_dp_both_pma = false, 753 + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, 754 + .dp_lane = {false, false}, 755 + .set_swap = false, 756 + }, 757 + .swapped = { 758 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED, 759 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, 760 + .crossbar_dp_both_pma = false, 761 + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, 762 + .dp_lane = {false, false}, 763 + .set_swap = false, /* intentionally false */ 764 + }, 765 + .enable_dp_aux = false, 766 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB4, 767 + }, 768 + [APPLE_ATCPHY_MODE_DP] = { 769 + .normal = { 770 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP, 771 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100, 772 + .crossbar_dp_both_pma = true, 773 + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP}, 774 + .dp_lane = {true, true}, 775 + .set_swap = false, 776 + }, 777 + .swapped = { 778 + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP, 779 + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, 780 + .crossbar_dp_both_pma = false, /* intentionally false */ 781 + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP}, 782 + .dp_lane = {true, true}, 783 + .set_swap = false, /* intentionally false */ 784 + }, 785 + .enable_dp_aux = true, 786 + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, 787 + }, 788 + }; 789 + 790 + static const struct atcphy_dp_link_rate_configuration dp_lr_config[] = { 791 + [ATCPHY_DP_LINK_RATE_RBR] = { 792 + .freqinit_count_target = 0x21c, 793 + .fbdivn_frac_den = 0x0, 794 + .fbdivn_frac_num = 0x0, 795 + .pclk_div_sel = 0x13, 796 + .lfclk_ctrl = 0x5, 797 + .vclk_op_divn = 0x2, 798 + .plla_clkout_vreg_bypass = true, 799 + .txa_ldoclk_bypass = true, 800 + .txa_div2_en = true, 801 + }, 802 + [ATCPHY_DP_LINK_RATE_HBR] = { 803 + .freqinit_count_target = 0x1c2, 804 + .fbdivn_frac_den = 0x3ffe, 805 + .fbdivn_frac_num = 0x1fff, 806 + .pclk_div_sel = 0x9, 807 + .lfclk_ctrl = 0x5, 808 + .vclk_op_divn = 0x2, 809 + .plla_clkout_vreg_bypass = true, 810 + .txa_ldoclk_bypass = true, 811 + .txa_div2_en = false, 812 + }, 813 + [ATCPHY_DP_LINK_RATE_HBR2] = { 814 + .freqinit_count_target = 0x1c2, 815 + .fbdivn_frac_den = 0x3ffe, 816 + .fbdivn_frac_num = 0x1fff, 817 + .pclk_div_sel = 0x4, 818 + .lfclk_ctrl = 0x5, 819 + .vclk_op_divn = 0x0, 820 + .plla_clkout_vreg_bypass = true, 821 + .txa_ldoclk_bypass = true, 822 + .txa_div2_en = false, 823 + }, 824 + [ATCPHY_DP_LINK_RATE_HBR3] = { 825 + .freqinit_count_target = 0x2a3, 826 + .fbdivn_frac_den = 0x3ffc, 827 + .fbdivn_frac_num = 0x2ffd, 828 + .pclk_div_sel = 0x4, 829 + .lfclk_ctrl = 0x6, 830 + .vclk_op_divn = 0x0, 831 + .plla_clkout_vreg_bypass = false, 832 + .txa_ldoclk_bypass = false, 833 + .txa_div2_en = false, 834 + }, 835 + }; 836 + 837 + static inline void mask32(void __iomem *reg, u32 mask, u32 set) 838 + { 839 + u32 value = readl(reg); 840 + 841 + value &= ~mask; 842 + value |= set; 843 + writel(value, reg); 844 + } 845 + 846 + static inline void core_mask32(struct apple_atcphy *atcphy, u32 reg, u32 mask, u32 set) 847 + { 848 + mask32(atcphy->regs.core + reg, mask, set); 849 + } 850 + 851 + static inline void set32(void __iomem *reg, u32 set) 852 + { 853 + mask32(reg, 0, set); 854 + } 855 + 856 + static inline void core_set32(struct apple_atcphy *atcphy, u32 reg, u32 set) 857 + { 858 + core_mask32(atcphy, reg, 0, set); 859 + } 860 + 861 + static inline void clear32(void __iomem *reg, u32 clear) 862 + { 863 + mask32(reg, clear, 0); 864 + } 865 + 866 + static inline void core_clear32(struct apple_atcphy *atcphy, u32 reg, u32 clear) 867 + { 868 + core_mask32(atcphy, reg, clear, 0); 869 + } 870 + 871 + static const struct atcphy_mode_configuration *atcphy_get_mode_config(struct apple_atcphy *atcphy, 872 + enum atcphy_mode mode) 873 + { 874 + if (atcphy->swap_lanes) 875 + return &atcphy_modes[mode].swapped; 876 + else 877 + return &atcphy_modes[mode].normal; 878 + } 879 + 880 + static void atcphy_apply_tunables(struct apple_atcphy *atcphy, enum atcphy_mode mode) 881 + { 882 + const int lane0 = atcphy->swap_lanes ? 1 : 0; 883 + const int lane1 = atcphy->swap_lanes ? 0 : 1; 884 + 885 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.common[0]); 886 + apple_tunable_apply(atcphy->regs.axi2af, atcphy->tunables.axi2af); 887 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.common[1]); 888 + 889 + switch (mode) { 890 + /* 891 + * USB 3.2 Gen 2x2 / SuperSpeed 20Gbps is not supported by this hardware and applying USB3 892 + * tunables to both lanes does not result in a working PHY configuration. Thus, both 893 + * USB3-only and USB3/DP get the same tunable setup here. 894 + */ 895 + case APPLE_ATCPHY_MODE_USB3: 896 + case APPLE_ATCPHY_MODE_USB3_DP: 897 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb3[lane0]); 898 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane1]); 899 + break; 900 + 901 + case APPLE_ATCPHY_MODE_DP: 902 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane0]); 903 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane1]); 904 + break; 905 + 906 + /* 907 + * Even though the various Thunderbolt versions and USB4 are different protocols they need 908 + * the same tunables. The actual protocol-specific setup happens inside the Thunderbolt/USB4 909 + * native host interface. 910 + */ 911 + case APPLE_ATCPHY_MODE_TBT: 912 + case APPLE_ATCPHY_MODE_USB4: 913 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb4[lane0]); 914 + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb4[lane1]); 915 + break; 916 + 917 + case APPLE_ATCPHY_MODE_OFF: 918 + case APPLE_ATCPHY_MODE_USB2: 919 + break; 920 + } 921 + } 922 + 923 + static int atcphy_pipehandler_lock(struct apple_atcphy *atcphy) 924 + { 925 + int ret; 926 + u32 reg; 927 + 928 + if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ) & PIPEHANDLER_LOCK_EN) { 929 + dev_warn(atcphy->dev, "Pipehandler already locked\n"); 930 + return 0; 931 + } 932 + 933 + set32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, PIPEHANDLER_LOCK_EN); 934 + 935 + ret = readl_poll_timeout(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK, reg, 936 + reg & PIPEHANDLER_LOCK_EN, 10, PIPEHANDLER_LOCK_ACK_TIMEOUT_US); 937 + if (ret) { 938 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, 1); 939 + dev_warn(atcphy->dev, "Pipehandler lock not acked.\n"); 940 + } 941 + 942 + return ret; 943 + } 944 + 945 + static int atcphy_pipehandler_unlock(struct apple_atcphy *atcphy) 946 + { 947 + int ret; 948 + u32 reg; 949 + 950 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, PIPEHANDLER_LOCK_EN); 951 + ret = readl_poll_timeout(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK, reg, 952 + !(reg & PIPEHANDLER_LOCK_EN), 10, PIPEHANDLER_LOCK_ACK_TIMEOUT_US); 953 + if (ret) 954 + dev_warn(atcphy->dev, "Pipehandler lock release not acked.\n"); 955 + 956 + return ret; 957 + } 958 + 959 + static int atcphy_pipehandler_check(struct apple_atcphy *atcphy) 960 + { 961 + int ret; 962 + 963 + lockdep_assert_held(&atcphy->lock); 964 + 965 + if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK) & PIPEHANDLER_LOCK_EN) { 966 + dev_warn(atcphy->dev, "Pipehandler already locked\n"); 967 + 968 + ret = atcphy_pipehandler_unlock(atcphy); 969 + if (ret) { 970 + dev_err(atcphy->dev, "Failed to unlock pipehandler\n"); 971 + return ret; 972 + } 973 + } 974 + 975 + return 0; 976 + } 977 + 978 + static int atcphy_configure_pipehandler_usb3(struct apple_atcphy *atcphy, bool host) 979 + { 980 + int ret; 981 + u32 reg; 982 + 983 + ret = atcphy_pipehandler_check(atcphy); 984 + if (ret) 985 + return ret; 986 + 987 + /* 988 + * Only host mode requires this unknown BIST sequence to work correctly, possibly due to 989 + * some hardware quirk. Guest mode breaks if we try to apply this sequence. 990 + */ 991 + if (host) { 992 + /* Force disable link detection */ 993 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES, 994 + PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 | PIPEHANDLER_OVERRIDE_VAL_RXDETECT1); 995 + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, 996 + PIPEHANDLER_OVERRIDE_RXVALID); 997 + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, 998 + PIPEHANDLER_OVERRIDE_RXDETECT); 999 + 1000 + ret = atcphy_pipehandler_lock(atcphy); 1001 + if (ret) { 1002 + dev_err(atcphy->dev, "Failed to lock pipehandler"); 1003 + return ret; 1004 + } 1005 + 1006 + /* BIST dance */ 1007 + core_set32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG0, 1008 + ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N); 1009 + core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG, ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV); 1010 + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, 1011 + !(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 10, 10000); 1012 + if (ret) 1013 + dev_warn(atcphy->dev, 1014 + "Timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n"); 1015 + 1016 + core_set32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL, 1017 + ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE); 1018 + core_clear32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL, 1019 + ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE); 1020 + 1021 + core_mask32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG1, 1022 + ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN, 1023 + FIELD_PREP(ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN, 3)); 1024 + 1025 + core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG, 1026 + ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV); 1027 + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, 1028 + ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN); 1029 + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, 1030 + ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN); 1031 + writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_CIOPHY_CFG1); 1032 + 1033 + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, 1034 + (reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK0), 10, 10000); 1035 + if (ret) 1036 + dev_warn(atcphy->dev, 1037 + "timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK0\n"); 1038 + 1039 + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, 1040 + !(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 10, 10000); 1041 + if (ret) 1042 + dev_warn(atcphy->dev, 1043 + "timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n"); 1044 + 1045 + /* Clear reset for non-selected USB3 PHY (?) */ 1046 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, 1047 + PIPEHANDLER_NATIVE_POWER_DOWN, FIELD_PREP(PIPEHANDLER_NATIVE_POWER_DOWN, 3)); 1048 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, 1049 + PIPEHANDLER_NATIVE_RESET); 1050 + 1051 + /* More BIST stuff (?) */ 1052 + writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_OV_CFG); 1053 + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, 1054 + ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN); 1055 + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, 1056 + ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN); 1057 + } 1058 + 1059 + /* Configure PIPE mux to USB3 PHY */ 1060 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1061 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); 1062 + udelay(10); 1063 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, 1064 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_USB3)); 1065 + udelay(10); 1066 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1067 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_USB3)); 1068 + udelay(10); 1069 + 1070 + /* Remove link detection override */ 1071 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXVALID); 1072 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXDETECT); 1073 + 1074 + /* Pipehandler was only locked when the BIST sequence was applied for host mode */ 1075 + if (host) { 1076 + ret = atcphy_pipehandler_unlock(atcphy); 1077 + if (ret) 1078 + dev_warn(atcphy->dev, "Failed to unlock pipehandler"); 1079 + } 1080 + 1081 + return 0; 1082 + } 1083 + 1084 + static int atcphy_configure_pipehandler_dummy(struct apple_atcphy *atcphy) 1085 + { 1086 + int ret; 1087 + 1088 + ret = atcphy_pipehandler_check(atcphy); 1089 + if (ret) 1090 + return ret; 1091 + 1092 + /* Force disable link detection */ 1093 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES, 1094 + PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 | PIPEHANDLER_OVERRIDE_VAL_RXDETECT1); 1095 + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXVALID); 1096 + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXDETECT); 1097 + 1098 + ret = atcphy_pipehandler_lock(atcphy); 1099 + if (ret) 1100 + dev_warn(atcphy->dev, "Failed to lock pipehandler"); 1101 + 1102 + /* Switch to dummy PHY */ 1103 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1104 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); 1105 + udelay(10); 1106 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, 1107 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_DUMMY)); 1108 + udelay(10); 1109 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1110 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_DUMMY)); 1111 + udelay(10); 1112 + 1113 + ret = atcphy_pipehandler_unlock(atcphy); 1114 + if (ret) 1115 + dev_warn(atcphy->dev, "Failed to unlock pipehandler"); 1116 + 1117 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, 1118 + PIPEHANDLER_NATIVE_POWER_DOWN, FIELD_PREP(PIPEHANDLER_NATIVE_POWER_DOWN, 2)); 1119 + set32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, 1120 + PIPEHANDLER_NATIVE_RESET); 1121 + 1122 + return 0; 1123 + } 1124 + 1125 + static int atcphy_configure_pipehandler(struct apple_atcphy *atcphy, bool host) 1126 + { 1127 + int ret; 1128 + 1129 + lockdep_assert_held(&atcphy->lock); 1130 + 1131 + switch (atcphy_modes[atcphy->mode].pipehandler_state) { 1132 + case ATCPHY_PIPEHANDLER_STATE_USB3: 1133 + ret = atcphy_configure_pipehandler_usb3(atcphy, host); 1134 + atcphy->pipehandler_up = true; 1135 + break; 1136 + case ATCPHY_PIPEHANDLER_STATE_USB4: 1137 + dev_warn(atcphy->dev, 1138 + "ATCPHY_PIPEHANDLER_STATE_USB4 not implemented; falling back to USB2\n"); 1139 + ret = atcphy_configure_pipehandler_dummy(atcphy); 1140 + atcphy->pipehandler_up = false; 1141 + break; 1142 + default: 1143 + ret = -EINVAL; 1144 + } 1145 + 1146 + return ret; 1147 + } 1148 + 1149 + static void atcphy_setup_pipehandler(struct apple_atcphy *atcphy) 1150 + { 1151 + lockdep_assert_held(&atcphy->lock); 1152 + 1153 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1154 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); 1155 + udelay(10); 1156 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, 1157 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_DUMMY)); 1158 + udelay(10); 1159 + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, 1160 + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_DUMMY)); 1161 + udelay(10); 1162 + } 1163 + 1164 + static void atcphy_configure_lanes(struct apple_atcphy *atcphy, enum atcphy_mode mode) 1165 + { 1166 + const struct atcphy_mode_configuration *mode_cfg = atcphy_get_mode_config(atcphy, mode); 1167 + 1168 + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX0, 1169 + FIELD_PREP(ACIOPHY_LANE_MODE_RX0, mode_cfg->lane_mode[0])); 1170 + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX0, 1171 + FIELD_PREP(ACIOPHY_LANE_MODE_TX0, mode_cfg->lane_mode[0])); 1172 + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX1, 1173 + FIELD_PREP(ACIOPHY_LANE_MODE_RX1, mode_cfg->lane_mode[1])); 1174 + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX1, 1175 + FIELD_PREP(ACIOPHY_LANE_MODE_TX1, mode_cfg->lane_mode[1])); 1176 + core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_PROTOCOL, 1177 + FIELD_PREP(ACIOPHY_CROSSBAR_PROTOCOL, mode_cfg->crossbar)); 1178 + 1179 + if (mode_cfg->set_swap) 1180 + core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP); 1181 + else 1182 + core_clear32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP); 1183 + 1184 + core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_SINGLE_PMA, 1185 + FIELD_PREP(ACIOPHY_CROSSBAR_DP_SINGLE_PMA, mode_cfg->crossbar_dp_single_pma)); 1186 + if (mode_cfg->crossbar_dp_both_pma) 1187 + core_set32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_BOTH_PMA); 1188 + else 1189 + core_clear32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_BOTH_PMA); 1190 + 1191 + if (mode_cfg->dp_lane[0]) { 1192 + core_set32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1193 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); 1194 + udelay(10); 1195 + core_clear32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1196 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ); 1197 + } else { 1198 + core_clear32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1199 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); 1200 + udelay(10); 1201 + } 1202 + 1203 + if (mode_cfg->dp_lane[1]) { 1204 + core_set32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1205 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); 1206 + udelay(10); 1207 + core_clear32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1208 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ); 1209 + } else { 1210 + core_clear32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, 1211 + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); 1212 + udelay(10); 1213 + } 1214 + } 1215 + 1216 + static void atcphy_enable_dp_aux(struct apple_atcphy *atcphy) 1217 + { 1218 + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N); 1219 + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N_OV); 1220 + 1221 + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_SELECT, 1222 + FIELD_PREP(DPRX_PCLK_SELECT, 1)); 1223 + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_ENABLE); 1224 + 1225 + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_SELECT, 1226 + FIELD_PREP(DPTX_PCLK1_SELECT, 1)); 1227 + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_ENABLE); 1228 + 1229 + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_SELECT, 1230 + FIELD_PREP(DPTX_PCLK2_SELECT, 1)); 1231 + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_ENABLE); 1232 + 1233 + core_set32(atcphy, ACIOPHY_PLL_COMMON_CTRL, 1234 + ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT); 1235 + 1236 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); 1237 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_SML_IN); 1238 + udelay(10); 1239 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_BIG_IN); 1240 + udelay(10); 1241 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); 1242 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN); 1243 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_TXTERM_CODEMSB); 1244 + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_TXTERM_CODE, 1245 + FIELD_PREP(LPDPTX_TXTERM_CODE, 0x16)); 1246 + 1247 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL, 0x1c00); 1248 + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1, LPDPTX_CFG_PMA_PHYS_ADJ, 1249 + FIELD_PREP(LPDPTX_CFG_PMA_PHYS_ADJ, 5)); 1250 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1, 1251 + LPDPTX_CFG_PMA_PHYS_ADJ_OV); 1252 + 1253 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN, 1254 + LPDPTX_MARGIN_RCAL_RXOFFSET_EN); 1255 + 1256 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_CTRL_PWRDN); 1257 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0, 1258 + LPDPTX_CFG_PMA_AUX_SEL_LF_DATA); 1259 + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_RXOFFSET, 1260 + FIELD_PREP(LPDPTX_BLK_AUX_RXOFFSET, 3)); 1261 + 1262 + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN, LPDPTX_AUX_MARGIN_RCAL_TXSWING, 1263 + FIELD_PREP(LPDPTX_AUX_MARGIN_RCAL_TXSWING, 12)); 1264 + 1265 + atcphy->dp_link_rate = -1; 1266 + } 1267 + 1268 + static void atcphy_disable_dp_aux(struct apple_atcphy *atcphy) 1269 + { 1270 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN); 1271 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_CTRL_PWRDN); 1272 + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); 1273 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_SML_IN); 1274 + udelay(10); 1275 + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_BIG_IN); 1276 + udelay(10); 1277 + 1278 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N); 1279 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_ENABLE); 1280 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_ENABLE); 1281 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_ENABLE); 1282 + } 1283 + 1284 + static int atcphy_dp_configure_lane(struct apple_atcphy *atcphy, enum atcphy_lane lane, 1285 + const struct atcphy_dp_link_rate_configuration *cfg) 1286 + { 1287 + void __iomem *tx_shm, *rx_shm, *rx_top; 1288 + unsigned int tx_cal_code; 1289 + 1290 + lockdep_assert_held(&atcphy->lock); 1291 + 1292 + switch (lane) { 1293 + case APPLE_ATCPHY_LANE_0: 1294 + tx_shm = atcphy->regs.core + LN0_AUSPMA_TX_SHM; 1295 + rx_shm = atcphy->regs.core + LN0_AUSPMA_RX_SHM; 1296 + rx_top = atcphy->regs.core + LN0_AUSPMA_RX_TOP; 1297 + break; 1298 + case APPLE_ATCPHY_LANE_1: 1299 + tx_shm = atcphy->regs.core + LN1_AUSPMA_TX_SHM; 1300 + rx_shm = atcphy->regs.core + LN1_AUSPMA_RX_SHM; 1301 + rx_top = atcphy->regs.core + LN1_AUSPMA_RX_TOP; 1302 + break; 1303 + default: 1304 + return -EINVAL; 1305 + } 1306 + 1307 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML); 1308 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML_OV); 1309 + udelay(10); 1310 + 1311 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG); 1312 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG_OV); 1313 + udelay(10); 1314 + 1315 + if (cfg->txa_ldoclk_bypass) { 1316 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML); 1317 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML_OV); 1318 + udelay(10); 1319 + 1320 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG); 1321 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG_OV); 1322 + udelay(10); 1323 + } else { 1324 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML); 1325 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML_OV); 1326 + udelay(10); 1327 + 1328 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG); 1329 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG_OV); 1330 + udelay(10); 1331 + } 1332 + 1333 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_SEL_OV); 1334 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_EN); 1335 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_EN_OV); 1336 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_CLR); 1337 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_CLR_OV); 1338 + 1339 + if (cfg->txa_div2_en) 1340 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN); 1341 + else 1342 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN); 1343 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN_OV); 1344 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN); 1345 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN_OV); 1346 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_RESET); 1347 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_RESET_OV); 1348 + 1349 + mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE, 1350 + FIELD_PREP(LN_TXA_CAL_CTRL_BASE, 0xf)); 1351 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE_OV); 1352 + 1353 + tx_cal_code = FIELD_GET(AUS_UNK_A20_TX_CAL_CODE, readl(atcphy->regs.core + AUS_UNK_A20)); 1354 + mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL, 1355 + FIELD_PREP(LN_TXA_CAL_CTRL, (1 << tx_cal_code) - 1)); 1356 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_OV); 1357 + 1358 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN); 1359 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_OV); 1360 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R); 1361 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R_OV); 1362 + 1363 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST); 1364 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_OV); 1365 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R); 1366 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R_OV); 1367 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R); 1368 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R_OV); 1369 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE); 1370 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_OV); 1371 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R); 1372 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R_OV); 1373 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R); 1374 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R_OV); 1375 + 1376 + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ); 1377 + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ_OV); 1378 + 1379 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N); 1380 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N_OV); 1381 + udelay(10); 1382 + 1383 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N); 1384 + 1385 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_EN); 1386 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_EN_OV); 1387 + 1388 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE, 1389 + FIELD_PREP(LN_TX_CAL_CODE, tx_cal_code)); 1390 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE_OV); 1391 + 1392 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DLY_CTRL_TAPGEN, 1393 + FIELD_PREP(LN_TX_CLK_DLY_CTRL_TAPGEN, 3)); 1394 + 1395 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST); 1396 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV); 1397 + 1398 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN); 1399 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN_OV); 1400 + 1401 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN); 1402 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN_OV); 1403 + 1404 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_TEST_RXLPBKDT_EN); 1405 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_TEST_RXLPBKDT_EN_OV); 1406 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_LPBKIN_DATA, 1407 + FIELD_PREP(LN_VREF_LPBKIN_DATA, 3)); 1408 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BIAS_SEL, 1409 + FIELD_PREP(LN_VREF_BIAS_SEL, 2)); 1410 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BIAS_SEL_OV); 1411 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_ADJUST_GRAY, 1412 + FIELD_PREP(LN_VREF_ADJUST_GRAY, 0x18)); 1413 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_ADJUST_GRAY_OV); 1414 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN); 1415 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN_OV); 1416 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN); 1417 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN_OV); 1418 + udelay(10); 1419 + 1420 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN); 1421 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN_OV); 1422 + udelay(10); 1423 + 1424 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN); 1425 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN_OV); 1426 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN); 1427 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN_OV); 1428 + 1429 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN); 1430 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN_OV); 1431 + 1432 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_PULLUP_LEAK_EN); 1433 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_PULLUP_LEAK_EN_OV); 1434 + 1435 + set32(rx_top + LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE, LN_RX_TXMODE); 1436 + 1437 + if (cfg->txa_div2_en) 1438 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN); 1439 + else 1440 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN); 1441 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN_OV); 1442 + 1443 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_RST); 1444 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_RST_OV); 1445 + 1446 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL); 1447 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL_OV); 1448 + 1449 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN); 1450 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_OV); 1451 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB); 1452 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB_OV); 1453 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1); 1454 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_OV); 1455 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_LSB); 1456 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_LSB_OV); 1457 + 1458 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE); 1459 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE_OV); 1460 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE); 1461 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE_OV); 1462 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE); 1463 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_OV); 1464 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_LSB); 1465 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_LSB_OV); 1466 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_LSB_CODE); 1467 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_LSB_CODE_OV); 1468 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE); 1469 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE_OV); 1470 + 1471 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN); 1472 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN_OV); 1473 + udelay(10); 1474 + 1475 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN); 1476 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN_OV); 1477 + udelay(10); 1478 + 1479 + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST, 1480 + FIELD_PREP(LN_DTVREG_ADJUST, 0xa)); 1481 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV); 1482 + udelay(10); 1483 + 1484 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN); 1485 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN_OV); 1486 + udelay(10); 1487 + 1488 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN); 1489 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN_OV); 1490 + 1491 + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_CLR); 1492 + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_CLR_OV); 1493 + 1494 + return 0; 1495 + } 1496 + 1497 + static int atcphy_auspll_apb_command(struct apple_atcphy *atcphy, u32 command) 1498 + { 1499 + int ret; 1500 + u32 reg; 1501 + 1502 + reg = readl(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE); 1503 + reg &= ~AUSPLL_APB_CMD_OVERRIDE_CMD; 1504 + reg |= FIELD_PREP(AUSPLL_APB_CMD_OVERRIDE_CMD, command); 1505 + reg |= AUSPLL_APB_CMD_OVERRIDE_REQ; 1506 + reg |= AUSPLL_APB_CMD_OVERRIDE_UNK28; 1507 + writel(reg, atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE); 1508 + 1509 + ret = readl_poll_timeout(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE, reg, 1510 + (reg & AUSPLL_APB_CMD_OVERRIDE_ACK), 10, 10000); 1511 + if (ret) 1512 + dev_warn(atcphy->dev, "AUSPLL APB command was not acked\n"); 1513 + 1514 + core_clear32(atcphy, AUSPLL_APB_CMD_OVERRIDE, AUSPLL_APB_CMD_OVERRIDE_REQ); 1515 + 1516 + return 0; 1517 + } 1518 + 1519 + static int atcphy_dp_configure(struct apple_atcphy *atcphy, enum atcphy_dp_link_rate lr) 1520 + { 1521 + const struct atcphy_dp_link_rate_configuration *cfg; 1522 + const struct atcphy_mode_configuration *mode_cfg; 1523 + int ret; 1524 + u32 reg; 1525 + 1526 + guard(mutex)(&atcphy->lock); 1527 + mode_cfg = atcphy_get_mode_config(atcphy, atcphy->mode); 1528 + cfg = &dp_lr_config[lr]; 1529 + 1530 + if (atcphy->dp_link_rate == lr) 1531 + return 0; 1532 + 1533 + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_CMN_SHM_STS_REG0, reg, 1534 + (reg & ACIOPHY_CMN_SHM_STS_REG0_CMD_READY), 10, 10000); 1535 + if (ret) { 1536 + dev_err(atcphy->dev, "ACIOPHY_CMN_SHM_STS_REG0_CMD_READY not set.\n"); 1537 + return ret; 1538 + } 1539 + 1540 + core_clear32(atcphy, AUSPLL_FREQ_CFG, AUSPLL_FREQ_REFCLK); 1541 + 1542 + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FREQ_COUNT_TARGET, 1543 + FIELD_PREP(AUSPLL_FD_FREQ_COUNT_TARGET, cfg->freqinit_count_target)); 1544 + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FBDIVN_HALF); 1545 + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_REV_DIVN); 1546 + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_MAN, FIELD_PREP(AUSPLL_FD_KI_MAN, 8)); 1547 + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_EXP, FIELD_PREP(AUSPLL_FD_KI_EXP, 3)); 1548 + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_MAN, FIELD_PREP(AUSPLL_FD_KP_MAN, 8)); 1549 + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_EXP, FIELD_PREP(AUSPLL_FD_KP_EXP, 7)); 1550 + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KPKI_SCALE_HBW); 1551 + 1552 + core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_DEN, 1553 + FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_DEN, cfg->fbdivn_frac_den)); 1554 + core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_NUM, 1555 + FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_NUM, cfg->fbdivn_frac_num)); 1556 + 1557 + core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_STEP); 1558 + core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_EN); 1559 + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_PCLK_DIV_SEL, 1560 + FIELD_PREP(AUSPLL_FD_PCLK_DIV_SEL, cfg->pclk_div_sel)); 1561 + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFSDM_DIV, 1562 + FIELD_PREP(AUSPLL_FD_LFSDM_DIV, 1)); 1563 + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFCLK_CTRL, 1564 + FIELD_PREP(AUSPLL_FD_LFCLK_CTRL, cfg->lfclk_ctrl)); 1565 + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_OP_DIVN, 1566 + FIELD_PREP(AUSPLL_FD_VCLK_OP_DIVN, cfg->vclk_op_divn)); 1567 + core_set32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_PRE_DIVN); 1568 + 1569 + core_mask32(atcphy, AUSPLL_CLKOUT_DIV, AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI, 1570 + FIELD_PREP(AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI, 7)); 1571 + 1572 + if (cfg->plla_clkout_vreg_bypass) 1573 + core_set32(atcphy, AUSPLL_CLKOUT_DTC_VREG, AUSPLL_DTC_VREG_BYPASS); 1574 + else 1575 + core_clear32(atcphy, AUSPLL_CLKOUT_DTC_VREG, AUSPLL_DTC_VREG_BYPASS); 1576 + 1577 + core_set32(atcphy, AUSPLL_BGR, AUSPLL_BGR_CTRL_AVAIL); 1578 + 1579 + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN); 1580 + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN); 1581 + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN); 1582 + 1583 + ret = atcphy_auspll_apb_command(atcphy, 0); 1584 + if (ret) 1585 + return ret; 1586 + 1587 + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_DP_PCLK_STAT, reg, 1588 + (reg & ACIOPHY_AUSPLL_LOCK), 10, 10000); 1589 + if (ret) { 1590 + dev_err(atcphy->dev, "ACIOPHY_DP_PCLK did not lock.\n"); 1591 + return ret; 1592 + } 1593 + 1594 + ret = atcphy_auspll_apb_command(atcphy, 0x2800); 1595 + if (ret) 1596 + return ret; 1597 + 1598 + if (mode_cfg->dp_lane[0]) { 1599 + ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_0, cfg); 1600 + if (ret) 1601 + return ret; 1602 + } 1603 + 1604 + if (mode_cfg->dp_lane[1]) { 1605 + ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_1, cfg); 1606 + if (ret) 1607 + return ret; 1608 + } 1609 + 1610 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DP_PMA_BYTECLK_RESET); 1611 + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DP_MAC_DIV20_CLK_SEL); 1612 + 1613 + atcphy->dp_link_rate = lr; 1614 + return 0; 1615 + } 1616 + 1617 + static void atcphy_usb2_power_off(struct apple_atcphy *atcphy) 1618 + { 1619 + /* Disable the PHY, this clears USB2PHY_USBCTL_RUN */ 1620 + writel(USB2PHY_USBCTL_ISOLATION, atcphy->regs.usb2phy + USB2PHY_USBCTL); 1621 + udelay(10); 1622 + 1623 + /* Switch the PHY to low power mode */ 1624 + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ); 1625 + udelay(10); 1626 + 1627 + /* Enable all resets */ 1628 + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET); 1629 + udelay(10); 1630 + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET); 1631 + udelay(10); 1632 + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N); 1633 + udelay(10); 1634 + set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_APBCLK_GATE_OFF); 1635 + set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_REFCLK_GATE_OFF); 1636 + } 1637 + 1638 + static int atcphy_power_off(struct apple_atcphy *atcphy) 1639 + { 1640 + u32 reg; 1641 + int ret; 1642 + 1643 + atcphy_disable_dp_aux(atcphy); 1644 + 1645 + /* Enable all reset lines */ 1646 + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N); 1647 + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN); 1648 + core_clear32(atcphy, ATCPHY_MISC, ATCPHY_MISC_RESET_N | ATCPHY_MISC_LANE_SWAP); 1649 + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N); 1650 + 1651 + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG); 1652 + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, 1653 + !(reg & ATCPHY_POWER_SLEEP_BIG), 10, 1000); 1654 + if (ret) { 1655 + dev_err(atcphy->dev, "Failed to sleep atcphy \"big\"\n"); 1656 + return ret; 1657 + } 1658 + 1659 + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL); 1660 + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, 1661 + !(reg & ATCPHY_POWER_SLEEP_SMALL), 10, 1000); 1662 + if (ret) { 1663 + dev_err(atcphy->dev, "Failed to sleep atcphy \"small\"\n"); 1664 + return ret; 1665 + } 1666 + 1667 + return 0; 1668 + } 1669 + 1670 + static void atcphy_usb2_power_on(struct apple_atcphy *atcphy) 1671 + { 1672 + set32(atcphy->regs.usb2phy + USB2PHY_SIG, 1673 + USB2PHY_SIG_VBUSDET_FORCE_VAL | USB2PHY_SIG_VBUSDET_FORCE_EN | 1674 + USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL | USB2PHY_SIG_VBUSVLDEXT_FORCE_EN); 1675 + udelay(10); 1676 + 1677 + /* Take the PHY out of its low power state */ 1678 + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ); 1679 + udelay(10); 1680 + 1681 + /* Release reset */ 1682 + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET); 1683 + udelay(10); 1684 + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET); 1685 + udelay(10); 1686 + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N); 1687 + udelay(10); 1688 + clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_APBCLK_GATE_OFF); 1689 + clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_REFCLK_GATE_OFF); 1690 + 1691 + /* Enable the PHY */ 1692 + writel(USB2PHY_USBCTL_RUN, atcphy->regs.usb2phy + USB2PHY_USBCTL); 1693 + } 1694 + 1695 + static int atcphy_power_on(struct apple_atcphy *atcphy) 1696 + { 1697 + u32 reg; 1698 + int ret; 1699 + 1700 + atcphy_usb2_power_on(atcphy); 1701 + 1702 + core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_RESET_N); 1703 + 1704 + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL); 1705 + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, 1706 + reg & ATCPHY_POWER_SLEEP_SMALL, 100, 100000); 1707 + if (ret) { 1708 + dev_err(atcphy->dev, "failed to wakeup atcphy \"small\"\n"); 1709 + return ret; 1710 + } 1711 + 1712 + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG); 1713 + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, 1714 + reg & ATCPHY_POWER_SLEEP_BIG, 100, 100000); 1715 + if (ret) { 1716 + dev_err(atcphy->dev, "failed to wakeup atcphy \"big\"\n"); 1717 + return ret; 1718 + } 1719 + 1720 + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN); 1721 + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N); 1722 + 1723 + return 0; 1724 + } 1725 + 1726 + static int atcphy_configure(struct apple_atcphy *atcphy, enum atcphy_mode mode) 1727 + { 1728 + int ret = 0; 1729 + 1730 + lockdep_assert_held(&atcphy->lock); 1731 + 1732 + if (mode == APPLE_ATCPHY_MODE_OFF) { 1733 + ret = atcphy_power_off(atcphy); 1734 + atcphy->mode = mode; 1735 + return ret; 1736 + } 1737 + 1738 + ret = atcphy_power_on(atcphy); 1739 + if (ret) 1740 + return ret; 1741 + 1742 + atcphy_apply_tunables(atcphy, mode); 1743 + 1744 + core_set32(atcphy, AUSPLL_FSM_CTRL, 0x1fe000); 1745 + core_set32(atcphy, AUSPLL_APB_CMD_OVERRIDE, AUSPLL_APB_CMD_OVERRIDE_UNK28); 1746 + 1747 + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_SMALL_OV); 1748 + udelay(10); 1749 + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_BIG_OV); 1750 + udelay(10); 1751 + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_CLAMP_OV); 1752 + udelay(10); 1753 + 1754 + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_SMALL_OV, 1755 + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_SMALL_OV, 3)); 1756 + udelay(10); 1757 + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_BIG_OV, 1758 + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_BIG_OV, 3)); 1759 + udelay(10); 1760 + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV, 1761 + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV, 3)); 1762 + udelay(10); 1763 + 1764 + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_BIG_OV, 1765 + FIELD_PREP(ACIOPHY_CFG0_RX_BIG_OV, 3)); 1766 + udelay(10); 1767 + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_SMALL_OV, 1768 + FIELD_PREP(ACIOPHY_CFG0_RX_SMALL_OV, 3)); 1769 + udelay(10); 1770 + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_CLAMP_OV, 1771 + FIELD_PREP(ACIOPHY_CFG0_RX_CLAMP_OV, 3)); 1772 + udelay(10); 1773 + 1774 + /* Setup AUX channel if DP altmode is requested */ 1775 + if (atcphy_modes[mode].enable_dp_aux) 1776 + atcphy_enable_dp_aux(atcphy); 1777 + 1778 + /* Enable clocks and configure lanes */ 1779 + core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_PCLK_EN); 1780 + core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_REFCLK_EN); 1781 + atcphy_configure_lanes(atcphy, mode); 1782 + 1783 + /* Take the USB3 PHY out of reset */ 1784 + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N); 1785 + 1786 + atcphy->mode = mode; 1787 + 1788 + return 0; 1789 + } 1790 + 1791 + static int atcphy_usb2_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1792 + { 1793 + struct apple_atcphy *atcphy = phy_get_drvdata(phy); 1794 + 1795 + guard(mutex)(&atcphy->lock); 1796 + 1797 + switch (mode) { 1798 + case PHY_MODE_USB_HOST: 1799 + set32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST); 1800 + break; 1801 + case PHY_MODE_USB_DEVICE: 1802 + clear32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST); 1803 + break; 1804 + default: 1805 + return -EINVAL; 1806 + } 1807 + 1808 + return 0; 1809 + } 1810 + 1811 + static const struct phy_ops apple_atc_usb2_phy_ops = { 1812 + .owner = THIS_MODULE, 1813 + .set_mode = atcphy_usb2_set_mode, 1814 + }; 1815 + 1816 + static int atcphy_usb3_power_off(struct phy *phy) 1817 + { 1818 + struct apple_atcphy *atcphy = phy_get_drvdata(phy); 1819 + int ret; 1820 + 1821 + guard(mutex)(&atcphy->lock); 1822 + 1823 + ret = atcphy_configure_pipehandler_dummy(atcphy); 1824 + if (ret) 1825 + dev_warn(atcphy->dev, "Failed to switch pipe to dummy: %d", ret); 1826 + 1827 + atcphy->pipehandler_up = false; 1828 + 1829 + if (atcphy->mode != APPLE_ATCPHY_MODE_OFF) 1830 + atcphy_configure(atcphy, APPLE_ATCPHY_MODE_OFF); 1831 + 1832 + return 0; 1833 + } 1834 + 1835 + static int atcphy_usb3_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1836 + { 1837 + struct apple_atcphy *atcphy = phy_get_drvdata(phy); 1838 + 1839 + guard(mutex)(&atcphy->lock); 1840 + 1841 + /* 1842 + * We may get multiple calls to set_mode (for host mode e.g. at least one from the dwc3 glue 1843 + * driver and then another one from the generic xhci code) but must only configure the 1844 + * PIPE handler once. 1845 + */ 1846 + if (atcphy->pipehandler_up) 1847 + return 0; 1848 + 1849 + switch (mode) { 1850 + case PHY_MODE_USB_HOST: 1851 + return atcphy_configure_pipehandler(atcphy, true); 1852 + case PHY_MODE_USB_DEVICE: 1853 + return atcphy_configure_pipehandler(atcphy, false); 1854 + default: 1855 + return -EINVAL; 1856 + } 1857 + } 1858 + 1859 + static const struct phy_ops apple_atc_usb3_phy_ops = { 1860 + .owner = THIS_MODULE, 1861 + .power_off = atcphy_usb3_power_off, 1862 + .set_mode = atcphy_usb3_set_mode, 1863 + }; 1864 + 1865 + static int atcphy_dpphy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1866 + { 1867 + /* Nothing to do here since the setup already happened in mux_set */ 1868 + if (mode == PHY_MODE_DP && submode == 0) 1869 + return 0; 1870 + return -EINVAL; 1871 + } 1872 + 1873 + static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode, int submode, 1874 + union phy_configure_opts *opts_) 1875 + { 1876 + struct phy_configure_opts_dp *opts = &opts_->dp; 1877 + struct apple_atcphy *atcphy = phy_get_drvdata(phy); 1878 + 1879 + if (mode != PHY_MODE_DP) 1880 + return -EINVAL; 1881 + if (submode != 0) 1882 + return -EINVAL; 1883 + 1884 + switch (atcphy->mode) { 1885 + case APPLE_ATCPHY_MODE_USB3_DP: 1886 + opts->lanes = 2; 1887 + break; 1888 + case APPLE_ATCPHY_MODE_DP: 1889 + opts->lanes = 4; 1890 + break; 1891 + default: 1892 + opts->lanes = 0; 1893 + } 1894 + 1895 + return 0; 1896 + } 1897 + 1898 + static int atcphy_dpphy_configure(struct phy *phy, union phy_configure_opts *opts_) 1899 + { 1900 + struct phy_configure_opts_dp *opts = &opts_->dp; 1901 + struct apple_atcphy *atcphy = phy_get_drvdata(phy); 1902 + enum atcphy_dp_link_rate link_rate; 1903 + 1904 + if (opts->set_voltages) 1905 + return -EINVAL; 1906 + if (opts->set_lanes) 1907 + return -EINVAL; 1908 + 1909 + if (opts->set_rate) { 1910 + switch (opts->link_rate) { 1911 + case 1620: 1912 + link_rate = ATCPHY_DP_LINK_RATE_RBR; 1913 + break; 1914 + case 2700: 1915 + link_rate = ATCPHY_DP_LINK_RATE_HBR; 1916 + break; 1917 + case 5400: 1918 + link_rate = ATCPHY_DP_LINK_RATE_HBR2; 1919 + break; 1920 + case 8100: 1921 + link_rate = ATCPHY_DP_LINK_RATE_HBR3; 1922 + break; 1923 + case 0: 1924 + return 0; 1925 + default: 1926 + dev_err(atcphy->dev, "Unsupported link rate: %d\n", opts->link_rate); 1927 + return -EINVAL; 1928 + } 1929 + 1930 + return atcphy_dp_configure(atcphy, link_rate); 1931 + } 1932 + 1933 + return 0; 1934 + } 1935 + 1936 + static const struct phy_ops apple_atc_dp_phy_ops = { 1937 + .owner = THIS_MODULE, 1938 + .configure = atcphy_dpphy_configure, 1939 + .validate = atcphy_dpphy_validate, 1940 + .set_mode = atcphy_dpphy_set_mode, 1941 + }; 1942 + 1943 + static struct phy *atcphy_xlate(struct device *dev, const struct of_phandle_args *args) 1944 + { 1945 + struct apple_atcphy *atcphy = dev_get_drvdata(dev); 1946 + 1947 + switch (args->args[0]) { 1948 + case PHY_TYPE_USB2: 1949 + return atcphy->phys.usb2; 1950 + case PHY_TYPE_USB3: 1951 + return atcphy->phys.usb3; 1952 + case PHY_TYPE_DP: 1953 + return atcphy->phys.dp; 1954 + } 1955 + return ERR_PTR(-ENODEV); 1956 + } 1957 + 1958 + static int atcphy_probe_phy(struct apple_atcphy *atcphy) 1959 + { 1960 + struct { 1961 + struct phy **phy; 1962 + const struct phy_ops *ops; 1963 + } phys[] = { 1964 + { &atcphy->phys.usb2, &apple_atc_usb2_phy_ops }, 1965 + { &atcphy->phys.usb3, &apple_atc_usb3_phy_ops }, 1966 + { &atcphy->phys.dp, &apple_atc_dp_phy_ops }, 1967 + }; 1968 + 1969 + for (int i = 0; i < ARRAY_SIZE(phys); i++) { 1970 + *phys[i].phy = devm_phy_create(atcphy->dev, NULL, phys[i].ops); 1971 + if (IS_ERR(*phys[i].phy)) 1972 + return PTR_ERR(*phys[i].phy); 1973 + phy_set_drvdata(*phys[i].phy, atcphy); 1974 + } 1975 + 1976 + atcphy->phy_provider = devm_of_phy_provider_register(atcphy->dev, atcphy_xlate); 1977 + if (IS_ERR(atcphy->phy_provider)) 1978 + return PTR_ERR(atcphy->phy_provider); 1979 + return 0; 1980 + } 1981 + 1982 + static void _atcphy_dwc3_reset_assert(struct apple_atcphy *atcphy) 1983 + { 1984 + lockdep_assert_held(&atcphy->lock); 1985 + 1986 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, PIPEHANDLER_AON_GEN_DWC3_RESET_N); 1987 + set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, 1988 + PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN); 1989 + } 1990 + 1991 + static int atcphy_dwc3_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) 1992 + { 1993 + struct apple_atcphy *atcphy = container_of(rcdev, struct apple_atcphy, rcdev); 1994 + int ret; 1995 + 1996 + guard(mutex)(&atcphy->lock); 1997 + 1998 + _atcphy_dwc3_reset_assert(atcphy); 1999 + 2000 + if (atcphy->pipehandler_up) { 2001 + ret = atcphy_configure_pipehandler_dummy(atcphy); 2002 + if (ret) 2003 + dev_warn(atcphy->dev, "Failed to switch PIPE to dummy: %d\n", ret); 2004 + else 2005 + atcphy->pipehandler_up = false; 2006 + } 2007 + 2008 + atcphy_usb2_power_off(atcphy); 2009 + 2010 + return 0; 2011 + } 2012 + 2013 + static int atcphy_dwc3_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) 2014 + { 2015 + struct apple_atcphy *atcphy = container_of(rcdev, struct apple_atcphy, rcdev); 2016 + 2017 + guard(mutex)(&atcphy->lock); 2018 + 2019 + clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, 2020 + PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN); 2021 + set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, PIPEHANDLER_AON_GEN_DWC3_RESET_N); 2022 + 2023 + return 0; 2024 + } 2025 + 2026 + const struct reset_control_ops atcphy_dwc3_reset_ops = { 2027 + .assert = atcphy_dwc3_reset_assert, 2028 + .deassert = atcphy_dwc3_reset_deassert, 2029 + }; 2030 + 2031 + static int atcphy_reset_xlate(struct reset_controller_dev *rcdev, 2032 + const struct of_phandle_args *reset_spec) 2033 + { 2034 + return 0; 2035 + } 2036 + 2037 + static int atcphy_probe_rcdev(struct apple_atcphy *atcphy) 2038 + { 2039 + atcphy->rcdev.owner = THIS_MODULE; 2040 + atcphy->rcdev.nr_resets = 1; 2041 + atcphy->rcdev.ops = &atcphy_dwc3_reset_ops; 2042 + atcphy->rcdev.of_node = atcphy->dev->of_node; 2043 + atcphy->rcdev.of_reset_n_cells = 0; 2044 + atcphy->rcdev.of_xlate = atcphy_reset_xlate; 2045 + 2046 + return devm_reset_controller_register(atcphy->dev, &atcphy->rcdev); 2047 + } 2048 + 2049 + static int atcphy_sw_set(struct typec_switch_dev *sw, enum typec_orientation orientation) 2050 + { 2051 + struct apple_atcphy *atcphy = typec_switch_get_drvdata(sw); 2052 + 2053 + guard(mutex)(&atcphy->lock); 2054 + 2055 + switch (orientation) { 2056 + case TYPEC_ORIENTATION_NONE: 2057 + break; 2058 + case TYPEC_ORIENTATION_NORMAL: 2059 + atcphy->swap_lanes = false; 2060 + break; 2061 + case TYPEC_ORIENTATION_REVERSE: 2062 + atcphy->swap_lanes = true; 2063 + break; 2064 + } 2065 + 2066 + return 0; 2067 + } 2068 + 2069 + static int atcphy_probe_switch(struct apple_atcphy *atcphy) 2070 + { 2071 + struct typec_switch_desc sw_desc = { 2072 + .drvdata = atcphy, 2073 + .fwnode = atcphy->dev->fwnode, 2074 + .set = atcphy_sw_set, 2075 + }; 2076 + 2077 + return PTR_ERR_OR_ZERO(typec_switch_register(atcphy->dev, &sw_desc)); 2078 + } 2079 + 2080 + static int atcphy_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) 2081 + { 2082 + struct apple_atcphy *atcphy = typec_mux_get_drvdata(mux); 2083 + enum atcphy_mode target_mode; 2084 + 2085 + guard(mutex)(&atcphy->lock); 2086 + 2087 + if (state->mode == TYPEC_STATE_SAFE) { 2088 + target_mode = APPLE_ATCPHY_MODE_OFF; 2089 + } else if (state->mode == TYPEC_STATE_USB) { 2090 + target_mode = APPLE_ATCPHY_MODE_USB3; 2091 + } else if (!state->alt && state->mode == TYPEC_MODE_USB4) { 2092 + struct enter_usb_data *data = state->data; 2093 + u32 eudo_usb_mode = FIELD_GET(EUDO_USB_MODE_MASK, data->eudo); 2094 + 2095 + switch (eudo_usb_mode) { 2096 + case EUDO_USB_MODE_USB2: 2097 + target_mode = APPLE_ATCPHY_MODE_USB2; 2098 + break; 2099 + case EUDO_USB_MODE_USB3: 2100 + target_mode = APPLE_ATCPHY_MODE_USB3; 2101 + break; 2102 + case EUDO_USB_MODE_USB4: 2103 + target_mode = APPLE_ATCPHY_MODE_USB4; 2104 + break; 2105 + default: 2106 + dev_warn(atcphy->dev, "Unsupported EUDO USB mode: 0x%x.\n", eudo_usb_mode); 2107 + target_mode = APPLE_ATCPHY_MODE_OFF; 2108 + } 2109 + } else if (state->alt && state->alt->svid == USB_TYPEC_TBT_SID) { 2110 + target_mode = APPLE_ATCPHY_MODE_TBT; 2111 + } else if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) { 2112 + switch (state->mode) { 2113 + case TYPEC_DP_STATE_C: 2114 + case TYPEC_DP_STATE_E: 2115 + target_mode = APPLE_ATCPHY_MODE_DP; 2116 + break; 2117 + case TYPEC_DP_STATE_D: 2118 + target_mode = APPLE_ATCPHY_MODE_USB3_DP; 2119 + break; 2120 + default: 2121 + dev_err(atcphy->dev, 2122 + "Unsupported DP pin assignment: 0x%lx, your connected device will not work.\n", 2123 + state->mode); 2124 + target_mode = APPLE_ATCPHY_MODE_OFF; 2125 + } 2126 + } else if (state->alt) { 2127 + dev_err(atcphy->dev, 2128 + "Unknown alternate mode SVID: 0x%x, your connected device will not work.\n", 2129 + state->alt->svid); 2130 + target_mode = APPLE_ATCPHY_MODE_OFF; 2131 + } else { 2132 + dev_err(atcphy->dev, "Unknown mode: 0x%lx, your connected device will not work.\n", 2133 + state->mode); 2134 + target_mode = APPLE_ATCPHY_MODE_OFF; 2135 + } 2136 + 2137 + if (atcphy->mode == target_mode) 2138 + return 0; 2139 + 2140 + /* 2141 + * If the pipehandler is still/already up here there's a bug somewhere so make sure to 2142 + * complain loudly. We can still try to switch modes and hope for the best though, 2143 + * in the worst case the hardware will fall back to USB2-only. 2144 + */ 2145 + WARN_ON_ONCE(atcphy->pipehandler_up); 2146 + return atcphy_configure(atcphy, target_mode); 2147 + } 2148 + 2149 + static int atcphy_probe_mux(struct apple_atcphy *atcphy) 2150 + { 2151 + struct typec_mux_desc mux_desc = { 2152 + .drvdata = atcphy, 2153 + .fwnode = atcphy->dev->fwnode, 2154 + .set = atcphy_mux_set, 2155 + }; 2156 + 2157 + return PTR_ERR_OR_ZERO(typec_mux_register(atcphy->dev, &mux_desc)); 2158 + } 2159 + 2160 + static int atcphy_load_tunables(struct apple_atcphy *atcphy) 2161 + { 2162 + struct { 2163 + const char *dt_name; 2164 + struct apple_tunable **tunable; 2165 + struct resource *res; 2166 + } tunables[] = { 2167 + { "apple,tunable-axi2af", &atcphy->tunables.axi2af, atcphy->res.axi2af }, 2168 + { "apple,tunable-common-a", &atcphy->tunables.common[0], atcphy->res.core }, 2169 + { "apple,tunable-common-b", &atcphy->tunables.common[1], atcphy->res.core }, 2170 + { "apple,tunable-lane0-usb", &atcphy->tunables.lane_usb3[0], atcphy->res.core }, 2171 + { "apple,tunable-lane1-usb", &atcphy->tunables.lane_usb3[1], atcphy->res.core }, 2172 + { "apple,tunable-lane0-cio", &atcphy->tunables.lane_usb4[0], atcphy->res.core }, 2173 + { "apple,tunable-lane1-cio", &atcphy->tunables.lane_usb4[1], atcphy->res.core }, 2174 + { "apple,tunable-lane0-dp", &atcphy->tunables.lane_dp[0], atcphy->res.core }, 2175 + { "apple,tunable-lane1-dp", &atcphy->tunables.lane_dp[1], atcphy->res.core }, 2176 + }; 2177 + 2178 + for (int i = 0; i < ARRAY_SIZE(tunables); i++) { 2179 + *tunables[i].tunable = devm_apple_tunable_parse( 2180 + atcphy->dev, atcphy->np, tunables[i].dt_name, tunables[i].res); 2181 + if (IS_ERR(*tunables[i].tunable)) { 2182 + dev_err(atcphy->dev, "Failed to read tunable %s: %ld\n", 2183 + tunables[i].dt_name, PTR_ERR(*tunables[i].tunable)); 2184 + return PTR_ERR(*tunables[i].tunable); 2185 + } 2186 + } 2187 + 2188 + return 0; 2189 + } 2190 + 2191 + static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy) 2192 + { 2193 + struct { 2194 + const char *name; 2195 + void __iomem **addr; 2196 + struct resource **res; 2197 + } resources[] = { 2198 + { "core", &atcphy->regs.core, &atcphy->res.core }, 2199 + { "lpdptx", &atcphy->regs.lpdptx, NULL }, 2200 + { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af }, 2201 + { "usb2phy", &atcphy->regs.usb2phy, NULL }, 2202 + { "pipehandler", &atcphy->regs.pipehandler, NULL }, 2203 + }; 2204 + struct resource *res; 2205 + 2206 + for (int i = 0; i < ARRAY_SIZE(resources); i++) { 2207 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name); 2208 + *resources[i].addr = devm_ioremap_resource(&pdev->dev, res); 2209 + if (IS_ERR(resources[i].addr)) 2210 + return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr), 2211 + "Unable to map %s regs", resources[i].name); 2212 + 2213 + if (resources[i].res) 2214 + *resources[i].res = res; 2215 + } 2216 + 2217 + return 0; 2218 + } 2219 + 2220 + static int atcphy_probe_finalize(struct apple_atcphy *atcphy) 2221 + { 2222 + int ret; 2223 + 2224 + guard(mutex)(&atcphy->lock); 2225 + 2226 + /* Reset dwc3 on probe, let dwc3 (consumer) deassert it */ 2227 + _atcphy_dwc3_reset_assert(atcphy); 2228 + 2229 + /* Reset atcphy to clear any state potentially left by the bootloader */ 2230 + atcphy_usb2_power_off(atcphy); 2231 + atcphy_power_off(atcphy); 2232 + atcphy_setup_pipehandler(atcphy); 2233 + 2234 + ret = atcphy_probe_rcdev(atcphy); 2235 + if (ret) 2236 + return dev_err_probe(atcphy->dev, ret, "Probing rcdev failed"); 2237 + ret = atcphy_probe_mux(atcphy); 2238 + if (ret) 2239 + return dev_err_probe(atcphy->dev, ret, "Probing mux failed"); 2240 + ret = atcphy_probe_switch(atcphy); 2241 + if (ret) 2242 + return dev_err_probe(atcphy->dev, ret, "Probing switch failed"); 2243 + ret = atcphy_probe_phy(atcphy); 2244 + if (ret) 2245 + return dev_err_probe(atcphy->dev, ret, "Probing phy failed"); 2246 + 2247 + return 0; 2248 + } 2249 + 2250 + static int atcphy_probe(struct platform_device *pdev) 2251 + { 2252 + struct apple_atcphy *atcphy; 2253 + struct device *dev = &pdev->dev; 2254 + int ret; 2255 + 2256 + atcphy = devm_kzalloc(&pdev->dev, sizeof(*atcphy), GFP_KERNEL); 2257 + if (!atcphy) 2258 + return -ENOMEM; 2259 + 2260 + atcphy->dev = dev; 2261 + atcphy->np = dev->of_node; 2262 + mutex_init(&atcphy->lock); 2263 + platform_set_drvdata(pdev, atcphy); 2264 + 2265 + ret = atcphy_map_resources(pdev, atcphy); 2266 + if (ret) 2267 + return ret; 2268 + ret = atcphy_load_tunables(atcphy); 2269 + if (ret) 2270 + return ret; 2271 + 2272 + atcphy->mode = APPLE_ATCPHY_MODE_OFF; 2273 + atcphy->pipehandler_up = false; 2274 + 2275 + return atcphy_probe_finalize(atcphy); 2276 + } 2277 + 2278 + static const struct of_device_id atcphy_match[] = { 2279 + { .compatible = "apple,t8103-atcphy" }, 2280 + {}, 2281 + }; 2282 + MODULE_DEVICE_TABLE(of, atcphy_match); 2283 + 2284 + static struct platform_driver atcphy_driver = { 2285 + .driver = { 2286 + .name = "phy-apple-atc", 2287 + .of_match_table = atcphy_match, 2288 + }, 2289 + .probe = atcphy_probe, 2290 + }; 2291 + module_platform_driver(atcphy_driver); 2292 + 2293 + MODULE_AUTHOR("Sven Peter <sven@kernel.org>"); 2294 + MODULE_DESCRIPTION("Apple Type-C PHY driver"); 2295 + MODULE_LICENSE("GPL");
+159 -7
drivers/phy/cadence/phy-cadence-torrent.c
··· 300 300 TYPE_USB, 301 301 TYPE_USXGMII, 302 302 TYPE_PCIE_ML, 303 + TYPE_XAUI, 303 304 }; 304 305 305 306 enum cdns_torrent_ref_clk { ··· 321 320 /* Unique key id for vals table entry 322 321 * REFCLK0_RATE | REFCLK1_RATE | LINK0_TYPE | LINK1_TYPE | SSC_TYPE 323 322 */ 324 - #define REFCLK0_SHIFT 12 325 - #define REFCLK0_MASK GENMASK(14, 12) 326 - #define REFCLK1_SHIFT 9 327 - #define REFCLK1_MASK GENMASK(11, 9) 328 - #define LINK0_SHIFT 6 329 - #define LINK0_MASK GENMASK(8, 6) 323 + #define REFCLK0_SHIFT 15 324 + #define REFCLK0_MASK GENMASK(18, 15) 325 + #define REFCLK1_SHIFT 11 326 + #define REFCLK1_MASK GENMASK(14, 11) 327 + #define LINK0_SHIFT 7 328 + #define LINK0_MASK GENMASK(10, 7) 330 329 #define LINK1_SHIFT 3 331 - #define LINK1_MASK GENMASK(5, 3) 330 + #define LINK1_MASK GENMASK(6, 3) 332 331 #define SSC_SHIFT 0 333 332 #define SSC_MASK GENMASK(2, 0) 334 333 ··· 398 397 struct clk_hw hw; 399 398 struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG]; 400 399 struct clk_init_data clk_data; 400 + u8 parent_index; 401 401 }; 402 402 403 403 #define to_cdns_torrent_refclk_driver(_hw) \ ··· 710 708 return "USB"; 711 709 case TYPE_USXGMII: 712 710 return "USXGMII"; 711 + case TYPE_XAUI: 712 + return "XAUI"; 713 713 default: 714 714 return "None"; 715 715 } ··· 3024 3020 case PHY_TYPE_USXGMII: 3025 3021 cdns_phy->phys[node].phy_type = TYPE_USXGMII; 3026 3022 break; 3023 + case PHY_TYPE_XAUI: 3024 + cdns_phy->phys[node].phy_type = TYPE_XAUI; 3025 + break; 3027 3026 default: 3028 3027 dev_err(dev, "Unsupported protocol\n"); 3029 3028 ret = -EINVAL; ··· 3333 3326 .num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs), 3334 3327 }; 3335 3328 3329 + static void cdns_torrent_refclk_driver_suspend(struct cdns_torrent_phy *cdns_phy) 3330 + { 3331 + struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER]; 3332 + struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw); 3333 + 3334 + refclk_driver->parent_index = cdns_torrent_refclk_driver_get_parent(hw); 3335 + } 3336 + 3337 + static int cdns_torrent_refclk_driver_resume(struct cdns_torrent_phy *cdns_phy) 3338 + { 3339 + struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER]; 3340 + struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw); 3341 + 3342 + return cdns_torrent_refclk_driver_set_parent(hw, refclk_driver->parent_index); 3343 + } 3344 + 3336 3345 static int cdns_torrent_phy_suspend_noirq(struct device *dev) 3337 3346 { 3338 3347 struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev); 3339 3348 int i; 3349 + 3350 + cdns_torrent_refclk_driver_suspend(cdns_phy); 3340 3351 3341 3352 reset_control_assert(cdns_phy->phy_rst); 3342 3353 reset_control_assert(cdns_phy->apb_rst); ··· 3376 3351 struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev); 3377 3352 int node = cdns_phy->nsubnodes; 3378 3353 int ret, i; 3354 + 3355 + ret = cdns_torrent_refclk_driver_resume(cdns_phy); 3356 + if (ret) 3357 + return ret; 3379 3358 3380 3359 ret = cdns_torrent_clk(cdns_phy); 3381 3360 if (ret) ··· 3410 3381 static DEFINE_NOIRQ_DEV_PM_OPS(cdns_torrent_phy_pm_ops, 3411 3382 cdns_torrent_phy_suspend_noirq, 3412 3383 cdns_torrent_phy_resume_noirq); 3384 + 3385 + /* PCIe and XAUI link configuration */ 3386 + static const struct cdns_reg_pairs pcie_xaui_link_cmn_regs[] = { 3387 + {0x0003, PHY_PLL_CFG}, 3388 + {0x0600, CMN_PDIAG_PLL1_CLK_SEL_M0} 3389 + }; 3390 + 3391 + static const struct cdns_reg_pairs xaui_pcie_xcvr_diag_ln_regs[] = { 3392 + {0x0011, XCVR_DIAG_HSCLK_SEL}, 3393 + {0x0089, XCVR_DIAG_PLLDRC_CTRL} 3394 + }; 3395 + 3396 + static const struct cdns_torrent_vals pcie_xaui_link_cmn_vals = { 3397 + .reg_pairs = pcie_xaui_link_cmn_regs, 3398 + .num_regs = ARRAY_SIZE(pcie_xaui_link_cmn_regs), 3399 + }; 3400 + 3401 + static const struct cdns_torrent_vals xaui_pcie_xcvr_diag_ln_vals = { 3402 + .reg_pairs = xaui_pcie_xcvr_diag_ln_regs, 3403 + .num_regs = ARRAY_SIZE(xaui_pcie_xcvr_diag_ln_regs), 3404 + }; 3405 + 3406 + /* XAUI 100 MHz Ref clk, no SSC */ 3407 + static const struct cdns_reg_pairs xaui_100_no_ssc_cmn_regs[] = { 3408 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 3409 + {0x0B17, CMN_PDIAG_PLL1_CP_PADJ_M0}, 3410 + {0x0E01, CMN_PDIAG_PLL1_CP_IADJ_M0}, 3411 + {0x0D05, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 3412 + {0x003E, CMN_PLL1_INTDIV_M0}, 3413 + {0x8000, CMN_PLL1_FRACDIVL_M0}, 3414 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 3415 + {0x002A, CMN_PLL1_HIGH_THR_M0}, 3416 + {0x3102, CMN_PDIAG_PLL1_CTRL_M0}, 3417 + {0x007F, CMN_TXPUCAL_TUNE}, 3418 + {0x007F, CMN_TXPDCAL_TUNE} 3419 + }; 3420 + 3421 + static const struct cdns_reg_pairs xaui_100_no_ssc_tx_ln_regs[] = { 3422 + {0x00F3, TX_PSC_A0}, 3423 + {0x04A2, TX_PSC_A2}, 3424 + {0x04A2, TX_PSC_A3 }, 3425 + {0x0000, TX_TXCC_CPOST_MULT_00} 3426 + }; 3427 + 3428 + static const struct cdns_reg_pairs ti_xaui_100_no_ssc_tx_ln_regs[] = { 3429 + {0x00F3, TX_PSC_A0}, 3430 + {0x04A2, TX_PSC_A2}, 3431 + {0x04A2, TX_PSC_A3 }, 3432 + {0x0000, TX_TXCC_CPOST_MULT_00}, 3433 + {0x4000, XCVR_DIAG_RXCLK_CTRL} 3434 + }; 3435 + 3436 + static const struct cdns_reg_pairs xaui_100_no_ssc_rx_ln_regs[] = { 3437 + {0x091D, RX_PSC_A0}, 3438 + {0x0900, RX_PSC_A2}, 3439 + {0x0100, RX_PSC_A3}, 3440 + {0x03C7, RX_REE_GCSM1_EQENM_PH1}, 3441 + {0x01C7, RX_REE_GCSM1_EQENM_PH2}, 3442 + {0x0000, RX_DIAG_DFE_CTRL}, 3443 + {0x0019, RX_REE_TAP1_CLIP}, 3444 + {0x0019, RX_REE_TAP2TON_CLIP}, 3445 + {0x0098, RX_DIAG_NQST_CTRL}, 3446 + {0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, 3447 + {0x0000, RX_DIAG_DFE_AMP_TUNE_3}, 3448 + {0x0000, RX_DIAG_PI_CAP}, 3449 + {0x0031, RX_DIAG_PI_RATE}, 3450 + {0x0001, RX_DIAG_ACYA}, 3451 + {0x018C, RX_CDRLF_CNFG}, 3452 + }; 3453 + 3454 + static const struct cdns_torrent_vals xaui_100_no_ssc_cmn_vals = { 3455 + .reg_pairs = xaui_100_no_ssc_cmn_regs, 3456 + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_cmn_regs), 3457 + }; 3458 + 3459 + static const struct cdns_torrent_vals xaui_100_no_ssc_tx_ln_vals = { 3460 + .reg_pairs = xaui_100_no_ssc_tx_ln_regs, 3461 + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_tx_ln_regs), 3462 + }; 3463 + 3464 + static const struct cdns_torrent_vals ti_xaui_100_no_ssc_tx_ln_vals = { 3465 + .reg_pairs = ti_xaui_100_no_ssc_tx_ln_regs, 3466 + .num_regs = ARRAY_SIZE(ti_xaui_100_no_ssc_tx_ln_regs), 3467 + }; 3468 + 3469 + static const struct cdns_torrent_vals xaui_100_no_ssc_rx_ln_vals = { 3470 + .reg_pairs = xaui_100_no_ssc_rx_ln_regs, 3471 + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_rx_ln_regs), 3472 + }; 3413 3473 3414 3474 /* USB and DP link configuration */ 3415 3475 static const struct cdns_reg_pairs usb_dp_link_cmn_regs[] = { ··· 4971 4853 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals}, 4972 4854 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals}, 4973 4855 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals}, 4856 + {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), &pcie_xaui_link_cmn_vals}, 4974 4857 4975 4858 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_link_cmn_vals}, 4976 4859 ··· 4998 4879 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &pcie_usxgmii_link_cmn_vals}, 4999 4880 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_link_cmn_vals}, 5000 4881 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_link_cmn_vals}, 4882 + 4883 + {CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &pcie_xaui_link_cmn_vals}, 5001 4884 }; 5002 4885 5003 4886 static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = { ··· 5014 4893 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals}, 5015 4894 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals}, 5016 4895 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals}, 4896 + {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), NULL}, 5017 4897 5018 4898 {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_xcvr_diag_ln_vals}, 5019 4899 ··· 5041 4919 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &usxgmii_pcie_xcvr_diag_ln_vals}, 5042 4920 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_xcvr_diag_ln_vals}, 5043 4921 {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_xcvr_diag_ln_vals}, 4922 + 4923 + {CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &xaui_pcie_xcvr_diag_ln_vals}, 5044 4924 }; 5045 4925 5046 4926 static const struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = { ··· 5083 4959 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_int_ssc_cmn_vals}, 5084 4960 5085 4961 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, 4962 + 4963 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, 5086 4964 5087 4965 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals}, 5088 4966 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals}, ··· 5136 5010 5137 5011 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals}, 5138 5012 5013 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals}, 5014 + 5139 5015 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, 5140 5016 5141 5017 /* Dual refclk */ ··· 5181 5053 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), NULL}, 5182 5054 5183 5055 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, 5056 + 5057 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, 5184 5058 5185 5059 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, 5186 5060 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, ··· 5234 5104 5235 5105 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, 5236 5106 5107 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_tx_ln_vals}, 5108 + 5237 5109 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, 5238 5110 5239 5111 /* Dual refclk */ ··· 5279 5147 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5280 5148 5281 5149 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5150 + 5151 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, 5282 5152 5283 5153 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, 5284 5154 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, ··· 5331 5197 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, 5332 5198 5333 5199 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, 5200 + 5201 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals}, 5334 5202 5335 5203 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, 5336 5204 ··· 5414 5278 5415 5279 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, 5416 5280 5281 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, 5282 + 5417 5283 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, 5418 5284 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, 5419 5285 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL}, ··· 5465 5327 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_tx_ln_vals}, 5466 5328 5467 5329 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, 5330 + 5331 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals}, 5468 5332 5469 5333 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, 5470 5334 ··· 5546 5406 5547 5407 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, 5548 5408 5409 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, 5410 + 5549 5411 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals}, 5550 5412 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals}, 5551 5413 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals}, ··· 5598 5456 5599 5457 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals}, 5600 5458 5459 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals}, 5460 + 5601 5461 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, 5602 5462 5603 5463 /* Dual refclk */ ··· 5643 5499 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), NULL}, 5644 5500 5645 5501 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, 5502 + 5503 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, 5646 5504 5647 5505 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, 5648 5506 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, ··· 5696 5550 5697 5551 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, 5698 5552 5553 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals}, 5554 + 5699 5555 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, 5700 5556 5701 5557 /* Dual refclk */ ··· 5741 5593 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5742 5594 5743 5595 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5596 + 5597 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5744 5598 5745 5599 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, 5746 5600 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, ··· 5793 5643 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_QSGMII, INTERNAL_SSC), &usb_100_no_ssc_rx_ln_vals}, 5794 5644 5795 5645 {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, 5646 + 5647 + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals}, 5796 5648 5797 5649 {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, 5798 5650
+24 -1
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
··· 17 17 #define PHY_CTRL0_FSEL_MASK GENMASK(10, 5) 18 18 #define PHY_CTRL0_FSEL_24M 0x2a 19 19 #define PHY_CTRL0_FSEL_100M 0x27 20 + #define PHY_CTRL0_SSC_RANGE_MASK GENMASK(23, 21) 21 + #define PHY_CTRL0_SSC_RANGE_4003PPM 0x2 22 + #define PHY_CTRL0_SSC_RANGE_4492PPM 0x1 23 + #define PHY_CTRL0_SSC_RANGE_4980PPM 0x0 20 24 21 25 #define PHY_CTRL1 0x4 22 26 #define PHY_CTRL1_RESET BIT(0) ··· 51 47 #define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0) 52 48 53 49 #define PHY_CTRL6 0x18 50 + #define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29) 54 51 #define PHY_CTRL6_ALT_CLK_EN BIT(1) 55 52 #define PHY_CTRL6_ALT_CLK_SEL BIT(0) 56 53 ··· 592 587 593 588 value = readl(imx_phy->base + PHY_CTRL0); 594 589 value |= PHY_CTRL0_REF_SSP_EN; 590 + value &= ~PHY_CTRL0_SSC_RANGE_MASK; 591 + value |= FIELD_PREP(PHY_CTRL0_SSC_RANGE_MASK, 592 + PHY_CTRL0_SSC_RANGE_4003PPM); 595 593 writel(value, imx_phy->base + PHY_CTRL0); 596 594 597 595 value = readl(imx_phy->base + PHY_CTRL2); ··· 618 610 static int imx8mq_phy_power_on(struct phy *phy) 619 611 { 620 612 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 613 + u32 value; 621 614 int ret; 622 615 623 616 ret = regulator_enable(imx_phy->vbus); ··· 635 626 return ret; 636 627 } 637 628 638 - return ret; 629 + /* Disable rx term override */ 630 + value = readl(imx_phy->base + PHY_CTRL6); 631 + value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL; 632 + writel(value, imx_phy->base + PHY_CTRL6); 633 + 634 + return 0; 639 635 } 640 636 641 637 static int imx8mq_phy_power_off(struct phy *phy) 642 638 { 643 639 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 640 + u32 value; 641 + 642 + /* Override rx term to be 0 */ 643 + value = readl(imx_phy->base + PHY_CTRL6); 644 + value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL; 645 + writel(value, imx_phy->base + PHY_CTRL6); 644 646 645 647 clk_disable_unprepare(imx_phy->alt_clk); 646 648 clk_disable_unprepare(imx_phy->clk); ··· 695 675 imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL); 696 676 if (!imx_phy) 697 677 return -ENOMEM; 678 + 679 + platform_set_drvdata(pdev, imx_phy); 698 680 699 681 imx_phy->clk = devm_clk_get(dev, "phy"); 700 682 if (IS_ERR(imx_phy->clk)) { ··· 752 730 .driver = { 753 731 .name = "imx8mq-usb-phy", 754 732 .of_match_table = imx8mq_usb_phy_of_match, 733 + .suppress_bind_attrs = true, 755 734 } 756 735 }; 757 736 module_platform_driver(imx8mq_usb_phy_driver);
+1 -1
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
··· 251 251 struct imx_hsio_lane *lane = phy_get_drvdata(phy); 252 252 struct imx_hsio_priv *priv = lane->priv; 253 253 254 - if (strncmp(priv->refclk_pad, "output", 6) == 0) { 254 + if (priv->refclk_pad && strncmp(priv->refclk_pad, "output", 6) == 0) { 255 255 pll = true; 256 256 regmap_update_bits(priv->misc, HSIO_CTRL0, 257 257 HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,
+2 -4
drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
··· 286 286 287 287 regmap_write(priv->regmap, PHY_CTRL, CTRL_RESET_VAL); 288 288 289 - ret = pm_runtime_put(dev); 290 - if (ret < 0) 291 - dev_err(dev, "failed to put PM runtime: %d\n", ret); 289 + pm_runtime_put(dev); 292 290 293 - return ret; 291 + return 0; 294 292 } 295 293 296 294 static struct phy *mixel_lvds_phy_xlate(struct device *dev,
+870 -276
drivers/phy/freescale/phy-fsl-lynx-28g.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0+ 2 2 /* Copyright (c) 2021-2022 NXP. */ 3 3 4 + #include <linux/bitfield.h> 4 5 #include <linux/module.h> 5 6 #include <linux/of.h> 6 7 #include <linux/phy.h> ··· 12 11 #define LYNX_28G_NUM_LANE 8 13 12 #define LYNX_28G_NUM_PLL 2 14 13 15 - /* General registers per SerDes block */ 16 - #define LYNX_28G_PCC8 0x10a0 17 - #define LYNX_28G_PCC8_SGMII 0x1 18 - #define LYNX_28G_PCC8_SGMII_DIS 0x0 14 + /* SoC IP wrapper for protocol converters */ 15 + #define PCC8 0x10a0 16 + #define PCC8_SGMIIa_KX BIT(3) 17 + #define PCC8_SGMIIa_CFG BIT(0) 19 18 20 - #define LYNX_28G_PCCC 0x10b0 21 - #define LYNX_28G_PCCC_10GBASER 0x9 22 - #define LYNX_28G_PCCC_USXGMII 0x1 23 - #define LYNX_28G_PCCC_SXGMII_DIS 0x0 19 + #define PCCC 0x10b0 20 + #define PCCC_SXGMIIn_XFI BIT(3) 21 + #define PCCC_SXGMIIn_CFG BIT(0) 24 22 25 - #define LYNX_28G_LNa_PCC_OFFSET(lane) (4 * (LYNX_28G_NUM_LANE - (lane->id) - 1)) 23 + #define PCCD 0x10b4 24 + #define PCCD_E25Gn_CFG BIT(0) 25 + 26 + #define PCCE 0x10b8 27 + #define PCCE_E40Gn_LRV BIT(3) 28 + #define PCCE_E40Gn_CFG BIT(0) 29 + #define PCCE_E50Gn_LRV BIT(3) 30 + #define PCCE_E50GnCFG BIT(0) 31 + #define PCCE_E100Gn_LRV BIT(3) 32 + #define PCCE_E100Gn_CFG BIT(0) 33 + 34 + #define SGMII_CFG(id) (28 - (id) * 4) /* Offset into PCC8 */ 35 + #define SXGMII_CFG(id) (28 - (id) * 4) /* Offset into PCCC */ 36 + #define E25G_CFG(id) (28 - (id) * 4) /* Offset into PCCD */ 37 + #define E40G_CFG(id) (28 - (id) * 4) /* Offset into PCCE */ 38 + #define E50G_CFG(id) (20 - (id) * 4) /* Offset into PCCE */ 39 + #define E100G_CFG(id) (12 - (id) * 4) /* Offset into PCCE */ 26 40 27 41 /* Per PLL registers */ 28 - #define LYNX_28G_PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0) 29 - #define LYNX_28G_PLLnRSTCTL_DIS(rstctl) (((rstctl) & BIT(24)) >> 24) 30 - #define LYNX_28G_PLLnRSTCTL_LOCK(rstctl) (((rstctl) & BIT(23)) >> 23) 42 + #define PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0) 43 + #define PLLnRSTCTL_DIS(rstctl) (((rstctl) & BIT(24)) >> 24) 44 + #define PLLnRSTCTL_LOCK(rstctl) (((rstctl) & BIT(23)) >> 23) 31 45 32 - #define LYNX_28G_PLLnCR0(pll) (0x400 + (pll) * 0x100 + 0x4) 33 - #define LYNX_28G_PLLnCR0_REFCLK_SEL(cr0) (((cr0) & GENMASK(20, 16))) 34 - #define LYNX_28G_PLLnCR0_REFCLK_SEL_100MHZ 0x0 35 - #define LYNX_28G_PLLnCR0_REFCLK_SEL_125MHZ 0x10000 36 - #define LYNX_28G_PLLnCR0_REFCLK_SEL_156MHZ 0x20000 37 - #define LYNX_28G_PLLnCR0_REFCLK_SEL_150MHZ 0x30000 38 - #define LYNX_28G_PLLnCR0_REFCLK_SEL_161MHZ 0x40000 46 + #define PLLnCR0(pll) (0x400 + (pll) * 0x100 + 0x4) 47 + #define PLLnCR0_REFCLK_SEL GENMASK(20, 16) 48 + #define PLLnCR0_REFCLK_SEL_100MHZ 0x0 49 + #define PLLnCR0_REFCLK_SEL_125MHZ 0x1 50 + #define PLLnCR0_REFCLK_SEL_156MHZ 0x2 51 + #define PLLnCR0_REFCLK_SEL_150MHZ 0x3 52 + #define PLLnCR0_REFCLK_SEL_161MHZ 0x4 39 53 40 - #define LYNX_28G_PLLnCR1(pll) (0x400 + (pll) * 0x100 + 0x8) 41 - #define LYNX_28G_PLLnCR1_FRATE_SEL(cr1) (((cr1) & GENMASK(28, 24))) 42 - #define LYNX_28G_PLLnCR1_FRATE_5G_10GVCO 0x0 43 - #define LYNX_28G_PLLnCR1_FRATE_5G_25GVCO 0x10000000 44 - #define LYNX_28G_PLLnCR1_FRATE_10G_20GVCO 0x6000000 54 + #define PLLnCR1(pll) (0x400 + (pll) * 0x100 + 0x8) 55 + #define PLLnCR1_FRATE_SEL GENMASK(28, 24) 56 + #define PLLnCR1_FRATE_5G_10GVCO 0x0 57 + #define PLLnCR1_FRATE_5G_25GVCO 0x10 58 + #define PLLnCR1_FRATE_10G_20GVCO 0x6 45 59 46 60 /* Per SerDes lane registers */ 47 61 /* Lane a General Control Register */ 48 - #define LYNX_28G_LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0) 49 - #define LYNX_28G_LNaGCR0_PROTO_SEL_MSK GENMASK(7, 3) 50 - #define LYNX_28G_LNaGCR0_PROTO_SEL_SGMII 0x8 51 - #define LYNX_28G_LNaGCR0_PROTO_SEL_XFI 0x50 52 - #define LYNX_28G_LNaGCR0_IF_WIDTH_MSK GENMASK(2, 0) 53 - #define LYNX_28G_LNaGCR0_IF_WIDTH_10_BIT 0x0 54 - #define LYNX_28G_LNaGCR0_IF_WIDTH_20_BIT 0x2 62 + #define LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0) 63 + #define LNaGCR0_PROTO_SEL GENMASK(7, 3) 64 + #define LNaGCR0_PROTO_SEL_SGMII 0x1 65 + #define LNaGCR0_PROTO_SEL_XFI 0xa 66 + #define LNaGCR0_IF_WIDTH GENMASK(2, 0) 67 + #define LNaGCR0_IF_WIDTH_10_BIT 0x0 68 + #define LNaGCR0_IF_WIDTH_20_BIT 0x2 55 69 56 70 /* Lane a Tx Reset Control Register */ 57 - #define LYNX_28G_LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20) 58 - #define LYNX_28G_LNaTRSTCTL_HLT_REQ BIT(27) 59 - #define LYNX_28G_LNaTRSTCTL_RST_DONE BIT(30) 60 - #define LYNX_28G_LNaTRSTCTL_RST_REQ BIT(31) 71 + #define LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20) 72 + #define LNaTRSTCTL_HLT_REQ BIT(27) 73 + #define LNaTRSTCTL_RST_DONE BIT(30) 74 + #define LNaTRSTCTL_RST_REQ BIT(31) 61 75 62 76 /* Lane a Tx General Control Register */ 63 - #define LYNX_28G_LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24) 64 - #define LYNX_28G_LNaTGCR0_USE_PLLF 0x0 65 - #define LYNX_28G_LNaTGCR0_USE_PLLS BIT(28) 66 - #define LYNX_28G_LNaTGCR0_USE_PLL_MSK BIT(28) 67 - #define LYNX_28G_LNaTGCR0_N_RATE_FULL 0x0 68 - #define LYNX_28G_LNaTGCR0_N_RATE_HALF 0x1000000 69 - #define LYNX_28G_LNaTGCR0_N_RATE_QUARTER 0x2000000 70 - #define LYNX_28G_LNaTGCR0_N_RATE_MSK GENMASK(26, 24) 77 + #define LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24) 78 + #define LNaTGCR0_USE_PLL BIT(28) 79 + #define LNaTGCR0_USE_PLLF 0x0 80 + #define LNaTGCR0_USE_PLLS 0x1 81 + #define LNaTGCR0_N_RATE GENMASK(26, 24) 82 + #define LNaTGCR0_N_RATE_FULL 0x0 83 + #define LNaTGCR0_N_RATE_HALF 0x1 84 + #define LNaTGCR0_N_RATE_QUARTER 0x2 71 85 72 - #define LYNX_28G_LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30) 86 + #define LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30) 87 + #define LNaTECR0_EQ_TYPE GENMASK(30, 28) 88 + #define LNaTECR0_EQ_SGN_PREQ BIT(23) 89 + #define LNaTECR0_EQ_PREQ GENMASK(19, 16) 90 + #define LNaTECR0_EQ_SGN_POST1Q BIT(15) 91 + #define LNaTECR0_EQ_POST1Q GENMASK(12, 8) 92 + #define LNaTECR0_EQ_AMP_RED GENMASK(5, 0) 93 + 94 + #define LNaTECR1(lane) (0x800 + (lane) * 0x100 + 0x34) 95 + #define LNaTECR1_EQ_ADPT_EQ_DRVR_DIS BIT(31) 96 + #define LNaTECR1_EQ_ADPT_EQ GENMASK(29, 24) 73 97 74 98 /* Lane a Rx Reset Control Register */ 75 - #define LYNX_28G_LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40) 76 - #define LYNX_28G_LNaRRSTCTL_HLT_REQ BIT(27) 77 - #define LYNX_28G_LNaRRSTCTL_RST_DONE BIT(30) 78 - #define LYNX_28G_LNaRRSTCTL_RST_REQ BIT(31) 79 - #define LYNX_28G_LNaRRSTCTL_CDR_LOCK BIT(12) 99 + #define LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40) 100 + #define LNaRRSTCTL_HLT_REQ BIT(27) 101 + #define LNaRRSTCTL_RST_DONE BIT(30) 102 + #define LNaRRSTCTL_RST_REQ BIT(31) 103 + #define LNaRRSTCTL_CDR_LOCK BIT(12) 80 104 81 105 /* Lane a Rx General Control Register */ 82 - #define LYNX_28G_LNaRGCR0(lane) (0x800 + (lane) * 0x100 + 0x44) 83 - #define LYNX_28G_LNaRGCR0_USE_PLLF 0x0 84 - #define LYNX_28G_LNaRGCR0_USE_PLLS BIT(28) 85 - #define LYNX_28G_LNaRGCR0_USE_PLL_MSK BIT(28) 86 - #define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) 87 - #define LYNX_28G_LNaRGCR0_N_RATE_FULL 0x0 88 - #define LYNX_28G_LNaRGCR0_N_RATE_HALF 0x1000000 89 - #define LYNX_28G_LNaRGCR0_N_RATE_QUARTER 0x2000000 90 - #define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) 106 + #define LNaRGCR0(lane) (0x800 + (lane) * 0x100 + 0x44) 107 + #define LNaRGCR0_USE_PLL BIT(28) 108 + #define LNaRGCR0_USE_PLLF 0x0 109 + #define LNaRGCR0_USE_PLLS 0x1 110 + #define LNaRGCR0_N_RATE GENMASK(26, 24) 111 + #define LNaRGCR0_N_RATE_FULL 0x0 112 + #define LNaRGCR0_N_RATE_HALF 0x1 113 + #define LNaRGCR0_N_RATE_QUARTER 0x2 91 114 92 - #define LYNX_28G_LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48) 115 + #define LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48) 116 + #define LNaRGCR1_RX_ORD_ELECIDLE BIT(31) 117 + #define LNaRGCR1_DATA_LOST_FLT BIT(30) 118 + #define LNaRGCR1_DATA_LOST BIT(29) 119 + #define LNaRGCR1_IDLE_CONFIG BIT(28) 120 + #define LNaRGCR1_ENTER_IDLE_FLT_SEL GENMASK(26, 24) 121 + #define LNaRGCR1_EXIT_IDLE_FLT_SEL GENMASK(22, 20) 122 + #define LNaRGCR1_DATA_LOST_TH_SEL GENMASK(18, 16) 123 + #define LNaRGCR1_EXT_REC_CLK_SEL GENMASK(10, 8) 124 + #define LNaRGCR1_WAKE_TX_DIS BIT(5) 125 + #define LNaRGCR1_PHY_RDY BIT(4) 126 + #define LNaRGCR1_CHANGE_RX_CLK BIT(3) 127 + #define LNaRGCR1_PWR_MGT GENMASK(2, 0) 93 128 94 - #define LYNX_28G_LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50) 95 - #define LYNX_28G_LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54) 96 - #define LYNX_28G_LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58) 129 + #define LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50) 130 + #define LNaRECR0_EQ_GAINK2_HF_OV_EN BIT(31) 131 + #define LNaRECR0_EQ_GAINK2_HF_OV GENMASK(28, 24) 132 + #define LNaRECR0_EQ_GAINK3_MF_OV_EN BIT(23) 133 + #define LNaRECR0_EQ_GAINK3_MF_OV GENMASK(20, 16) 134 + #define LNaRECR0_EQ_GAINK4_LF_OV_EN BIT(7) 135 + #define LNaRECR0_EQ_GAINK4_LF_DIS BIT(6) 136 + #define LNaRECR0_EQ_GAINK4_LF_OV GENMASK(4, 0) 97 137 98 - #define LYNX_28G_LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74) 138 + #define LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54) 139 + #define LNaRECR1_EQ_BLW_OV_EN BIT(31) 140 + #define LNaRECR1_EQ_BLW_OV GENMASK(28, 24) 141 + #define LNaRECR1_EQ_OFFSET_OV_EN BIT(23) 142 + #define LNaRECR1_EQ_OFFSET_OV GENMASK(21, 16) 99 143 100 - #define LYNX_28G_LNaPSS(lane) (0x1000 + (lane) * 0x4) 101 - #define LYNX_28G_LNaPSS_TYPE(pss) (((pss) & GENMASK(30, 24)) >> 24) 102 - #define LYNX_28G_LNaPSS_TYPE_SGMII 0x4 103 - #define LYNX_28G_LNaPSS_TYPE_XFI 0x28 144 + #define LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58) 145 + #define LNaRECR2_EQ_OFFSET_RNG_DBL BIT(31) 146 + #define LNaRECR2_EQ_BOOST GENMASK(29, 28) 147 + #define LNaRECR2_EQ_BLW_SEL GENMASK(25, 24) 148 + #define LNaRECR2_EQ_ZERO GENMASK(17, 16) 149 + #define LNaRECR2_EQ_IND GENMASK(13, 12) 150 + #define LNaRECR2_EQ_BIN_DATA_AVG_TC GENMASK(5, 4) 151 + #define LNaRECR2_SPARE_IN GENMASK(1, 0) 104 152 105 - #define LYNX_28G_SGMIIaCR1(lane) (0x1804 + (lane) * 0x10) 106 - #define LYNX_28G_SGMIIaCR1_SGPCS_EN BIT(11) 107 - #define LYNX_28G_SGMIIaCR1_SGPCS_DIS 0x0 108 - #define LYNX_28G_SGMIIaCR1_SGPCS_MSK BIT(11) 153 + #define LNaRECR3(lane) (0x800 + (lane) * 0x100 + 0x5c) 154 + #define LNaRECR3_EQ_SNAP_START BIT(31) 155 + #define LNaRECR3_EQ_SNAP_DONE BIT(30) 156 + #define LNaRECR3_EQ_GAINK2_HF_STAT GENMASK(28, 24) 157 + #define LNaRECR3_EQ_GAINK3_MF_STAT GENMASK(20, 16) 158 + #define LNaRECR3_SPARE_OUT GENMASK(13, 12) 159 + #define LNaRECR3_EQ_GAINK4_LF_STAT GENMASK(4, 0) 160 + 161 + #define LNaRECR4(lane) (0x800 + (lane) * 0x100 + 0x60) 162 + #define LNaRECR4_BLW_STAT GENMASK(28, 24) 163 + #define LNaRECR4_EQ_OFFSET_STAT GENMASK(21, 16) 164 + #define LNaRECR4_EQ_BIN_DATA_SEL GENMASK(15, 12) 165 + #define LNaRECR4_EQ_BIN_DATA GENMASK(8, 0) /* bit 9 is reserved */ 166 + #define LNaRECR4_EQ_BIN_DATA_SGN BIT(8) 167 + 168 + #define LNaRCCR0(lane) (0x800 + (lane) * 0x100 + 0x68) 169 + #define LNaRCCR0_CAL_EN BIT(31) 170 + #define LNaRCCR0_MEAS_EN BIT(30) 171 + #define LNaRCCR0_CAL_BIN_SEL BIT(28) 172 + #define LNaRCCR0_CAL_DC3_DIS BIT(27) 173 + #define LNaRCCR0_CAL_DC2_DIS BIT(26) 174 + #define LNaRCCR0_CAL_DC1_DIS BIT(25) 175 + #define LNaRCCR0_CAL_DC0_DIS BIT(24) 176 + #define LNaRCCR0_CAL_AC3_OV_EN BIT(15) 177 + #define LNaRCCR0_CAL_AC3_OV GENMASK(11, 8) 178 + #define LNaRCCR0_CAL_AC2_OV_EN BIT(7) 179 + 180 + #define LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74) 181 + #define LNaRSCCR0_SMP_OFF_EN BIT(31) 182 + #define LNaRSCCR0_SMP_OFF_OV_EN BIT(30) 183 + #define LNaRSCCR0_SMP_MAN_OFF_EN BIT(29) 184 + #define LNaRSCCR0_SMP_OFF_RNG_OV_EN BIT(27) 185 + #define LNaRSCCR0_SMP_OFF_RNG_4X_OV BIT(25) 186 + #define LNaRSCCR0_SMP_OFF_RNG_2X_OV BIT(24) 187 + #define LNaRSCCR0_SMP_AUTOZ_PD BIT(23) 188 + #define LNaRSCCR0_SMP_AUTOZ_CTRL GENMASK(19, 16) 189 + #define LNaRSCCR0_SMP_AUTOZ_D1R GENMASK(13, 12) 190 + #define LNaRSCCR0_SMP_AUTOZ_D1F GENMASK(9, 8) 191 + #define LNaRSCCR0_SMP_AUTOZ_EG1R GENMASK(5, 4) 192 + #define LNaRSCCR0_SMP_AUTOZ_EG1F GENMASK(1, 0) 193 + 194 + #define LNaTTLCR0(lane) (0x800 + (lane) * 0x100 + 0x80) 195 + #define LNaTTLCR0_TTL_FLT_SEL GENMASK(29, 24) 196 + #define LNaTTLCR0_TTL_SLO_PM_BYP BIT(22) 197 + #define LNaTTLCR0_STALL_DET_DIS BIT(21) 198 + #define LNaTTLCR0_INACT_MON_DIS BIT(20) 199 + #define LNaTTLCR0_CDR_OV GENMASK(18, 16) 200 + #define LNaTTLCR0_DATA_IN_SSC BIT(15) 201 + #define LNaTTLCR0_CDR_MIN_SMP_ON GENMASK(1, 0) 202 + 203 + #define LNaTCSR0(lane) (0x800 + (lane) * 0x100 + 0xa0) 204 + #define LNaTCSR0_SD_STAT_OBS_EN BIT(31) 205 + #define LNaTCSR0_SD_LPBK_SEL GENMASK(29, 28) 206 + 207 + #define LNaPSS(lane) (0x1000 + (lane) * 0x4) 208 + #define LNaPSS_TYPE GENMASK(30, 24) 209 + #define LNaPSS_TYPE_SGMII (PROTO_SEL_SGMII_BASEX_KX << 2) 210 + #define LNaPSS_TYPE_XFI (PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2) 211 + #define LNaPSS_TYPE_40G ((PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2) | 3) 212 + #define LNaPSS_TYPE_25G (PROTO_SEL_25G_50G_100G << 2) 213 + #define LNaPSS_TYPE_100G ((PROTO_SEL_25G_50G_100G << 2) | 2) 214 + 215 + /* MDEV_PORT is at the same bitfield address for all protocol converters */ 216 + #define MDEV_PORT GENMASK(31, 27) 217 + 218 + #define SGMIIaCR0(lane) (0x1800 + (lane) * 0x10) 219 + #define SGMIIaCR1(lane) (0x1804 + (lane) * 0x10) 220 + #define SGMIIaCR1_SGPCS_EN BIT(11) 221 + 222 + #define ANLTaCR0(lane) (0x1a00 + (lane) * 0x10) 223 + #define ANLTaCR1(lane) (0x1a04 + (lane) * 0x10) 224 + 225 + #define SXGMIIaCR0(lane) (0x1a80 + (lane) * 0x10) 226 + #define SXGMIIaCR0_RST BIT(31) 227 + #define SXGMIIaCR0_PD BIT(30) 228 + 229 + #define SXGMIIaCR1(lane) (0x1a84 + (lane) * 0x10) 230 + 231 + #define E25GaCR0(lane) (0x1b00 + (lane) * 0x10) 232 + #define E25GaCR0_RST BIT(31) 233 + #define E25GaCR0_PD BIT(30) 234 + 235 + #define E25GaCR1(lane) (0x1b04 + (lane) * 0x10) 236 + 237 + #define E25GaCR2(lane) (0x1b08 + (lane) * 0x10) 238 + #define E25GaCR2_FEC_ENA BIT(23) 239 + #define E25GaCR2_FEC_ERR_ENA BIT(22) 240 + #define E25GaCR2_FEC91_ENA BIT(20) 241 + 242 + #define E40GaCR0(pcvt) (0x1b40 + (pcvt) * 0x20) 243 + #define E40GaCR1(pcvt) (0x1b44 + (pcvt) * 0x20) 244 + 245 + #define E50GaCR1(pcvt) (0x1b84 + (pcvt) * 0x10) 246 + 247 + #define E100GaCR1(pcvt) (0x1c04 + (pcvt) * 0x20) 248 + 249 + #define CR(x) ((x) * 4) 250 + 251 + enum lynx_28g_eq_type { 252 + EQ_TYPE_NO_EQ = 0, 253 + EQ_TYPE_2TAP = 1, 254 + EQ_TYPE_3TAP = 2, 255 + }; 256 + 257 + enum lynx_28g_proto_sel { 258 + PROTO_SEL_PCIE = 0, 259 + PROTO_SEL_SGMII_BASEX_KX = 1, 260 + PROTO_SEL_SATA = 2, 261 + PROTO_SEL_XAUI = 4, 262 + PROTO_SEL_XFI_10GBASER_KR_SXGMII = 0xa, 263 + PROTO_SEL_25G_50G_100G = 0x1a, 264 + }; 265 + 266 + enum lynx_lane_mode { 267 + LANE_MODE_UNKNOWN, 268 + LANE_MODE_1000BASEX_SGMII, 269 + LANE_MODE_10GBASER, 270 + LANE_MODE_USXGMII, 271 + LANE_MODE_MAX, 272 + }; 273 + 274 + struct lynx_28g_proto_conf { 275 + /* LNaGCR0 */ 276 + int proto_sel; 277 + int if_width; 278 + /* LNaTECR0 */ 279 + int teq_type; 280 + int sgn_preq; 281 + int ratio_preq; 282 + int sgn_post1q; 283 + int ratio_post1q; 284 + int amp_red; 285 + /* LNaTECR1 */ 286 + int adpt_eq; 287 + /* LNaRGCR1 */ 288 + int enter_idle_flt_sel; 289 + int exit_idle_flt_sel; 290 + int data_lost_th_sel; 291 + /* LNaRECR0 */ 292 + int gk2ovd; 293 + int gk3ovd; 294 + int gk4ovd; 295 + int gk2ovd_en; 296 + int gk3ovd_en; 297 + int gk4ovd_en; 298 + /* LNaRECR1 ? */ 299 + int eq_offset_ovd; 300 + int eq_offset_ovd_en; 301 + /* LNaRECR2 */ 302 + int eq_offset_rng_dbl; 303 + int eq_blw_sel; 304 + int eq_boost; 305 + int spare_in; 306 + /* LNaRSCCR0 */ 307 + int smp_autoz_d1r; 308 + int smp_autoz_eg1r; 309 + /* LNaRCCR0 */ 310 + int rccr0; 311 + /* LNaTTLCR0 */ 312 + int ttlcr0; 313 + }; 314 + 315 + static const struct lynx_28g_proto_conf lynx_28g_proto_conf[LANE_MODE_MAX] = { 316 + [LANE_MODE_1000BASEX_SGMII] = { 317 + .proto_sel = LNaGCR0_PROTO_SEL_SGMII, 318 + .if_width = LNaGCR0_IF_WIDTH_10_BIT, 319 + .teq_type = EQ_TYPE_NO_EQ, 320 + .sgn_preq = 1, 321 + .ratio_preq = 0, 322 + .sgn_post1q = 1, 323 + .ratio_post1q = 0, 324 + .amp_red = 6, 325 + .adpt_eq = 48, 326 + .enter_idle_flt_sel = 4, 327 + .exit_idle_flt_sel = 3, 328 + .data_lost_th_sel = 1, 329 + .gk2ovd = 0x1f, 330 + .gk3ovd = 0, 331 + .gk4ovd = 0, 332 + .gk2ovd_en = 1, 333 + .gk3ovd_en = 1, 334 + .gk4ovd_en = 0, 335 + .eq_offset_ovd = 0x1f, 336 + .eq_offset_ovd_en = 0, 337 + .eq_offset_rng_dbl = 0, 338 + .eq_blw_sel = 0, 339 + .eq_boost = 0, 340 + .spare_in = 0, 341 + .smp_autoz_d1r = 0, 342 + .smp_autoz_eg1r = 0, 343 + .rccr0 = LNaRCCR0_CAL_EN, 344 + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | 345 + LNaTTLCR0_DATA_IN_SSC, 346 + }, 347 + [LANE_MODE_USXGMII] = { 348 + .proto_sel = LNaGCR0_PROTO_SEL_XFI, 349 + .if_width = LNaGCR0_IF_WIDTH_20_BIT, 350 + .teq_type = EQ_TYPE_2TAP, 351 + .sgn_preq = 1, 352 + .ratio_preq = 0, 353 + .sgn_post1q = 1, 354 + .ratio_post1q = 3, 355 + .amp_red = 7, 356 + .adpt_eq = 48, 357 + .enter_idle_flt_sel = 0, 358 + .exit_idle_flt_sel = 0, 359 + .data_lost_th_sel = 0, 360 + .gk2ovd = 0, 361 + .gk3ovd = 0, 362 + .gk4ovd = 0, 363 + .gk2ovd_en = 0, 364 + .gk3ovd_en = 0, 365 + .gk4ovd_en = 0, 366 + .eq_offset_ovd = 0x1f, 367 + .eq_offset_ovd_en = 0, 368 + .eq_offset_rng_dbl = 1, 369 + .eq_blw_sel = 1, 370 + .eq_boost = 0, 371 + .spare_in = 0, 372 + .smp_autoz_d1r = 2, 373 + .smp_autoz_eg1r = 0, 374 + .rccr0 = LNaRCCR0_CAL_EN, 375 + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | 376 + LNaTTLCR0_DATA_IN_SSC, 377 + }, 378 + [LANE_MODE_10GBASER] = { 379 + .proto_sel = LNaGCR0_PROTO_SEL_XFI, 380 + .if_width = LNaGCR0_IF_WIDTH_20_BIT, 381 + .teq_type = EQ_TYPE_2TAP, 382 + .sgn_preq = 1, 383 + .ratio_preq = 0, 384 + .sgn_post1q = 1, 385 + .ratio_post1q = 3, 386 + .amp_red = 7, 387 + .adpt_eq = 48, 388 + .enter_idle_flt_sel = 0, 389 + .exit_idle_flt_sel = 0, 390 + .data_lost_th_sel = 0, 391 + .gk2ovd = 0, 392 + .gk3ovd = 0, 393 + .gk4ovd = 0, 394 + .gk2ovd_en = 0, 395 + .gk3ovd_en = 0, 396 + .gk4ovd_en = 0, 397 + .eq_offset_ovd = 0x1f, 398 + .eq_offset_ovd_en = 0, 399 + .eq_offset_rng_dbl = 1, 400 + .eq_blw_sel = 1, 401 + .eq_boost = 0, 402 + .spare_in = 0, 403 + .smp_autoz_d1r = 2, 404 + .smp_autoz_eg1r = 0, 405 + .rccr0 = LNaRCCR0_CAL_EN, 406 + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | 407 + LNaTTLCR0_DATA_IN_SSC, 408 + }, 409 + }; 410 + 411 + struct lynx_pccr { 412 + int offset; 413 + int width; 414 + int shift; 415 + }; 109 416 110 417 struct lynx_28g_priv; 111 418 ··· 421 112 struct lynx_28g_priv *priv; 422 113 u32 rstctl, cr0, cr1; 423 114 int id; 424 - DECLARE_PHY_INTERFACE_MASK(supported); 115 + DECLARE_BITMAP(supported, LANE_MODE_MAX); 425 116 }; 426 117 427 118 struct lynx_28g_lane { ··· 430 121 bool powered_up; 431 122 bool init; 432 123 unsigned int id; 433 - phy_interface_t interface; 124 + enum lynx_lane_mode mode; 434 125 }; 435 126 436 127 struct lynx_28g_priv { ··· 458 149 iowrite32(tmp, reg); 459 150 } 460 151 152 + #define lynx_28g_read(priv, off) \ 153 + ioread32((priv)->base + (off)) 154 + #define lynx_28g_write(priv, off, val) \ 155 + iowrite32(val, (priv)->base + (off)) 461 156 #define lynx_28g_lane_rmw(lane, reg, val, mask) \ 462 - lynx_28g_rmw((lane)->priv, LYNX_28G_##reg(lane->id), \ 463 - LYNX_28G_##reg##_##val, LYNX_28G_##reg##_##mask) 157 + lynx_28g_rmw((lane)->priv, reg(lane->id), val, mask) 464 158 #define lynx_28g_lane_read(lane, reg) \ 465 - ioread32((lane)->priv->base + LYNX_28G_##reg((lane)->id)) 159 + ioread32((lane)->priv->base + reg((lane)->id)) 160 + #define lynx_28g_lane_write(lane, reg, val) \ 161 + iowrite32(val, (lane)->priv->base + reg((lane)->id)) 466 162 #define lynx_28g_pll_read(pll, reg) \ 467 - ioread32((pll)->priv->base + LYNX_28G_##reg((pll)->id)) 163 + ioread32((pll)->priv->base + reg((pll)->id)) 468 164 469 - static bool lynx_28g_supports_interface(struct lynx_28g_priv *priv, int intf) 165 + static const char *lynx_lane_mode_str(enum lynx_lane_mode lane_mode) 166 + { 167 + switch (lane_mode) { 168 + case LANE_MODE_1000BASEX_SGMII: 169 + return "1000Base-X/SGMII"; 170 + case LANE_MODE_10GBASER: 171 + return "10GBase-R"; 172 + case LANE_MODE_USXGMII: 173 + return "USXGMII"; 174 + default: 175 + return "unknown"; 176 + } 177 + } 178 + 179 + static enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf) 180 + { 181 + switch (intf) { 182 + case PHY_INTERFACE_MODE_SGMII: 183 + case PHY_INTERFACE_MODE_1000BASEX: 184 + return LANE_MODE_1000BASEX_SGMII; 185 + case PHY_INTERFACE_MODE_10GBASER: 186 + return LANE_MODE_10GBASER; 187 + case PHY_INTERFACE_MODE_USXGMII: 188 + return LANE_MODE_USXGMII; 189 + default: 190 + return LANE_MODE_UNKNOWN; 191 + } 192 + } 193 + 194 + static bool lynx_28g_supports_lane_mode(struct lynx_28g_priv *priv, 195 + enum lynx_lane_mode mode) 470 196 { 471 197 int i; 472 198 473 199 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 474 - if (LYNX_28G_PLLnRSTCTL_DIS(priv->pll[i].rstctl)) 200 + if (PLLnRSTCTL_DIS(priv->pll[i].rstctl)) 475 201 continue; 476 202 477 - if (test_bit(intf, priv->pll[i].supported)) 203 + if (test_bit(mode, priv->pll[i].supported)) 478 204 return true; 479 205 } 480 206 ··· 517 173 } 518 174 519 175 static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, 520 - phy_interface_t intf) 176 + enum lynx_lane_mode mode) 521 177 { 522 178 struct lynx_28g_pll *pll; 523 179 int i; ··· 525 181 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 526 182 pll = &priv->pll[i]; 527 183 528 - if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 184 + if (PLLnRSTCTL_DIS(pll->rstctl)) 529 185 continue; 530 186 531 - if (test_bit(intf, pll->supported)) 187 + if (test_bit(mode, pll->supported)) 532 188 return pll; 533 189 } 534 190 535 191 /* no pll supports requested mode, either caller forgot to check 536 192 * lynx_28g_supports_lane_mode, or this is a bug. 537 193 */ 538 - dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf)); 194 + dev_WARN_ONCE(priv->dev, 1, "no pll for lane mode %s\n", 195 + lynx_lane_mode_str(mode)); 539 196 return NULL; 540 197 } 541 198 542 199 static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane, 543 200 struct lynx_28g_pll *pll, 544 - phy_interface_t intf) 201 + enum lynx_lane_mode lane_mode) 545 202 { 546 - switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 547 - case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 548 - case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 549 - switch (intf) { 550 - case PHY_INTERFACE_MODE_SGMII: 551 - case PHY_INTERFACE_MODE_1000BASEX: 552 - lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK); 553 - lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_QUARTER, N_RATE_MSK); 203 + switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) { 204 + case PLLnCR1_FRATE_5G_10GVCO: 205 + case PLLnCR1_FRATE_5G_25GVCO: 206 + switch (lane_mode) { 207 + case LANE_MODE_1000BASEX_SGMII: 208 + lynx_28g_lane_rmw(lane, LNaTGCR0, 209 + FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_QUARTER), 210 + LNaTGCR0_N_RATE); 211 + lynx_28g_lane_rmw(lane, LNaRGCR0, 212 + FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_QUARTER), 213 + LNaRGCR0_N_RATE); 554 214 break; 555 215 default: 556 216 break; 557 217 } 558 218 break; 559 - case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 560 - switch (intf) { 561 - case PHY_INTERFACE_MODE_10GBASER: 562 - case PHY_INTERFACE_MODE_USXGMII: 563 - lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_FULL, N_RATE_MSK); 564 - lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_FULL, N_RATE_MSK); 219 + case PLLnCR1_FRATE_10G_20GVCO: 220 + switch (lane_mode) { 221 + case LANE_MODE_10GBASER: 222 + case LANE_MODE_USXGMII: 223 + lynx_28g_lane_rmw(lane, LNaTGCR0, 224 + FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_FULL), 225 + LNaTGCR0_N_RATE); 226 + lynx_28g_lane_rmw(lane, LNaRGCR0, 227 + FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_FULL), 228 + LNaRGCR0_N_RATE); 565 229 break; 566 230 default: 567 231 break; ··· 584 232 struct lynx_28g_pll *pll) 585 233 { 586 234 if (pll->id == 0) { 587 - lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLF, USE_PLL_MSK); 588 - lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLF, USE_PLL_MSK); 235 + lynx_28g_lane_rmw(lane, LNaTGCR0, 236 + FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLF), 237 + LNaTGCR0_USE_PLL); 238 + lynx_28g_lane_rmw(lane, LNaRGCR0, 239 + FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLF), 240 + LNaRGCR0_USE_PLL); 589 241 } else { 590 - lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLS, USE_PLL_MSK); 591 - lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLS, USE_PLL_MSK); 242 + lynx_28g_lane_rmw(lane, LNaTGCR0, 243 + FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLS), 244 + LNaTGCR0_USE_PLL); 245 + lynx_28g_lane_rmw(lane, LNaRGCR0, 246 + FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLS), 247 + LNaRGCR0_USE_PLL); 592 248 } 593 - } 594 - 595 - static void lynx_28g_cleanup_lane(struct lynx_28g_lane *lane) 596 - { 597 - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 598 - struct lynx_28g_priv *priv = lane->priv; 599 - 600 - /* Cleanup the protocol configuration registers of the current protocol */ 601 - switch (lane->interface) { 602 - case PHY_INTERFACE_MODE_10GBASER: 603 - lynx_28g_rmw(priv, LYNX_28G_PCCC, 604 - LYNX_28G_PCCC_SXGMII_DIS << lane_offset, 605 - GENMASK(3, 0) << lane_offset); 606 - break; 607 - case PHY_INTERFACE_MODE_SGMII: 608 - case PHY_INTERFACE_MODE_1000BASEX: 609 - lynx_28g_rmw(priv, LYNX_28G_PCC8, 610 - LYNX_28G_PCC8_SGMII_DIS << lane_offset, 611 - GENMASK(3, 0) << lane_offset); 612 - break; 613 - default: 614 - break; 615 - } 616 - } 617 - 618 - static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane) 619 - { 620 - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 621 - struct lynx_28g_priv *priv = lane->priv; 622 - struct lynx_28g_pll *pll; 623 - 624 - lynx_28g_cleanup_lane(lane); 625 - 626 - /* Setup the lane to run in SGMII */ 627 - lynx_28g_rmw(priv, LYNX_28G_PCC8, 628 - LYNX_28G_PCC8_SGMII << lane_offset, 629 - GENMASK(3, 0) << lane_offset); 630 - 631 - /* Setup the protocol select and SerDes parallel interface width */ 632 - lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); 633 - lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); 634 - 635 - /* Find the PLL that works with this interface type */ 636 - pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); 637 - if (unlikely(pll == NULL)) 638 - return; 639 - 640 - /* Switch to the PLL that works with this interface type */ 641 - lynx_28g_lane_set_pll(lane, pll); 642 - 643 - /* Choose the portion of clock net to be used on this lane */ 644 - lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_SGMII); 645 - 646 - /* Enable the SGMII PCS */ 647 - lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_EN, SGPCS_MSK); 648 - 649 - /* Configure the appropriate equalization parameters for the protocol */ 650 - iowrite32(0x00808006, priv->base + LYNX_28G_LNaTECR0(lane->id)); 651 - iowrite32(0x04310000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 652 - iowrite32(0x9f800000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 653 - iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 654 - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR2(lane->id)); 655 - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 656 - } 657 - 658 - static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane) 659 - { 660 - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 661 - struct lynx_28g_priv *priv = lane->priv; 662 - struct lynx_28g_pll *pll; 663 - 664 - lynx_28g_cleanup_lane(lane); 665 - 666 - /* Enable the SXGMII lane */ 667 - lynx_28g_rmw(priv, LYNX_28G_PCCC, 668 - LYNX_28G_PCCC_10GBASER << lane_offset, 669 - GENMASK(3, 0) << lane_offset); 670 - 671 - /* Setup the protocol select and SerDes parallel interface width */ 672 - lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); 673 - lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); 674 - 675 - /* Find the PLL that works with this interface type */ 676 - pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); 677 - if (unlikely(pll == NULL)) 678 - return; 679 - 680 - /* Switch to the PLL that works with this interface type */ 681 - lynx_28g_lane_set_pll(lane, pll); 682 - 683 - /* Choose the portion of clock net to be used on this lane */ 684 - lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER); 685 - 686 - /* Disable the SGMII PCS */ 687 - lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK); 688 - 689 - /* Configure the appropriate equalization parameters for the protocol */ 690 - iowrite32(0x10808307, priv->base + LYNX_28G_LNaTECR0(lane->id)); 691 - iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 692 - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 693 - iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 694 - iowrite32(0x81000020, priv->base + LYNX_28G_LNaRECR2(lane->id)); 695 - iowrite32(0x00002000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 696 249 } 697 250 698 251 static int lynx_28g_power_off(struct phy *phy) ··· 609 352 return 0; 610 353 611 354 /* Issue a halt request */ 612 - lynx_28g_lane_rmw(lane, LNaTRSTCTL, HLT_REQ, HLT_REQ); 613 - lynx_28g_lane_rmw(lane, LNaRRSTCTL, HLT_REQ, HLT_REQ); 355 + lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_HLT_REQ, 356 + LNaTRSTCTL_HLT_REQ); 357 + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_HLT_REQ, 358 + LNaRRSTCTL_HLT_REQ); 614 359 615 360 /* Wait until the halting process is complete */ 616 361 do { 617 362 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 618 363 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 619 - } while ((trstctl & LYNX_28G_LNaTRSTCTL_HLT_REQ) || 620 - (rrstctl & LYNX_28G_LNaRRSTCTL_HLT_REQ)); 364 + } while ((trstctl & LNaTRSTCTL_HLT_REQ) || 365 + (rrstctl & LNaRRSTCTL_HLT_REQ)); 621 366 622 367 lane->powered_up = false; 623 368 ··· 635 376 return 0; 636 377 637 378 /* Issue a reset request on the lane */ 638 - lynx_28g_lane_rmw(lane, LNaTRSTCTL, RST_REQ, RST_REQ); 639 - lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 379 + lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_RST_REQ, 380 + LNaTRSTCTL_RST_REQ); 381 + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ, 382 + LNaRRSTCTL_RST_REQ); 640 383 641 384 /* Wait until the reset sequence is completed */ 642 385 do { 643 386 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 644 387 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 645 - } while (!(trstctl & LYNX_28G_LNaTRSTCTL_RST_DONE) || 646 - !(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 388 + } while (!(trstctl & LNaTRSTCTL_RST_DONE) || 389 + !(rrstctl & LNaRRSTCTL_RST_DONE)); 647 390 648 391 lane->powered_up = true; 649 392 650 393 return 0; 394 + } 395 + 396 + static int lynx_28g_get_pccr(enum lynx_lane_mode lane_mode, int lane, 397 + struct lynx_pccr *pccr) 398 + { 399 + switch (lane_mode) { 400 + case LANE_MODE_1000BASEX_SGMII: 401 + pccr->offset = PCC8; 402 + pccr->width = 4; 403 + pccr->shift = SGMII_CFG(lane); 404 + break; 405 + case LANE_MODE_USXGMII: 406 + case LANE_MODE_10GBASER: 407 + pccr->offset = PCCC; 408 + pccr->width = 4; 409 + pccr->shift = SXGMII_CFG(lane); 410 + break; 411 + default: 412 + return -EOPNOTSUPP; 413 + } 414 + 415 + return 0; 416 + } 417 + 418 + static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode) 419 + { 420 + switch (lane_mode) { 421 + case LANE_MODE_1000BASEX_SGMII: 422 + return SGMIIaCR0(lane); 423 + case LANE_MODE_USXGMII: 424 + case LANE_MODE_10GBASER: 425 + return SXGMIIaCR0(lane); 426 + default: 427 + return -EOPNOTSUPP; 428 + } 429 + } 430 + 431 + static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode, 432 + u32 *val) 433 + { 434 + struct lynx_28g_priv *priv = lane->priv; 435 + struct lynx_pccr pccr; 436 + u32 tmp; 437 + int err; 438 + 439 + err = lynx_28g_get_pccr(mode, lane->id, &pccr); 440 + if (err) 441 + return err; 442 + 443 + tmp = lynx_28g_read(priv, pccr.offset); 444 + *val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0); 445 + 446 + return 0; 447 + } 448 + 449 + static int lynx_pccr_write(struct lynx_28g_lane *lane, 450 + enum lynx_lane_mode lane_mode, u32 val) 451 + { 452 + struct lynx_28g_priv *priv = lane->priv; 453 + struct lynx_pccr pccr; 454 + u32 old, tmp, mask; 455 + int err; 456 + 457 + err = lynx_28g_get_pccr(lane_mode, lane->id, &pccr); 458 + if (err) 459 + return err; 460 + 461 + old = lynx_28g_read(priv, pccr.offset); 462 + mask = GENMASK(pccr.width - 1, 0) << pccr.shift; 463 + tmp = (old & ~mask) | (val << pccr.shift); 464 + lynx_28g_write(priv, pccr.offset, tmp); 465 + 466 + dev_dbg(&lane->phy->dev, "PCCR@0x%x: 0x%x -> 0x%x\n", 467 + pccr.offset, old, tmp); 468 + 469 + return 0; 470 + } 471 + 472 + static int lynx_pcvt_read(struct lynx_28g_lane *lane, 473 + enum lynx_lane_mode lane_mode, int cr, u32 *val) 474 + { 475 + struct lynx_28g_priv *priv = lane->priv; 476 + int offset; 477 + 478 + offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); 479 + if (offset < 0) 480 + return offset; 481 + 482 + *val = lynx_28g_read(priv, offset + cr); 483 + 484 + return 0; 485 + } 486 + 487 + static int lynx_pcvt_write(struct lynx_28g_lane *lane, 488 + enum lynx_lane_mode lane_mode, int cr, u32 val) 489 + { 490 + struct lynx_28g_priv *priv = lane->priv; 491 + int offset; 492 + 493 + offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); 494 + if (offset < 0) 495 + return offset; 496 + 497 + lynx_28g_write(priv, offset + cr, val); 498 + 499 + return 0; 500 + } 501 + 502 + static int lynx_pcvt_rmw(struct lynx_28g_lane *lane, 503 + enum lynx_lane_mode lane_mode, 504 + int cr, u32 val, u32 mask) 505 + { 506 + int err; 507 + u32 tmp; 508 + 509 + err = lynx_pcvt_read(lane, lane_mode, cr, &tmp); 510 + if (err) 511 + return err; 512 + 513 + tmp &= ~mask; 514 + tmp |= val; 515 + 516 + return lynx_pcvt_write(lane, lane_mode, cr, tmp); 517 + } 518 + 519 + static void lynx_28g_lane_remap_pll(struct lynx_28g_lane *lane, 520 + enum lynx_lane_mode lane_mode) 521 + { 522 + struct lynx_28g_priv *priv = lane->priv; 523 + struct lynx_28g_pll *pll; 524 + 525 + /* Switch to the PLL that works with this interface type */ 526 + pll = lynx_28g_pll_get(priv, lane_mode); 527 + if (unlikely(pll == NULL)) 528 + return; 529 + 530 + lynx_28g_lane_set_pll(lane, pll); 531 + 532 + /* Choose the portion of clock net to be used on this lane */ 533 + lynx_28g_lane_set_nrate(lane, pll, lane_mode); 534 + } 535 + 536 + static void lynx_28g_lane_change_proto_conf(struct lynx_28g_lane *lane, 537 + enum lynx_lane_mode lane_mode) 538 + { 539 + const struct lynx_28g_proto_conf *conf = &lynx_28g_proto_conf[lane_mode]; 540 + 541 + lynx_28g_lane_rmw(lane, LNaGCR0, 542 + FIELD_PREP(LNaGCR0_PROTO_SEL, conf->proto_sel) | 543 + FIELD_PREP(LNaGCR0_IF_WIDTH, conf->if_width), 544 + LNaGCR0_PROTO_SEL | LNaGCR0_IF_WIDTH); 545 + 546 + lynx_28g_lane_rmw(lane, LNaTECR0, 547 + FIELD_PREP(LNaTECR0_EQ_TYPE, conf->teq_type) | 548 + FIELD_PREP(LNaTECR0_EQ_SGN_PREQ, conf->sgn_preq) | 549 + FIELD_PREP(LNaTECR0_EQ_PREQ, conf->ratio_preq) | 550 + FIELD_PREP(LNaTECR0_EQ_SGN_POST1Q, conf->sgn_post1q) | 551 + FIELD_PREP(LNaTECR0_EQ_POST1Q, conf->ratio_post1q) | 552 + FIELD_PREP(LNaTECR0_EQ_AMP_RED, conf->amp_red), 553 + LNaTECR0_EQ_TYPE | 554 + LNaTECR0_EQ_SGN_PREQ | 555 + LNaTECR0_EQ_PREQ | 556 + LNaTECR0_EQ_SGN_POST1Q | 557 + LNaTECR0_EQ_POST1Q | 558 + LNaTECR0_EQ_AMP_RED); 559 + 560 + lynx_28g_lane_rmw(lane, LNaTECR1, 561 + FIELD_PREP(LNaTECR1_EQ_ADPT_EQ, conf->adpt_eq), 562 + LNaTECR1_EQ_ADPT_EQ); 563 + 564 + lynx_28g_lane_rmw(lane, LNaRGCR1, 565 + FIELD_PREP(LNaRGCR1_ENTER_IDLE_FLT_SEL, conf->enter_idle_flt_sel) | 566 + FIELD_PREP(LNaRGCR1_EXIT_IDLE_FLT_SEL, conf->exit_idle_flt_sel) | 567 + FIELD_PREP(LNaRGCR1_DATA_LOST_TH_SEL, conf->data_lost_th_sel), 568 + LNaRGCR1_ENTER_IDLE_FLT_SEL | 569 + LNaRGCR1_EXIT_IDLE_FLT_SEL | 570 + LNaRGCR1_DATA_LOST_TH_SEL); 571 + 572 + lynx_28g_lane_rmw(lane, LNaRECR0, 573 + FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV_EN, conf->gk2ovd_en) | 574 + FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV_EN, conf->gk3ovd_en) | 575 + FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV_EN, conf->gk4ovd_en) | 576 + FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV, conf->gk2ovd) | 577 + FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV, conf->gk3ovd) | 578 + FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV, conf->gk4ovd), 579 + LNaRECR0_EQ_GAINK2_HF_OV | 580 + LNaRECR0_EQ_GAINK3_MF_OV | 581 + LNaRECR0_EQ_GAINK4_LF_OV | 582 + LNaRECR0_EQ_GAINK2_HF_OV_EN | 583 + LNaRECR0_EQ_GAINK3_MF_OV_EN | 584 + LNaRECR0_EQ_GAINK4_LF_OV_EN); 585 + 586 + lynx_28g_lane_rmw(lane, LNaRECR1, 587 + FIELD_PREP(LNaRECR1_EQ_OFFSET_OV, conf->eq_offset_ovd) | 588 + FIELD_PREP(LNaRECR1_EQ_OFFSET_OV_EN, conf->eq_offset_ovd_en), 589 + LNaRECR1_EQ_OFFSET_OV | 590 + LNaRECR1_EQ_OFFSET_OV_EN); 591 + 592 + lynx_28g_lane_rmw(lane, LNaRECR2, 593 + FIELD_PREP(LNaRECR2_EQ_OFFSET_RNG_DBL, conf->eq_offset_rng_dbl) | 594 + FIELD_PREP(LNaRECR2_EQ_BLW_SEL, conf->eq_blw_sel) | 595 + FIELD_PREP(LNaRECR2_EQ_BOOST, conf->eq_boost) | 596 + FIELD_PREP(LNaRECR2_SPARE_IN, conf->spare_in), 597 + LNaRECR2_EQ_OFFSET_RNG_DBL | 598 + LNaRECR2_EQ_BLW_SEL | 599 + LNaRECR2_EQ_BOOST | 600 + LNaRECR2_SPARE_IN); 601 + 602 + lynx_28g_lane_rmw(lane, LNaRSCCR0, 603 + FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_D1R, conf->smp_autoz_d1r) | 604 + FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_EG1R, conf->smp_autoz_eg1r), 605 + LNaRSCCR0_SMP_AUTOZ_D1R | 606 + LNaRSCCR0_SMP_AUTOZ_EG1R); 607 + 608 + lynx_28g_lane_write(lane, LNaRCCR0, conf->rccr0); 609 + lynx_28g_lane_write(lane, LNaTTLCR0, conf->ttlcr0); 610 + } 611 + 612 + static int lynx_28g_lane_disable_pcvt(struct lynx_28g_lane *lane, 613 + enum lynx_lane_mode lane_mode) 614 + { 615 + struct lynx_28g_priv *priv = lane->priv; 616 + int err; 617 + 618 + spin_lock(&priv->pcc_lock); 619 + 620 + err = lynx_pccr_write(lane, lane_mode, 0); 621 + if (err) 622 + goto out; 623 + 624 + switch (lane_mode) { 625 + case LANE_MODE_1000BASEX_SGMII: 626 + err = lynx_pcvt_rmw(lane, lane_mode, CR(1), 0, 627 + SGMIIaCR1_SGPCS_EN); 628 + break; 629 + default: 630 + err = 0; 631 + } 632 + 633 + out: 634 + spin_unlock(&priv->pcc_lock); 635 + 636 + return err; 637 + } 638 + 639 + static int lynx_28g_lane_enable_pcvt(struct lynx_28g_lane *lane, 640 + enum lynx_lane_mode lane_mode) 641 + { 642 + struct lynx_28g_priv *priv = lane->priv; 643 + u32 val; 644 + int err; 645 + 646 + spin_lock(&priv->pcc_lock); 647 + 648 + switch (lane_mode) { 649 + case LANE_MODE_1000BASEX_SGMII: 650 + err = lynx_pcvt_rmw(lane, lane_mode, CR(1), SGMIIaCR1_SGPCS_EN, 651 + SGMIIaCR1_SGPCS_EN); 652 + break; 653 + default: 654 + err = 0; 655 + } 656 + 657 + val = 0; 658 + 659 + switch (lane_mode) { 660 + case LANE_MODE_1000BASEX_SGMII: 661 + val |= PCC8_SGMIIa_CFG; 662 + break; 663 + case LANE_MODE_10GBASER: 664 + val |= PCCC_SXGMIIn_XFI; 665 + fallthrough; 666 + case LANE_MODE_USXGMII: 667 + val |= PCCC_SXGMIIn_CFG; 668 + break; 669 + default: 670 + break; 671 + } 672 + 673 + err = lynx_pccr_write(lane, lane_mode, val); 674 + 675 + spin_unlock(&priv->pcc_lock); 676 + 677 + return err; 651 678 } 652 679 653 680 static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) ··· 941 396 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 942 397 struct lynx_28g_priv *priv = lane->priv; 943 398 int powered_up = lane->powered_up; 399 + enum lynx_lane_mode lane_mode; 944 400 int err = 0; 945 401 946 402 if (mode != PHY_MODE_ETHERNET) 947 403 return -EOPNOTSUPP; 948 404 949 - if (lane->interface == PHY_INTERFACE_MODE_NA) 405 + if (lane->mode == LANE_MODE_UNKNOWN) 950 406 return -EOPNOTSUPP; 951 407 952 - if (!lynx_28g_supports_interface(priv, submode)) 408 + lane_mode = phy_interface_to_lane_mode(submode); 409 + if (!lynx_28g_supports_lane_mode(priv, lane_mode)) 953 410 return -EOPNOTSUPP; 411 + 412 + if (lane_mode == lane->mode) 413 + return 0; 954 414 955 415 /* If the lane is powered up, put the lane into the halt state while 956 416 * the reconfiguration is being done. ··· 963 413 if (powered_up) 964 414 lynx_28g_power_off(phy); 965 415 966 - spin_lock(&priv->pcc_lock); 967 - 968 - switch (submode) { 969 - case PHY_INTERFACE_MODE_SGMII: 970 - case PHY_INTERFACE_MODE_1000BASEX: 971 - lynx_28g_lane_set_sgmii(lane); 972 - break; 973 - case PHY_INTERFACE_MODE_10GBASER: 974 - lynx_28g_lane_set_10gbaser(lane); 975 - break; 976 - default: 977 - err = -EOPNOTSUPP; 416 + err = lynx_28g_lane_disable_pcvt(lane, lane->mode); 417 + if (err) 978 418 goto out; 979 - } 980 419 981 - lane->interface = submode; 420 + lynx_28g_lane_change_proto_conf(lane, lane_mode); 421 + lynx_28g_lane_remap_pll(lane, lane_mode); 422 + WARN_ON(lynx_28g_lane_enable_pcvt(lane, lane_mode)); 423 + 424 + lane->mode = lane_mode; 982 425 983 426 out: 984 - spin_unlock(&priv->pcc_lock); 985 - 986 - /* Power up the lane if necessary */ 987 427 if (powered_up) 988 428 lynx_28g_power_on(phy); 989 429 ··· 985 445 { 986 446 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 987 447 struct lynx_28g_priv *priv = lane->priv; 448 + enum lynx_lane_mode lane_mode; 988 449 989 450 if (mode != PHY_MODE_ETHERNET) 990 451 return -EOPNOTSUPP; 991 452 992 - if (!lynx_28g_supports_interface(priv, submode)) 453 + lane_mode = phy_interface_to_lane_mode(submode); 454 + if (!lynx_28g_supports_lane_mode(priv, lane_mode)) 993 455 return -EOPNOTSUPP; 994 456 995 457 return 0; ··· 1037 495 pll->cr0 = lynx_28g_pll_read(pll, PLLnCR0); 1038 496 pll->cr1 = lynx_28g_pll_read(pll, PLLnCR1); 1039 497 1040 - if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 498 + if (PLLnRSTCTL_DIS(pll->rstctl)) 1041 499 continue; 1042 500 1043 - switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 1044 - case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 1045 - case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 501 + switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) { 502 + case PLLnCR1_FRATE_5G_10GVCO: 503 + case PLLnCR1_FRATE_5G_25GVCO: 1046 504 /* 5GHz clock net */ 1047 - __set_bit(PHY_INTERFACE_MODE_1000BASEX, pll->supported); 1048 - __set_bit(PHY_INTERFACE_MODE_SGMII, pll->supported); 505 + __set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported); 1049 506 break; 1050 - case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 507 + case PLLnCR1_FRATE_10G_20GVCO: 1051 508 /* 10.3125GHz clock net */ 1052 - __set_bit(PHY_INTERFACE_MODE_10GBASER, pll->supported); 509 + __set_bit(LANE_MODE_10GBASER, pll->supported); 510 + __set_bit(LANE_MODE_USXGMII, pll->supported); 1053 511 break; 1054 512 default: 1055 513 /* 6GHz, 12.890625GHz, 8GHz */ ··· 1078 536 } 1079 537 1080 538 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 1081 - if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) { 1082 - lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 539 + if (!(rrstctl & LNaRRSTCTL_CDR_LOCK)) { 540 + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ, 541 + LNaRRSTCTL_RST_REQ); 1083 542 do { 1084 543 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 1085 - } while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 544 + } while (!(rrstctl & LNaRRSTCTL_RST_DONE)); 1086 545 } 1087 546 1088 547 mutex_unlock(&lane->phy->mutex); ··· 1094 551 1095 552 static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane) 1096 553 { 1097 - u32 pss, protocol; 554 + u32 pccr, pss, protocol; 1098 555 1099 556 pss = lynx_28g_lane_read(lane, LNaPSS); 1100 - protocol = LYNX_28G_LNaPSS_TYPE(pss); 557 + protocol = FIELD_GET(LNaPSS_TYPE, pss); 1101 558 switch (protocol) { 1102 - case LYNX_28G_LNaPSS_TYPE_SGMII: 1103 - lane->interface = PHY_INTERFACE_MODE_SGMII; 559 + case LNaPSS_TYPE_SGMII: 560 + lane->mode = LANE_MODE_1000BASEX_SGMII; 1104 561 break; 1105 - case LYNX_28G_LNaPSS_TYPE_XFI: 1106 - lane->interface = PHY_INTERFACE_MODE_10GBASER; 562 + case LNaPSS_TYPE_XFI: 563 + lynx_pccr_read(lane, LANE_MODE_10GBASER, &pccr); 564 + if (pccr & PCCC_SXGMIIn_XFI) 565 + lane->mode = LANE_MODE_10GBASER; 566 + else 567 + lane->mode = LANE_MODE_USXGMII; 1107 568 break; 1108 569 default: 1109 - lane->interface = PHY_INTERFACE_MODE_NA; 570 + lane->mode = LANE_MODE_UNKNOWN; 1110 571 } 1111 572 } 1112 573 ··· 1118 571 const struct of_phandle_args *args) 1119 572 { 1120 573 struct lynx_28g_priv *priv = dev_get_drvdata(dev); 1121 - int idx = args->args[0]; 574 + int idx; 575 + 576 + if (args->args_count == 0) 577 + return of_phy_simple_xlate(dev, args); 578 + else if (args->args_count != 1) 579 + return ERR_PTR(-ENODEV); 580 + 581 + idx = args->args[0]; 1122 582 1123 583 if (WARN_ON(idx >= LYNX_28G_NUM_LANE)) 1124 584 return ERR_PTR(-EINVAL); ··· 1133 579 return priv->lane[idx].phy; 1134 580 } 1135 581 582 + static int lynx_28g_probe_lane(struct lynx_28g_priv *priv, int id, 583 + struct device_node *dn) 584 + { 585 + struct lynx_28g_lane *lane = &priv->lane[id]; 586 + struct phy *phy; 587 + 588 + phy = devm_phy_create(priv->dev, dn, &lynx_28g_ops); 589 + if (IS_ERR(phy)) 590 + return PTR_ERR(phy); 591 + 592 + lane->priv = priv; 593 + lane->phy = phy; 594 + lane->id = id; 595 + phy_set_drvdata(phy, lane); 596 + lynx_28g_lane_read_configuration(lane); 597 + 598 + return 0; 599 + } 600 + 1136 601 static int lynx_28g_probe(struct platform_device *pdev) 1137 602 { 1138 603 struct device *dev = &pdev->dev; 1139 604 struct phy_provider *provider; 1140 605 struct lynx_28g_priv *priv; 1141 - int i; 606 + struct device_node *dn; 607 + int err; 1142 608 1143 - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 609 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1144 610 if (!priv) 1145 611 return -ENOMEM; 1146 - priv->dev = &pdev->dev; 612 + 613 + priv->dev = dev; 614 + dev_set_drvdata(dev, priv); 615 + spin_lock_init(&priv->pcc_lock); 616 + INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); 1147 617 1148 618 priv->base = devm_platform_ioremap_resource(pdev, 0); 1149 619 if (IS_ERR(priv->base)) ··· 1175 597 1176 598 lynx_28g_pll_read_configuration(priv); 1177 599 1178 - for (i = 0; i < LYNX_28G_NUM_LANE; i++) { 1179 - struct lynx_28g_lane *lane = &priv->lane[i]; 1180 - struct phy *phy; 600 + dn = dev_of_node(dev); 601 + if (of_get_child_count(dn)) { 602 + struct device_node *child; 1181 603 1182 - memset(lane, 0, sizeof(*lane)); 604 + for_each_available_child_of_node(dn, child) { 605 + u32 reg; 1183 606 1184 - phy = devm_phy_create(&pdev->dev, NULL, &lynx_28g_ops); 1185 - if (IS_ERR(phy)) 1186 - return PTR_ERR(phy); 607 + /* PHY subnode name must be 'phy'. */ 608 + if (!(of_node_name_eq(child, "phy"))) 609 + continue; 1187 610 1188 - lane->priv = priv; 1189 - lane->phy = phy; 1190 - lane->id = i; 1191 - phy_set_drvdata(phy, lane); 1192 - lynx_28g_lane_read_configuration(lane); 611 + if (of_property_read_u32(child, "reg", &reg)) { 612 + dev_err(dev, "No \"reg\" property for %pOF\n", child); 613 + of_node_put(child); 614 + return -EINVAL; 615 + } 616 + 617 + if (reg >= LYNX_28G_NUM_LANE) { 618 + dev_err(dev, "\"reg\" property out of range for %pOF\n", child); 619 + of_node_put(child); 620 + return -EINVAL; 621 + } 622 + 623 + err = lynx_28g_probe_lane(priv, reg, child); 624 + if (err) { 625 + of_node_put(child); 626 + return err; 627 + } 628 + } 629 + } else { 630 + for (int i = 0; i < LYNX_28G_NUM_LANE; i++) { 631 + err = lynx_28g_probe_lane(priv, i, NULL); 632 + if (err) 633 + return err; 634 + } 1193 635 } 1194 636 1195 - dev_set_drvdata(dev, priv); 1196 - 1197 - spin_lock_init(&priv->pcc_lock); 1198 - INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); 637 + provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); 638 + if (IS_ERR(provider)) 639 + return PTR_ERR(provider); 1199 640 1200 641 queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, 1201 642 msecs_to_jiffies(1000)); 1202 643 1203 - dev_set_drvdata(&pdev->dev, priv); 1204 - provider = devm_of_phy_provider_register(&pdev->dev, lynx_28g_xlate); 1205 - 1206 - return PTR_ERR_OR_ZERO(provider); 644 + return 0; 1207 645 } 1208 646 1209 647 static void lynx_28g_remove(struct platform_device *pdev)
+8 -5
drivers/phy/freescale/phy-fsl-samsung-hdmi.c
··· 570 570 return fract_div_phy; 571 571 } 572 572 573 - static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw, 574 - unsigned long rate, unsigned long *parent_rate) 573 + static int fsl_samsung_hdmi_phy_clk_determine_rate(struct clk_hw *hw, 574 + struct clk_rate_request *req) 575 575 { 576 576 struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw); 577 - const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate); 577 + const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, 578 + req->rate); 578 579 579 580 if (target_settings == NULL) 580 581 return -EINVAL; 581 582 582 583 dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk); 583 - return target_settings->pixclk; 584 + req->rate = target_settings->pixclk; 585 + 586 + return 0; 584 587 } 585 588 586 589 static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw, ··· 602 599 603 600 static const struct clk_ops phy_clk_ops = { 604 601 .recalc_rate = phy_clk_recalc_rate, 605 - .round_rate = fsl_samsung_hdmi_phy_clk_round_rate, 602 + .determine_rate = fsl_samsung_hdmi_phy_clk_determine_rate, 606 603 .set_rate = fsl_samsung_hdmi_phy_clk_set_rate, 607 604 }; 608 605
+1 -1
drivers/phy/marvell/phy-mvebu-cp110-utmi.c
··· 338 338 return -ENOMEM; 339 339 } 340 340 341 - port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1); 341 + port->dr_mode = of_usb_get_dr_mode_by_phy(child, 0); 342 342 if ((port->dr_mode != USB_DR_MODE_HOST) && 343 343 (port->dr_mode != USB_DR_MODE_PERIPHERAL)) { 344 344 dev_err(&pdev->dev,
+4 -4
drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
··· 90 90 usleep_range(80, 100); 91 91 } 92 92 93 - static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, 94 - unsigned long *parent_rate) 93 + static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, 94 + struct clk_rate_request *req) 95 95 { 96 - return rate; 96 + return 0; 97 97 } 98 98 99 99 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, ··· 170 170 .prepare = mtk_hdmi_pll_prepare, 171 171 .unprepare = mtk_hdmi_pll_unprepare, 172 172 .set_rate = mtk_hdmi_pll_set_rate, 173 - .round_rate = mtk_hdmi_pll_round_rate, 173 + .determine_rate = mtk_hdmi_pll_determine_rate, 174 174 .recalc_rate = mtk_hdmi_pll_recalc_rate, 175 175 }; 176 176
+8 -8
drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
··· 118 118 usleep_range(100, 150); 119 119 } 120 120 121 - static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, 122 - unsigned long *parent_rate) 121 + static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, 122 + struct clk_rate_request *req) 123 123 { 124 124 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 125 125 126 - hdmi_phy->pll_rate = rate; 127 - if (rate <= 74250000) 128 - *parent_rate = rate; 126 + hdmi_phy->pll_rate = req->rate; 127 + if (req->rate <= 74250000) 128 + req->best_parent_rate = req->rate; 129 129 else 130 - *parent_rate = rate / 2; 130 + req->best_parent_rate = req->rate / 2; 131 131 132 - return rate; 132 + return 0; 133 133 } 134 134 135 135 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, ··· 223 223 .prepare = mtk_hdmi_pll_prepare, 224 224 .unprepare = mtk_hdmi_pll_unprepare, 225 225 .set_rate = mtk_hdmi_pll_set_rate, 226 - .round_rate = mtk_hdmi_pll_round_rate, 226 + .determine_rate = mtk_hdmi_pll_determine_rate, 227 227 .recalc_rate = mtk_hdmi_pll_recalc_rate, 228 228 }; 229 229
+5 -5
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
··· 418 418 return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate); 419 419 } 420 420 421 - static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, 422 - unsigned long *parent_rate) 421 + static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, 422 + struct clk_rate_request *req) 423 423 { 424 424 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 425 425 426 - hdmi_phy->pll_rate = rate; 427 - return rate; 426 + hdmi_phy->pll_rate = req->rate; 427 + return 0; 428 428 } 429 429 430 430 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, ··· 439 439 .prepare = mtk_hdmi_pll_prepare, 440 440 .unprepare = mtk_hdmi_pll_unprepare, 441 441 .set_rate = mtk_hdmi_pll_set_rate, 442 - .round_rate = mtk_hdmi_pll_round_rate, 442 + .determine_rate = mtk_hdmi_pll_determine_rate, 443 443 .recalc_rate = mtk_hdmi_pll_recalc_rate, 444 444 }; 445 445
+6 -4
drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
··· 237 237 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK); 238 238 } 239 239 240 - static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 241 - unsigned long *prate) 240 + static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw, 241 + struct clk_rate_request *req) 242 242 { 243 - return clamp_val(rate, 50000000, 1250000000); 243 + req->rate = clamp_val(req->rate, 50000000, 1250000000); 244 + 245 + return 0; 244 246 } 245 247 246 248 static const struct clk_ops mtk_mipi_tx_pll_ops = { 247 249 .prepare = mtk_mipi_tx_pll_prepare, 248 250 .unprepare = mtk_mipi_tx_pll_unprepare, 249 - .round_rate = mtk_mipi_tx_pll_round_rate, 251 + .determine_rate = mtk_mipi_tx_pll_determine_rate, 250 252 .set_rate = mtk_mipi_tx_pll_set_rate, 251 253 .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 252 254 };
+6 -4
drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
··· 97 97 mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); 98 98 } 99 99 100 - static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 101 - unsigned long *prate) 100 + static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw, 101 + struct clk_rate_request *req) 102 102 { 103 - return clamp_val(rate, 125000000, 1600000000); 103 + req->rate = clamp_val(req->rate, 125000000, 1600000000); 104 + 105 + return 0; 104 106 } 105 107 106 108 static const struct clk_ops mtk_mipi_tx_pll_ops = { 107 109 .enable = mtk_mipi_tx_pll_enable, 108 110 .disable = mtk_mipi_tx_pll_disable, 109 - .round_rate = mtk_mipi_tx_pll_round_rate, 111 + .determine_rate = mtk_mipi_tx_pll_determine_rate, 110 112 .set_rate = mtk_mipi_tx_pll_set_rate, 111 113 .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 112 114 };
+1 -1
drivers/phy/mediatek/phy-mtk-xfi-tphy.c
··· 353 353 * Disable and unprepare all clocks previously enabled. 354 354 * 355 355 * Return: 356 - * See clk_bulk_prepare_disable(). 356 + * See clk_bulk_disable_unprepare(). 357 357 */ 358 358 static int mtk_xfi_tphy_power_off(struct phy *phy) 359 359 {
+6 -9
drivers/phy/phy-core.c
··· 138 138 static struct phy_provider *of_phy_provider_lookup(struct device_node *node) 139 139 { 140 140 struct phy_provider *phy_provider; 141 - struct device_node *child; 142 141 143 142 list_for_each_entry(phy_provider, &phy_provider_list, list) { 144 143 if (phy_provider->dev->of_node == node) 145 144 return phy_provider; 146 145 147 - for_each_child_of_node(phy_provider->children, child) 148 - if (child == node) { 149 - of_node_put(child); 146 + for_each_child_of_node_scoped(phy_provider->children, child) 147 + if (child == node) 150 148 return phy_provider; 151 - } 152 149 } 153 150 154 151 return ERR_PTR(-EPROBE_DEFER); ··· 187 190 } 188 191 EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync); 189 192 190 - int phy_pm_runtime_put(struct phy *phy) 193 + void phy_pm_runtime_put(struct phy *phy) 191 194 { 192 195 if (!phy) 193 - return 0; 196 + return; 194 197 195 198 if (!pm_runtime_enabled(&phy->dev)) 196 - return -ENOTSUPP; 199 + return; 197 200 198 - return pm_runtime_put(&phy->dev); 201 + pm_runtime_put(&phy->dev); 199 202 } 200 203 EXPORT_SYMBOL_GPL(phy_pm_runtime_put); 201 204
+296
drivers/phy/phy-google-usb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * phy-google-usb.c - Google USB PHY driver 4 + * 5 + * Copyright (C) 2025, Google LLC 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/cleanup.h> 10 + #include <linux/clk.h> 11 + #include <linux/io.h> 12 + #include <linux/kernel.h> 13 + #include <linux/mfd/syscon.h> 14 + #include <linux/module.h> 15 + #include <linux/mutex.h> 16 + #include <linux/of.h> 17 + #include <linux/phy/phy.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/regmap.h> 20 + #include <linux/reset.h> 21 + #include <linux/usb/typec_mux.h> 22 + 23 + #define USBCS_USB2PHY_CFG19_OFFSET 0x0 24 + #define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8) 25 + 26 + #define USBCS_USB2PHY_CFG21_OFFSET 0x8 27 + #define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12) 28 + #define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13) 29 + #define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19) 30 + 31 + #define USBCS_PHY_CFG1_OFFSET 0x28 32 + #define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17) 33 + 34 + enum google_usb_phy_id { 35 + GOOGLE_USB2_PHY, 36 + GOOGLE_USB_PHY_NUM, 37 + }; 38 + 39 + struct google_usb_phy_instance { 40 + struct google_usb_phy *parent; 41 + unsigned int index; 42 + struct phy *phy; 43 + unsigned int num_clks; 44 + struct clk_bulk_data *clks; 45 + unsigned int num_rsts; 46 + struct reset_control_bulk_data *rsts; 47 + }; 48 + 49 + struct google_usb_phy { 50 + struct device *dev; 51 + struct regmap *usb_cfg_regmap; 52 + unsigned int usb2_cfg_offset; 53 + void __iomem *usbdp_top_base; 54 + struct google_usb_phy_instance *insts; 55 + /* 56 + * Protect phy registers from concurrent access, specifically via 57 + * google_usb_set_orientation callback. 58 + */ 59 + struct mutex phy_mutex; 60 + struct typec_switch_dev *sw; 61 + enum typec_orientation orientation; 62 + }; 63 + 64 + static void set_vbus_valid(struct google_usb_phy *gphy) 65 + { 66 + u32 reg; 67 + 68 + if (gphy->orientation == TYPEC_ORIENTATION_NONE) { 69 + reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); 70 + reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID; 71 + writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); 72 + } else { 73 + reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); 74 + reg |= USBCS_PHY_CFG1_SYS_VBUSVALID; 75 + writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); 76 + } 77 + } 78 + 79 + static int google_usb_set_orientation(struct typec_switch_dev *sw, 80 + enum typec_orientation orientation) 81 + { 82 + struct google_usb_phy *gphy = typec_switch_get_drvdata(sw); 83 + 84 + dev_dbg(gphy->dev, "set orientation %d\n", orientation); 85 + 86 + gphy->orientation = orientation; 87 + 88 + if (pm_runtime_suspended(gphy->dev)) 89 + return 0; 90 + 91 + guard(mutex)(&gphy->phy_mutex); 92 + 93 + set_vbus_valid(gphy); 94 + 95 + return 0; 96 + } 97 + 98 + static int google_usb2_phy_init(struct phy *_phy) 99 + { 100 + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy); 101 + struct google_usb_phy *gphy = inst->parent; 102 + u32 reg; 103 + int ret; 104 + 105 + dev_dbg(gphy->dev, "initializing usb2 phy\n"); 106 + 107 + guard(mutex)(&gphy->phy_mutex); 108 + 109 + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg); 110 + reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL; 111 + reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL; 112 + reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0); 113 + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); 114 + 115 + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, &reg); 116 + reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV; 117 + reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368); 118 + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, reg); 119 + 120 + set_vbus_valid(gphy); 121 + 122 + ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks); 123 + if (ret) 124 + return ret; 125 + 126 + ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts); 127 + if (ret) { 128 + clk_bulk_disable_unprepare(inst->num_clks, inst->clks); 129 + return ret; 130 + } 131 + 132 + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg); 133 + reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE; 134 + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); 135 + 136 + return 0; 137 + } 138 + 139 + static int google_usb2_phy_exit(struct phy *_phy) 140 + { 141 + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy); 142 + struct google_usb_phy *gphy = inst->parent; 143 + u32 reg; 144 + 145 + dev_dbg(gphy->dev, "exiting usb2 phy\n"); 146 + 147 + guard(mutex)(&gphy->phy_mutex); 148 + 149 + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg); 150 + reg &= ~USBCS_USB2PHY_CFG21_PHY_ENABLE; 151 + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); 152 + 153 + reset_control_bulk_assert(inst->num_rsts, inst->rsts); 154 + clk_bulk_disable_unprepare(inst->num_clks, inst->clks); 155 + 156 + return 0; 157 + } 158 + 159 + static const struct phy_ops google_usb2_phy_ops = { 160 + .init = google_usb2_phy_init, 161 + .exit = google_usb2_phy_exit, 162 + }; 163 + 164 + static struct phy *google_usb_phy_xlate(struct device *dev, 165 + const struct of_phandle_args *args) 166 + { 167 + struct google_usb_phy *gphy = dev_get_drvdata(dev); 168 + 169 + if (args->args[0] >= GOOGLE_USB_PHY_NUM) { 170 + dev_err(dev, "invalid PHY index requested from DT\n"); 171 + return ERR_PTR(-ENODEV); 172 + } 173 + return gphy->insts[args->args[0]].phy; 174 + } 175 + 176 + static int google_usb_phy_probe(struct platform_device *pdev) 177 + { 178 + struct typec_switch_desc sw_desc = { }; 179 + struct google_usb_phy_instance *inst; 180 + struct phy_provider *phy_provider; 181 + struct device *dev = &pdev->dev; 182 + struct google_usb_phy *gphy; 183 + struct phy *phy; 184 + u32 args[1]; 185 + int ret; 186 + 187 + gphy = devm_kzalloc(dev, sizeof(*gphy), GFP_KERNEL); 188 + if (!gphy) 189 + return -ENOMEM; 190 + 191 + dev_set_drvdata(dev, gphy); 192 + gphy->dev = dev; 193 + 194 + ret = devm_mutex_init(dev, &gphy->phy_mutex); 195 + if (ret) 196 + return ret; 197 + 198 + gphy->usb_cfg_regmap = 199 + syscon_regmap_lookup_by_phandle_args(dev->of_node, 200 + "google,usb-cfg-csr", 201 + ARRAY_SIZE(args), args); 202 + if (IS_ERR(gphy->usb_cfg_regmap)) { 203 + return dev_err_probe(dev, PTR_ERR(gphy->usb_cfg_regmap), 204 + "invalid usb cfg csr\n"); 205 + } 206 + 207 + gphy->usb2_cfg_offset = args[0]; 208 + 209 + gphy->usbdp_top_base = devm_platform_ioremap_resource_byname(pdev, 210 + "usbdp_top"); 211 + if (IS_ERR(gphy->usbdp_top_base)) 212 + return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base), 213 + "invalid usbdp top\n"); 214 + 215 + gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL); 216 + if (!gphy->insts) 217 + return -ENOMEM; 218 + 219 + inst = &gphy->insts[GOOGLE_USB2_PHY]; 220 + inst->parent = gphy; 221 + inst->index = GOOGLE_USB2_PHY; 222 + phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops); 223 + if (IS_ERR(phy)) 224 + return dev_err_probe(dev, PTR_ERR(phy), 225 + "failed to create usb2 phy instance\n"); 226 + inst->phy = phy; 227 + phy_set_drvdata(phy, inst); 228 + 229 + inst->num_clks = 2; 230 + inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL); 231 + if (!inst->clks) 232 + return -ENOMEM; 233 + inst->clks[0].id = "usb2"; 234 + inst->clks[1].id = "usb2_apb"; 235 + ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks); 236 + if (ret) 237 + return dev_err_probe(dev, ret, "failed to get u2 phy clks\n"); 238 + 239 + inst->num_rsts = 2; 240 + inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL); 241 + if (!inst->rsts) 242 + return -ENOMEM; 243 + inst->rsts[0].id = "usb2"; 244 + inst->rsts[1].id = "usb2_apb"; 245 + ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts); 246 + if (ret) 247 + return dev_err_probe(dev, ret, "failed to get u2 phy resets\n"); 248 + 249 + phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate); 250 + if (IS_ERR(phy_provider)) 251 + return dev_err_probe(dev, PTR_ERR(phy_provider), 252 + "failed to register phy provider\n"); 253 + 254 + pm_runtime_enable(dev); 255 + 256 + sw_desc.fwnode = dev_fwnode(dev); 257 + sw_desc.drvdata = gphy; 258 + sw_desc.name = fwnode_get_name(dev_fwnode(dev)); 259 + sw_desc.set = google_usb_set_orientation; 260 + 261 + gphy->sw = typec_switch_register(dev, &sw_desc); 262 + if (IS_ERR(gphy->sw)) 263 + return dev_err_probe(dev, PTR_ERR(gphy->sw), 264 + "failed to register typec switch\n"); 265 + 266 + return 0; 267 + } 268 + 269 + static void google_usb_phy_remove(struct platform_device *pdev) 270 + { 271 + struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev); 272 + 273 + typec_switch_unregister(gphy->sw); 274 + pm_runtime_disable(&pdev->dev); 275 + } 276 + 277 + static const struct of_device_id google_usb_phy_of_match[] = { 278 + { 279 + .compatible = "google,lga-usb-phy", 280 + }, 281 + { } 282 + }; 283 + MODULE_DEVICE_TABLE(of, google_usb_phy_of_match); 284 + 285 + static struct platform_driver google_usb_phy = { 286 + .probe = google_usb_phy_probe, 287 + .remove = google_usb_phy_remove, 288 + .driver = { 289 + .name = "google-usb-phy", 290 + .of_match_table = google_usb_phy_of_match, 291 + } 292 + }; 293 + 294 + module_platform_driver(google_usb_phy); 295 + MODULE_LICENSE("GPL"); 296 + MODULE_DESCRIPTION("Google USB phy driver");
+670
drivers/phy/phy-spacemit-k1-pcie.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver 4 + * 5 + * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/clk.h> 10 + #include <linux/clk-provider.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/kernel.h> 13 + #include <linux/mfd/syscon.h> 14 + #include <linux/module.h> 15 + #include <linux/phy/phy.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + #include <linux/reset.h> 19 + 20 + #include <dt-bindings/phy/phy.h> 21 + 22 + /* 23 + * Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver 24 + * supports their PHYs. 25 + * 26 + * The PHY for PCIe port A is different from the PHYs for ports B and C: 27 + * - It has one lane, while ports B and C have two 28 + * - It is a combo PHY can be used for PCIe or USB 3 29 + * - It can automatically calibrate PCIe TX and RX termination settings 30 + * 31 + * The PHY functionality for PCIe ports B and C is identical: 32 + * - They have two PCIe lanes (but can be restricted to 1 via device tree) 33 + * - They are used for PCIe only 34 + * - They are configured using TX and RX values computed for port A 35 + * 36 + * A given board is designed to use the combo PHY for either PCIe or USB 3. 37 + * Whether the combo PHY is configured for PCIe or USB 3 is specified in 38 + * device tree using a phandle plus an argument. The argument indicates 39 + * the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3). 40 + * 41 + * Each PHY has a reset that it gets and deasserts during initialization. 42 + * Each depends also on other clocks and resets provided by the controller 43 + * hardware (PCIe or USB) it is associated with. The controller drivers 44 + * are required to enable any clocks and de-assert any resets that affect 45 + * PHY operation. In addition each PHY implements an internal PLL, driven 46 + * by an external (24 MHz) oscillator. 47 + * 48 + * PCIe PHYs must be programmed with RX and TX calibration values. The 49 + * combo PHY is the only one that can determine these values. They are 50 + * determined by temporarily enabling the combo PHY in PCIe mode at probe 51 + * time (if necessary). This calibration only needs to be done once, and 52 + * when it has completed the TX and RX values are saved. 53 + * 54 + * To allow the combo PHY to be enabled for calibration, the resets and 55 + * clocks it uses in PCIe mode must be supplied. 56 + */ 57 + 58 + struct k1_pcie_phy { 59 + struct device *dev; /* PHY provider device */ 60 + struct phy *phy; 61 + void __iomem *regs; 62 + u32 pcie_lanes; /* Max (1 or 2) unless limited by DT */ 63 + struct clk *pll; 64 + struct clk_hw pll_hw; /* Private PLL clock */ 65 + 66 + /* The remaining fields are only used for the combo PHY */ 67 + u32 type; /* PHY_TYPE_PCIE or PHY_TYPE_USB3 */ 68 + struct regmap *pmu; /* MMIO regmap (no errors) */ 69 + }; 70 + 71 + #define CALIBRATION_TIMEOUT 500000 /* For combo PHY (usec) */ 72 + #define PLL_TIMEOUT 500000 /* For PHY PLL lock (usec) */ 73 + #define POLL_DELAY 500 /* Time between polls (usec) */ 74 + 75 + /* Selecting the combo PHY operating mode requires APMU regmap access */ 76 + #define SYSCON_APMU "spacemit,apmu" 77 + 78 + /* PMU space, for selecting between PCIe and USB 3 mode (combo PHY only) */ 79 + 80 + #define PMUA_USB_PHY_CTRL0 0x0110 81 + #define COMBO_PHY_SEL BIT(3) /* 0: PCIe; 1: USB 3 */ 82 + 83 + #define PCIE_CLK_RES_CTRL 0x03cc 84 + #define PCIE_APP_HOLD_PHY_RST BIT(30) 85 + 86 + /* PHY register space */ 87 + 88 + /* Offset between lane 0 and lane 1 registers when there are two */ 89 + #define PHY_LANE_OFFSET 0x0400 90 + 91 + /* PHY PLL configuration */ 92 + #define PCIE_PU_ADDR_CLK_CFG 0x0008 93 + #define PLL_READY BIT(0) /* read-only */ 94 + #define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7) 95 + #define TIMER_ADJ_USB 0x2 96 + #define TIMER_ADJ_PCIE 0x6 97 + #define CFG_SW_PHY_INIT_DONE BIT(11) /* We set after PLL config */ 98 + 99 + #define PCIE_RC_DONE_STATUS 0x0018 100 + #define CFG_FORCE_RCV_RETRY BIT(10) /* Used for PCIe */ 101 + 102 + /* PCIe PHY lane calibration; assumes 24MHz input clock */ 103 + #define PCIE_RC_CAL_REG2 0x0020 104 + #define RC_CAL_TOGGLE BIT(22) 105 + #define CLKSEL GENMASK(31, 29) 106 + #define CLKSEL_24M 0x3 107 + 108 + /* Additional PHY PLL configuration (USB 3 and PCIe) */ 109 + #define PCIE_PU_PLL_1 0x0048 110 + #define REF_100_WSSC BIT(12) /* 1: input is 100MHz, SSC */ 111 + #define FREF_SEL GENMASK(15, 13) 112 + #define FREF_24M 0x1 113 + #define SSC_DEP_SEL GENMASK(19, 16) 114 + #define SSC_DEP_NONE 0x0 115 + #define SSC_DEP_5000PPM 0xa 116 + 117 + /* PCIe PHY configuration */ 118 + #define PCIE_PU_PLL_2 0x004c 119 + #define GEN_REF100 BIT(4) /* 1: generate 100MHz clk */ 120 + 121 + #define PCIE_RX_REG1 0x0050 122 + #define EN_RTERM BIT(3) 123 + #define AFE_RTERM_REG GENMASK(11, 8) 124 + 125 + #define PCIE_RX_REG2 0x0054 126 + #define RX_RTERM_SEL BIT(5) /* 0: use AFE_RTERM_REG value */ 127 + 128 + #define PCIE_LTSSM_DIS_ENTRY 0x005c 129 + #define CFG_REFCLK_MODE GENMASK(9, 8) 130 + #define RFCLK_MODE_DRIVER 0x1 131 + #define OVRD_REFCLK_MODE BIT(10) /* 1: use CFG_RFCLK_MODE */ 132 + 133 + #define PCIE_TX_REG1 0x0064 134 + #define TX_RTERM_REG GENMASK(15, 12) 135 + #define TX_RTERM_SEL BIT(25) /* 1: use TX_RTERM_REG */ 136 + 137 + /* Zeroed for the combo PHY operating in USB mode */ 138 + #define USB3_TEST_CTRL 0x0068 139 + 140 + /* PHY calibration values, determined by the combo PHY at probe time */ 141 + #define PCIE_RCAL_RESULT 0x0084 /* Port A PHY only */ 142 + #define RTERM_VALUE_RX GENMASK(3, 0) 143 + #define RTERM_VALUE_TX GENMASK(7, 4) 144 + #define R_TUNE_DONE BIT(10) 145 + 146 + static u32 k1_phy_rterm = ~0; /* Invalid initial value */ 147 + 148 + /* Save the RX and TX receiver termination values */ 149 + static void k1_phy_rterm_set(u32 val) 150 + { 151 + k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX); 152 + } 153 + 154 + static bool k1_phy_rterm_valid(void) 155 + { 156 + /* Valid if no bits outside those we care about are set */ 157 + return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX)); 158 + } 159 + 160 + static u32 k1_phy_rterm_rx(void) 161 + { 162 + return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm); 163 + } 164 + 165 + static u32 k1_phy_rterm_tx(void) 166 + { 167 + return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm); 168 + } 169 + 170 + /* Only the combo PHY has a PMU pointer defined */ 171 + static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy) 172 + { 173 + return !!k1_phy->pmu; 174 + } 175 + 176 + /* The PLL clocks are driven by the external oscillator */ 177 + static const struct clk_parent_data k1_pcie_phy_data[] = { 178 + { .fw_name = "refclk", }, 179 + }; 180 + 181 + static struct k1_pcie_phy *clk_hw_to_k1_phy(struct clk_hw *clk_hw) 182 + { 183 + return container_of(clk_hw, struct k1_pcie_phy, pll_hw); 184 + } 185 + 186 + /* USB mode only works on the combo PHY, which has only one lane */ 187 + static void k1_pcie_phy_pll_prepare_usb(struct k1_pcie_phy *k1_phy) 188 + { 189 + void __iomem *regs = k1_phy->regs; 190 + u32 val; 191 + 192 + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); 193 + val &= ~CFG_INTERNAL_TIMER_ADJ; 194 + val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_USB); 195 + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); 196 + 197 + val = readl(regs + PCIE_PU_PLL_1); 198 + val &= ~SSC_DEP_SEL; 199 + val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_5000PPM); 200 + writel(val, regs + PCIE_PU_PLL_1); 201 + } 202 + 203 + /* Perform PCIe-specific register updates before starting the PLL clock */ 204 + static void k1_pcie_phy_pll_prepare_pcie(struct k1_pcie_phy *k1_phy) 205 + { 206 + void __iomem *regs = k1_phy->regs; 207 + u32 val; 208 + u32 i; 209 + 210 + for (i = 0; i < k1_phy->pcie_lanes; i++) { 211 + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); 212 + val &= ~CFG_INTERNAL_TIMER_ADJ; 213 + val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_PCIE); 214 + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); 215 + 216 + regs += PHY_LANE_OFFSET; /* Next lane */ 217 + } 218 + 219 + regs = k1_phy->regs; 220 + val = readl(regs + PCIE_RC_DONE_STATUS); 221 + val |= CFG_FORCE_RCV_RETRY; 222 + writel(val, regs + PCIE_RC_DONE_STATUS); 223 + 224 + val = readl(regs + PCIE_PU_PLL_1); 225 + val &= ~SSC_DEP_SEL; 226 + val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_NONE); 227 + writel(val, regs + PCIE_PU_PLL_1); 228 + 229 + val = readl(regs + PCIE_PU_PLL_2); 230 + val |= GEN_REF100; /* Enable 100 MHz PLL output clock */ 231 + writel(val, regs + PCIE_PU_PLL_2); 232 + } 233 + 234 + static int k1_pcie_phy_pll_prepare(struct clk_hw *clk_hw) 235 + { 236 + struct k1_pcie_phy *k1_phy = clk_hw_to_k1_phy(clk_hw); 237 + void __iomem *regs = k1_phy->regs; 238 + u32 val; 239 + u32 i; 240 + 241 + if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) 242 + k1_pcie_phy_pll_prepare_usb(k1_phy); 243 + else 244 + k1_pcie_phy_pll_prepare_pcie(k1_phy); 245 + 246 + /* 247 + * Disable 100 MHz input reference with spread-spectrum 248 + * clocking and select the 24 MHz clock input frequency 249 + */ 250 + val = readl(regs + PCIE_PU_PLL_1); 251 + val &= ~REF_100_WSSC; 252 + val &= ~FREF_SEL; 253 + val |= FIELD_PREP(FREF_SEL, FREF_24M); 254 + writel(val, regs + PCIE_PU_PLL_1); 255 + 256 + /* Mark PLL configuration done on all lanes */ 257 + for (i = 0; i < k1_phy->pcie_lanes; i++) { 258 + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); 259 + val |= CFG_SW_PHY_INIT_DONE; 260 + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); 261 + 262 + regs += PHY_LANE_OFFSET; /* Next lane */ 263 + } 264 + 265 + /* 266 + * Wait for indication the PHY PLL is locked. Lanes for ports 267 + * B and C share a PLL, so it's enough to sample just lane 0. 268 + */ 269 + return readl_poll_timeout(k1_phy->regs + PCIE_PU_ADDR_CLK_CFG, 270 + val, val & PLL_READY, 271 + POLL_DELAY, PLL_TIMEOUT); 272 + } 273 + 274 + /* Prepare implies enable, and once enabled, it's always on */ 275 + static const struct clk_ops k1_pcie_phy_pll_ops = { 276 + .prepare = k1_pcie_phy_pll_prepare, 277 + }; 278 + 279 + /* We represent the PHY PLL as a private clock */ 280 + static int k1_pcie_phy_pll_setup(struct k1_pcie_phy *k1_phy) 281 + { 282 + struct clk_hw *hw = &k1_phy->pll_hw; 283 + struct device *dev = k1_phy->dev; 284 + struct clk_init_data init = { }; 285 + char *name; 286 + int ret; 287 + 288 + name = kasprintf(GFP_KERNEL, "pcie%u_phy_pll", k1_phy->phy->id); 289 + if (!name) 290 + return -ENOMEM; 291 + 292 + init.name = name; 293 + init.ops = &k1_pcie_phy_pll_ops; 294 + init.parent_data = k1_pcie_phy_data; 295 + init.num_parents = ARRAY_SIZE(k1_pcie_phy_data); 296 + 297 + hw->init = &init; 298 + 299 + ret = devm_clk_hw_register(dev, hw); 300 + 301 + kfree(name); /* __clk_register() duplicates the name we provide */ 302 + 303 + if (ret) 304 + return ret; 305 + 306 + k1_phy->pll = devm_clk_hw_get_clk(dev, hw, "pll"); 307 + if (IS_ERR(k1_phy->pll)) 308 + return PTR_ERR(k1_phy->pll); 309 + 310 + return 0; 311 + } 312 + 313 + /* Select PCIe or USB 3 mode for the combo PHY. */ 314 + static void k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb) 315 + { 316 + struct regmap *pmu = k1_phy->pmu; 317 + 318 + /* Only change it if it's not already in the desired state */ 319 + if (!regmap_test_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL) == usb) 320 + regmap_assign_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL, usb); 321 + } 322 + 323 + static void k1_pcie_phy_init_pcie(struct k1_pcie_phy *k1_phy) 324 + { 325 + u32 rx_rterm = k1_phy_rterm_rx(); 326 + u32 tx_rterm = k1_phy_rterm_tx(); 327 + void __iomem *regs; 328 + u32 val; 329 + int i; 330 + 331 + /* For the combo PHY, set PHY to PCIe mode */ 332 + if (k1_phy_port_a(k1_phy)) 333 + k1_combo_phy_sel(k1_phy, false); 334 + 335 + regs = k1_phy->regs; 336 + for (i = 0; i < k1_phy->pcie_lanes; i++) { 337 + val = readl(regs + PCIE_RX_REG1); 338 + 339 + /* Set RX analog front-end receiver termination value */ 340 + val &= ~AFE_RTERM_REG; 341 + val |= FIELD_PREP(AFE_RTERM_REG, rx_rterm); 342 + 343 + /* And enable refclock receiver termination */ 344 + val |= EN_RTERM; 345 + writel(val, regs + PCIE_RX_REG1); 346 + 347 + val = readl(regs + PCIE_RX_REG2); 348 + /* Use PCIE_RX_REG1 AFE_RTERM_REG value */ 349 + val &= ~RX_RTERM_SEL; 350 + writel(val, regs + PCIE_RX_REG2); 351 + 352 + val = readl(regs + PCIE_TX_REG1); 353 + 354 + /* Set TX driver termination value */ 355 + val &= ~TX_RTERM_REG; 356 + val |= FIELD_PREP(TX_RTERM_REG, tx_rterm); 357 + 358 + /* Use PCIE_TX_REG1 TX_RTERM_REG value */ 359 + val |= TX_RTERM_SEL; 360 + writel(val, regs + PCIE_TX_REG1); 361 + 362 + /* Set the input clock to 24 MHz, and clear RC_CAL_TOGGLE */ 363 + val = readl(regs + PCIE_RC_CAL_REG2); 364 + val &= CLKSEL; 365 + val |= FIELD_PREP(CLKSEL, CLKSEL_24M); 366 + val &= ~RC_CAL_TOGGLE; 367 + writel(val, regs + PCIE_RC_CAL_REG2); 368 + 369 + /* Now trigger recalibration by setting RC_CAL_TOGGLE again */ 370 + val |= RC_CAL_TOGGLE; 371 + writel(val, regs + PCIE_RC_CAL_REG2); 372 + 373 + val = readl(regs + PCIE_LTSSM_DIS_ENTRY); 374 + /* Override the reference clock; set to refclk driver mode */ 375 + val |= OVRD_REFCLK_MODE; 376 + val &= ~CFG_REFCLK_MODE; 377 + val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER); 378 + writel(val, regs + PCIE_LTSSM_DIS_ENTRY); 379 + 380 + regs += PHY_LANE_OFFSET; /* Next lane */ 381 + } 382 + } 383 + 384 + /* Only called for combo PHY */ 385 + static void k1_pcie_phy_init_usb(struct k1_pcie_phy *k1_phy) 386 + { 387 + k1_combo_phy_sel(k1_phy, true); 388 + 389 + /* We're not doing any testing */ 390 + writel(0, k1_phy->regs + USB3_TEST_CTRL); 391 + } 392 + 393 + static int k1_pcie_phy_init(struct phy *phy) 394 + { 395 + struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); 396 + 397 + /* Note: port type is only valid for port A (both checks needed) */ 398 + if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) 399 + k1_pcie_phy_init_usb(k1_phy); 400 + else 401 + k1_pcie_phy_init_pcie(k1_phy); 402 + 403 + 404 + return clk_prepare_enable(k1_phy->pll); 405 + } 406 + 407 + static int k1_pcie_phy_exit(struct phy *phy) 408 + { 409 + struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); 410 + 411 + clk_disable_unprepare(k1_phy->pll); 412 + 413 + return 0; 414 + } 415 + 416 + static const struct phy_ops k1_pcie_phy_ops = { 417 + .init = k1_pcie_phy_init, 418 + .exit = k1_pcie_phy_exit, 419 + .owner = THIS_MODULE, 420 + }; 421 + 422 + /* 423 + * Get values needed for calibrating PHYs operating in PCIe mode. Only 424 + * the combo PHY is able to do this, and its calibration values are used 425 + * for configuring all PCIe PHYs. 426 + * 427 + * We always need to de-assert the "global" reset on the combo PHY, 428 + * because the USB driver depends on it. If used for PCIe, that driver 429 + * will (also) de-assert this, but by leaving it de-asserted for the 430 + * combo PHY, the USB driver doesn't have to do this. Note: although 431 + * SpacemiT refers to this as the global reset, we name the "phy" reset. 432 + * 433 + * In addition, we guarantee the APP_HOLD_PHY_RESET bit is clear for the 434 + * combo PHY, so the USB driver doesn't have to manage that either. The 435 + * PCIe driver is free to change this bit for normal operation. 436 + * 437 + * Calibration only needs to be done once. It's possible calibration has 438 + * already completed (e.g., it might have happened in the boot loader, or 439 + * -EPROBE_DEFER might result in this function being called again). So we 440 + * check that early too, to avoid doing it more than once. 441 + * 442 + * Otherwise we temporarily power up the PHY using the PCIe app clocks 443 + * and resets, wait for the hardware to indicate calibration is done, 444 + * grab the value, then shut the PHY down again. 445 + */ 446 + static int k1_pcie_combo_phy_calibrate(struct k1_pcie_phy *k1_phy) 447 + { 448 + struct reset_control_bulk_data resets[] = { 449 + { .id = "dbi", }, 450 + { .id = "mstr", }, 451 + { .id = "slv", }, 452 + }; 453 + struct clk_bulk_data clocks[] = { 454 + { .id = "dbi", }, 455 + { .id = "mstr", }, 456 + { .id = "slv", }, 457 + }; 458 + struct device *dev = k1_phy->dev; 459 + int ret = 0; 460 + int val; 461 + 462 + /* Nothing to do if we already set the receiver termination value */ 463 + if (k1_phy_rterm_valid()) 464 + return 0; 465 + 466 + /* 467 + * We also guarantee the APP_HOLD_PHY_RESET bit is clear. We can 468 + * leave this bit clear even if an error happens below. 469 + */ 470 + regmap_assign_bits(k1_phy->pmu, PCIE_CLK_RES_CTRL, 471 + PCIE_APP_HOLD_PHY_RST, false); 472 + 473 + /* If the calibration already completed (e.g. by U-Boot), we're done */ 474 + val = readl(k1_phy->regs + PCIE_RCAL_RESULT); 475 + if (val & R_TUNE_DONE) 476 + goto out_tune_done; 477 + 478 + /* Put the PHY into PCIe mode */ 479 + k1_combo_phy_sel(k1_phy, false); 480 + 481 + /* Get and enable the PCIe app clocks */ 482 + ret = clk_bulk_get(dev, ARRAY_SIZE(clocks), clocks); 483 + if (ret < 0) 484 + goto out_tune_done; 485 + ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); 486 + if (ret) 487 + goto out_put_clocks; 488 + 489 + /* Get the PCIe application resets (not the PHY reset) */ 490 + ret = reset_control_bulk_get_shared(dev, ARRAY_SIZE(resets), resets); 491 + if (ret) 492 + goto out_disable_clocks; 493 + 494 + /* De-assert the PCIe application resets */ 495 + ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets); 496 + if (ret) 497 + goto out_put_resets; 498 + 499 + /* 500 + * This is the core activity here. Wait for the hardware to 501 + * signal that it has completed calibration/tuning. Once it 502 + * has, the register value will contain the values we'll 503 + * use to configure PCIe PHYs. 504 + */ 505 + ret = readl_poll_timeout(k1_phy->regs + PCIE_RCAL_RESULT, 506 + val, val & R_TUNE_DONE, 507 + POLL_DELAY, CALIBRATION_TIMEOUT); 508 + 509 + /* Clean up. We're done with the resets and clocks */ 510 + reset_control_bulk_assert(ARRAY_SIZE(resets), resets); 511 + out_put_resets: 512 + reset_control_bulk_put(ARRAY_SIZE(resets), resets); 513 + out_disable_clocks: 514 + clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); 515 + out_put_clocks: 516 + clk_bulk_put(ARRAY_SIZE(clocks), clocks); 517 + out_tune_done: 518 + /* If we got the value without timing out, set k1_phy_rterm */ 519 + if (!ret) 520 + k1_phy_rterm_set(val); 521 + 522 + return ret; 523 + } 524 + 525 + static struct phy * 526 + k1_pcie_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args) 527 + { 528 + struct k1_pcie_phy *k1_phy = dev_get_drvdata(dev); 529 + u32 type; 530 + 531 + /* The argument specifying the PHY mode is required */ 532 + if (args->args_count != 1) 533 + return ERR_PTR(-EINVAL); 534 + 535 + /* We only support PCIe and USB 3 mode */ 536 + type = args->args[0]; 537 + if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3) 538 + return ERR_PTR(-EINVAL); 539 + 540 + /* This PHY can only be used once */ 541 + if (k1_phy->type != PHY_NONE) 542 + return ERR_PTR(-EBUSY); 543 + 544 + k1_phy->type = type; 545 + 546 + return k1_phy->phy; 547 + } 548 + 549 + /* Use the maximum number of PCIe lanes unless limited by device tree */ 550 + static u32 k1_pcie_num_lanes(struct k1_pcie_phy *k1_phy, bool port_a) 551 + { 552 + struct device *dev = k1_phy->dev; 553 + u32 count = 0; 554 + u32 max; 555 + int ret; 556 + 557 + ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &count); 558 + if (count == 1) 559 + return 1; 560 + 561 + if (count == 2 && !port_a) 562 + return 2; 563 + 564 + max = port_a ? 1 : 2; 565 + if (ret != -EINVAL) 566 + dev_warn(dev, "bad lane count %u for port; using %u\n", 567 + count, max); 568 + 569 + return max; 570 + } 571 + 572 + static int k1_pcie_combo_phy_probe(struct k1_pcie_phy *k1_phy) 573 + { 574 + struct device *dev = k1_phy->dev; 575 + struct regmap *regmap; 576 + int ret; 577 + 578 + /* Setting the PHY mode requires access to the PMU regmap */ 579 + regmap = syscon_regmap_lookup_by_phandle(dev_of_node(dev), SYSCON_APMU); 580 + if (IS_ERR(regmap)) 581 + return dev_err_probe(dev, PTR_ERR(regmap), "failed to get PMU\n"); 582 + k1_phy->pmu = regmap; 583 + 584 + ret = k1_pcie_combo_phy_calibrate(k1_phy); 585 + if (ret) 586 + return dev_err_probe(dev, ret, "calibration failed\n"); 587 + 588 + /* Needed by k1_pcie_combo_phy_xlate(), which also sets k1_phy->type */ 589 + dev_set_drvdata(dev, k1_phy); 590 + 591 + return 0; 592 + } 593 + 594 + static int k1_pcie_phy_probe(struct platform_device *pdev) 595 + { 596 + struct phy *(*xlate)(struct device *dev, 597 + const struct of_phandle_args *args); 598 + struct device *dev = &pdev->dev; 599 + struct reset_control *phy_reset; 600 + struct phy_provider *provider; 601 + struct k1_pcie_phy *k1_phy; 602 + bool probing_port_a; 603 + int ret; 604 + 605 + xlate = of_device_get_match_data(dev); 606 + probing_port_a = xlate == k1_pcie_combo_phy_xlate; 607 + 608 + /* Only the combo PHY can calibrate, so it must probe first */ 609 + if (!k1_phy_rterm_valid() && !probing_port_a) 610 + return -EPROBE_DEFER; 611 + 612 + k1_phy = devm_kzalloc(dev, sizeof(*k1_phy), GFP_KERNEL); 613 + if (!k1_phy) 614 + return -ENOMEM; 615 + k1_phy->dev = dev; 616 + 617 + k1_phy->regs = devm_platform_ioremap_resource(pdev, 0); 618 + if (IS_ERR(k1_phy->regs)) 619 + return dev_err_probe(dev, PTR_ERR(k1_phy->regs), 620 + "error mapping registers\n"); 621 + 622 + /* De-assert the PHY (global) reset and leave it that way */ 623 + phy_reset = devm_reset_control_get_exclusive_deasserted(dev, "phy"); 624 + if (IS_ERR(phy_reset)) 625 + return PTR_ERR(phy_reset); 626 + 627 + if (probing_port_a) { 628 + ret = k1_pcie_combo_phy_probe(k1_phy); 629 + if (ret) 630 + return dev_err_probe(dev, ret, 631 + "error probing combo phy\n"); 632 + } 633 + 634 + k1_phy->pcie_lanes = k1_pcie_num_lanes(k1_phy, probing_port_a); 635 + 636 + k1_phy->phy = devm_phy_create(dev, NULL, &k1_pcie_phy_ops); 637 + if (IS_ERR(k1_phy->phy)) 638 + return dev_err_probe(dev, PTR_ERR(k1_phy->phy), 639 + "error creating phy\n"); 640 + phy_set_drvdata(k1_phy->phy, k1_phy); 641 + 642 + ret = k1_pcie_phy_pll_setup(k1_phy); 643 + if (ret) 644 + return dev_err_probe(dev, ret, "error initializing clock\n"); 645 + 646 + provider = devm_of_phy_provider_register(dev, xlate); 647 + if (IS_ERR(provider)) 648 + return dev_err_probe(dev, PTR_ERR(provider), 649 + "error registering provider\n"); 650 + return 0; 651 + } 652 + 653 + static const struct of_device_id k1_pcie_phy_of_match[] = { 654 + { .compatible = "spacemit,k1-combo-phy", k1_pcie_combo_phy_xlate, }, 655 + { .compatible = "spacemit,k1-pcie-phy", of_phy_simple_xlate, }, 656 + { }, 657 + }; 658 + MODULE_DEVICE_TABLE(of, k1_pcie_phy_of_match); 659 + 660 + static struct platform_driver k1_pcie_phy_driver = { 661 + .probe = k1_pcie_phy_probe, 662 + .driver = { 663 + .of_match_table = k1_pcie_phy_of_match, 664 + .name = "spacemit-k1-pcie-phy", 665 + } 666 + }; 667 + module_platform_driver(k1_pcie_phy_driver); 668 + 669 + MODULE_DESCRIPTION("SpacemiT K1 PCIe and USB 3 PHY driver"); 670 + MODULE_LICENSE("GPL");
+229 -17
drivers/phy/qualcomm/phy-qcom-edp.c
··· 26 26 #include "phy-qcom-qmp-qserdes-com-v4.h" 27 27 #include "phy-qcom-qmp-qserdes-com-v6.h" 28 28 29 + #include "phy-qcom-qmp-qserdes-dp-com-v8.h" 30 + 29 31 /* EDP_PHY registers */ 30 32 #define DP_PHY_CFG 0x0010 31 33 #define DP_PHY_CFG_1 0x0014 32 34 #define DP_PHY_PD_CTL 0x001c 33 35 #define DP_PHY_MODE 0x0020 34 36 35 - #define DP_AUX_CFG_SIZE 10 37 + #define DP_AUX_CFG_SIZE 13 36 38 #define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n))) 37 39 38 40 #define DP_PHY_AUX_INTERRUPT_MASK 0x0058 ··· 78 76 int (*com_power_on)(const struct qcom_edp *edp); 79 77 int (*com_resetsm_cntrl)(const struct qcom_edp *edp); 80 78 int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp); 79 + int (*com_clk_fwd_cfg)(const struct qcom_edp *edp); 81 80 int (*com_configure_pll)(const struct qcom_edp *edp); 82 81 int (*com_configure_ssc)(const struct qcom_edp *edp); 83 82 }; ··· 86 83 struct qcom_edp_phy_cfg { 87 84 bool is_edp; 88 85 const u8 *aux_cfg; 86 + const u8 *vco_div_cfg; 89 87 const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg; 90 88 const struct phy_ver_ops *ver_ops; 91 89 }; ··· 107 103 108 104 struct phy_configure_opts_dp dp_opts; 109 105 110 - struct clk_bulk_data clks[2]; 106 + struct clk_bulk_data *clks; 107 + int num_clks; 108 + 111 109 struct regulator_bulk_data supplies[2]; 112 110 113 111 bool is_edp; ··· 185 179 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3, 186 180 }; 187 181 188 - static const u8 edp_phy_aux_cfg_v4[10] = { 189 - 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 182 + static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = { 183 + 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, 184 + }; 185 + 186 + static const u8 edp_phy_vco_div_cfg_v4[4] = { 187 + 0x01, 0x01, 0x02, 0x00, 190 188 }; 191 189 192 190 static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = { ··· 214 204 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5, 215 205 }; 216 206 217 - static const u8 edp_phy_aux_cfg_v5[10] = { 218 - 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 207 + static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = { 208 + 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, 209 + }; 210 + 211 + static const u8 edp_phy_aux_cfg_v8[DP_AUX_CFG_SIZE] = { 212 + 0x00, 0x00, 0xa0, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x04, 213 + }; 214 + 215 + static const u8 edp_phy_vco_div_cfg_v8[4] = { 216 + 0x00, 0x00, 0x02, 0x01, 219 217 }; 220 218 221 219 static int qcom_edp_phy_init(struct phy *phy) ··· 236 218 if (ret) 237 219 return ret; 238 220 239 - ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks); 221 + ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks); 240 222 if (ret) 241 223 goto out_disable_supplies; 242 224 243 225 memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg)); 226 + 227 + ret = edp->cfg->ver_ops->com_clk_fwd_cfg(edp); 228 + if (ret) 229 + return ret; 244 230 245 231 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 246 232 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, ··· 365 343 366 344 switch (dp_opts->link_rate) { 367 345 case 1620: 368 - vco_div = 0x1; 346 + vco_div = edp->cfg->vco_div_cfg[0]; 369 347 *pixel_freq = 1620000000UL / 2; 370 348 break; 371 349 372 350 case 2700: 373 - vco_div = 0x1; 351 + vco_div = edp->cfg->vco_div_cfg[1]; 374 352 *pixel_freq = 2700000000UL / 2; 375 353 break; 376 354 377 355 case 5400: 378 - vco_div = 0x2; 356 + vco_div = edp->cfg->vco_div_cfg[2]; 379 357 *pixel_freq = 5400000000UL / 4; 380 358 break; 381 359 382 360 case 8100: 383 - vco_div = 0x0; 361 + vco_div = edp->cfg->vco_div_cfg[3]; 384 362 *pixel_freq = 8100000000UL / 6; 385 363 break; 386 364 ··· 416 394 417 395 return readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 418 396 val, val & BIT(0), 500, 10000); 397 + } 398 + 399 + static int qcom_edp_com_clk_fwd_cfg_v4(const struct qcom_edp *edp) 400 + { 401 + return 0; 419 402 } 420 403 421 404 static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp) ··· 555 528 .com_power_on = qcom_edp_phy_power_on_v4, 556 529 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, 557 530 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, 531 + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, 558 532 .com_configure_pll = qcom_edp_com_configure_pll_v4, 559 533 .com_configure_ssc = qcom_edp_com_configure_ssc_v4, 560 534 }; ··· 563 535 static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = { 564 536 .is_edp = false, 565 537 .aux_cfg = edp_phy_aux_cfg_v5, 538 + .vco_div_cfg = edp_phy_vco_div_cfg_v4, 566 539 .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5, 567 540 .ver_ops = &qcom_edp_phy_ops_v4, 568 541 }; 569 542 570 543 static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { 571 544 .aux_cfg = edp_phy_aux_cfg_v4, 545 + .vco_div_cfg = edp_phy_vco_div_cfg_v4, 572 546 .ver_ops = &qcom_edp_phy_ops_v4, 573 547 }; 574 548 575 549 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { 576 550 .aux_cfg = edp_phy_aux_cfg_v4, 551 + .vco_div_cfg = edp_phy_vco_div_cfg_v4, 577 552 .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 578 553 .ver_ops = &qcom_edp_phy_ops_v4, 579 554 }; ··· 584 553 static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { 585 554 .is_edp = true, 586 555 .aux_cfg = edp_phy_aux_cfg_v4, 556 + .vco_div_cfg = edp_phy_vco_div_cfg_v4, 587 557 .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 588 558 .ver_ops = &qcom_edp_phy_ops_v4, 589 559 }; ··· 758 726 .com_power_on = qcom_edp_phy_power_on_v6, 759 727 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6, 760 728 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6, 729 + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, 761 730 .com_configure_pll = qcom_edp_com_configure_pll_v6, 762 731 .com_configure_ssc = qcom_edp_com_configure_ssc_v6, 763 732 }; 764 733 765 734 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = { 766 735 .aux_cfg = edp_phy_aux_cfg_v4, 736 + .vco_div_cfg = edp_phy_vco_div_cfg_v4, 767 737 .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 768 738 .ver_ops = &qcom_edp_phy_ops_v6, 739 + }; 740 + 741 + static int qcom_edp_com_configure_ssc_v8(const struct qcom_edp *edp) 742 + { 743 + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 744 + u32 step1; 745 + u32 step2; 746 + 747 + switch (dp_opts->link_rate) { 748 + case 1620: 749 + case 2700: 750 + case 8100: 751 + step1 = 0x5b; 752 + step2 = 0x02; 753 + break; 754 + 755 + case 5400: 756 + step1 = 0x5b; 757 + step2 = 0x02; 758 + break; 759 + 760 + default: 761 + /* Other link rates aren't supported */ 762 + return -EINVAL; 763 + } 764 + 765 + writel(0x01, edp->pll + DP_QSERDES_V8_COM_SSC_EN_CENTER); 766 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_SSC_ADJ_PER1); 767 + writel(0x6b, edp->pll + DP_QSERDES_V8_COM_SSC_PER1); 768 + writel(0x02, edp->pll + DP_QSERDES_V8_COM_SSC_PER2); 769 + writel(step1, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0); 770 + writel(step2, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0); 771 + 772 + return 0; 773 + } 774 + 775 + static int qcom_edp_com_configure_pll_v8(const struct qcom_edp *edp) 776 + { 777 + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 778 + u32 div_frac_start2_mode0; 779 + u32 div_frac_start3_mode0; 780 + u32 dec_start_mode0; 781 + u32 lock_cmp1_mode0; 782 + u32 lock_cmp2_mode0; 783 + u32 code1_mode0; 784 + u32 code2_mode0; 785 + u32 hsclk_sel; 786 + 787 + switch (dp_opts->link_rate) { 788 + case 1620: 789 + hsclk_sel = 0x5; 790 + dec_start_mode0 = 0x34; 791 + div_frac_start2_mode0 = 0xc0; 792 + div_frac_start3_mode0 = 0x0b; 793 + lock_cmp1_mode0 = 0x37; 794 + lock_cmp2_mode0 = 0x04; 795 + code1_mode0 = 0x71; 796 + code2_mode0 = 0x0c; 797 + break; 798 + 799 + case 2700: 800 + hsclk_sel = 0x3; 801 + dec_start_mode0 = 0x34; 802 + div_frac_start2_mode0 = 0xc0; 803 + div_frac_start3_mode0 = 0x0b; 804 + lock_cmp1_mode0 = 0x07; 805 + lock_cmp2_mode0 = 0x07; 806 + code1_mode0 = 0x71; 807 + code2_mode0 = 0x0c; 808 + break; 809 + 810 + case 5400: 811 + case 8100: 812 + hsclk_sel = 0x2; 813 + dec_start_mode0 = 0x4f; 814 + div_frac_start2_mode0 = 0xa0; 815 + div_frac_start3_mode0 = 0x01; 816 + lock_cmp1_mode0 = 0x18; 817 + lock_cmp2_mode0 = 0x15; 818 + code1_mode0 = 0x14; 819 + code2_mode0 = 0x25; 820 + break; 821 + 822 + default: 823 + /* Other link rates aren't supported */ 824 + return -EINVAL; 825 + } 826 + 827 + writel(0x01, edp->pll + DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL); 828 + writel(0x3b, edp->pll + DP_QSERDES_V8_COM_SYSCLK_EN_SEL); 829 + writel(0x02, edp->pll + DP_QSERDES_V8_COM_SYS_CLK_CTRL); 830 + writel(0x0c, edp->pll + DP_QSERDES_V8_COM_CLK_ENABLE1); 831 + writel(0x06, edp->pll + DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE); 832 + writel(0x30, edp->pll + DP_QSERDES_V8_COM_CLK_SELECT); 833 + writel(hsclk_sel, edp->pll + DP_QSERDES_V8_COM_HSCLK_SEL_1); 834 + writel(0x07, edp->pll + DP_QSERDES_V8_COM_PLL_IVCO); 835 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP_EN); 836 + writel(0x36, edp->pll + DP_QSERDES_V8_COM_PLL_CCTRL_MODE0); 837 + writel(0x16, edp->pll + DP_QSERDES_V8_COM_PLL_RCTRL_MODE0); 838 + writel(0x06, edp->pll + DP_QSERDES_V8_COM_CP_CTRL_MODE0); 839 + writel(dec_start_mode0, edp->pll + DP_QSERDES_V8_COM_DEC_START_MODE0); 840 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0); 841 + writel(div_frac_start2_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0); 842 + writel(div_frac_start3_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0); 843 + writel(0x96, edp->pll + DP_QSERDES_V8_COM_CMN_CONFIG_1); 844 + writel(0x3f, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0); 845 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0); 846 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_MAP); 847 + writel(lock_cmp1_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP1_MODE0); 848 + writel(lock_cmp2_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP2_MODE0); 849 + 850 + writel(0x0a, edp->pll + DP_QSERDES_V8_COM_BG_TIMER); 851 + writel(0x0a, edp->pll + DP_QSERDES_V8_COM_CORECLK_DIV_MODE0); 852 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_CTRL); 853 + writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); 854 + writel(0x00, edp->pll + DP_QSERDES_V8_COM_CORE_CLK_EN); 855 + writel(0xa0, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE1_MODE0); 856 + writel(0x01, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE2_MODE0); 857 + 858 + writel(code1_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0); 859 + writel(code2_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0); 860 + 861 + return 0; 862 + } 863 + 864 + 865 + static int qcom_edp_phy_com_resetsm_cntrl_v8(const struct qcom_edp *edp) 866 + { 867 + u32 val; 868 + 869 + writel(0x20, edp->pll + DP_QSERDES_V8_COM_RESETSM_CNTRL); 870 + 871 + return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_C_READY_STATUS, 872 + val, val & BIT(0), 500, 10000); 873 + } 874 + 875 + static int qcom_edp_com_clk_fwd_cfg_v8(const struct qcom_edp *edp) 876 + { 877 + writel(0x3f, edp->pll + DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1); 878 + 879 + return 0; 880 + } 881 + 882 + static int qcom_edp_com_bias_en_clkbuflr_v8(const struct qcom_edp *edp) 883 + { 884 + /* Turn on BIAS current for PHY/PLL */ 885 + writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); 886 + 887 + return 0; 888 + } 889 + 890 + static int qcom_edp_phy_power_on_v8(const struct qcom_edp *edp) 891 + { 892 + u32 val; 893 + 894 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 895 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 896 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 897 + edp->edp + DP_PHY_PD_CTL); 898 + writel(0xfc, edp->edp + DP_PHY_MODE); 899 + 900 + return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_CMN_STATUS, 901 + val, val & BIT(7), 5, 200); 902 + } 903 + 904 + static const struct phy_ver_ops qcom_edp_phy_ops_v8 = { 905 + .com_power_on = qcom_edp_phy_power_on_v8, 906 + .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v8, 907 + .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v8, 908 + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v8, 909 + .com_configure_pll = qcom_edp_com_configure_pll_v8, 910 + .com_configure_ssc = qcom_edp_com_configure_ssc_v8, 911 + }; 912 + 913 + static struct qcom_edp_phy_cfg glymur_phy_cfg = { 914 + .aux_cfg = edp_phy_aux_cfg_v8, 915 + .vco_div_cfg = edp_phy_vco_div_cfg_v8, 916 + .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5, 917 + .ver_ops = &qcom_edp_phy_ops_v8, 769 918 }; 770 919 771 920 static int qcom_edp_phy_power_on(struct phy *phy) ··· 1098 885 { 1099 886 struct qcom_edp *edp = phy_get_drvdata(phy); 1100 887 1101 - clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks); 888 + clk_bulk_disable_unprepare(edp->num_clks, edp->clks); 1102 889 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 1103 890 1104 891 return 0; ··· 1305 1092 if (IS_ERR(edp->pll)) 1306 1093 return PTR_ERR(edp->pll); 1307 1094 1308 - edp->clks[0].id = "aux"; 1309 - edp->clks[1].id = "cfg_ahb"; 1310 - ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks); 1311 - if (ret) 1312 - return ret; 1095 + edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks); 1096 + if (edp->num_clks < 0) 1097 + return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n"); 1313 1098 1314 1099 edp->supplies[0].supply = "vdda-phy"; 1315 1100 edp->supplies[1].supply = "vdda-pll"; ··· 1344 1133 } 1345 1134 1346 1135 static const struct of_device_id qcom_edp_phy_match_table[] = { 1136 + { .compatible = "qcom,glymur-dp-phy", .data = &glymur_phy_cfg, }, 1347 1137 { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, }, 1348 1138 { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, }, 1349 1139 { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
+40
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
··· 37 37 #define EUSB2_TUNE_EUSB_EQU 0x5A 38 38 #define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B 39 39 40 + static const int squelch_detector[] = { 41 + [0] = -6000, 42 + [1] = -5000, 43 + [2] = -4000, 44 + [3] = -3000, 45 + [4] = -2000, 46 + [5] = -1000, 47 + [6] = 0, 48 + [7] = 1000, 49 + }; 50 + 40 51 struct eusb2_repeater_init_tbl_reg { 41 52 unsigned int reg; 42 53 unsigned int value; ··· 86 75 { EUSB2_TUNE_USB2_PREEM, 0x2 }, 87 76 }; 88 77 78 + static const struct eusb2_repeater_init_tbl_reg smb2370_init_tbl[] = { 79 + { EUSB2_TUNE_IUSB2, 0x4 }, 80 + { EUSB2_TUNE_SQUELCH_U, 0x3 }, 81 + { EUSB2_TUNE_USB2_SLEW, 0x7 }, 82 + { EUSB2_TUNE_USB2_PREEM, 0x0 }, 83 + }; 84 + 89 85 static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { 90 86 .init_tbl = pm8550b_init_tbl, 91 87 .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl), ··· 111 93 static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { 112 94 .init_tbl = smb2360_init_tbl, 113 95 .init_tbl_num = ARRAY_SIZE(smb2360_init_tbl), 96 + .vreg_list = pm8550b_vreg_l, 97 + .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 98 + }; 99 + 100 + static const struct eusb2_repeater_cfg smb2370_eusb2_cfg = { 101 + .init_tbl = smb2370_init_tbl, 102 + .init_tbl_num = ARRAY_SIZE(smb2370_init_tbl), 114 103 .vreg_list = pm8550b_vreg_l, 115 104 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 116 105 }; ··· 145 120 struct regmap *regmap = rptr->regmap; 146 121 u32 base = rptr->base; 147 122 u32 poll_val; 123 + s32 dt_val; 148 124 int ret; 125 + int i; 149 126 u8 val; 150 127 151 128 ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs); ··· 173 146 174 147 if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val)) 175 148 regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val); 149 + 150 + if (!of_property_read_s32(np, "qcom,squelch-detector-bp", &dt_val)) { 151 + for (i = 0; i < ARRAY_SIZE(squelch_detector); i++) { 152 + if (squelch_detector[i] == dt_val) { 153 + regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, i); 154 + break; 155 + } 156 + } 157 + } 176 158 177 159 /* Wait for status OK */ 178 160 ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, ··· 313 277 { 314 278 .compatible = "qcom,smb2360-eusb2-repeater", 315 279 .data = &smb2360_eusb2_cfg, 280 + }, 281 + { 282 + .compatible = "qcom,smb2370-eusb2-repeater", 283 + .data = &smb2370_eusb2_cfg, 316 284 }, 317 285 { }, 318 286 };
+675 -8
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
··· 30 30 #include "phy-qcom-qmp-common.h" 31 31 32 32 #include "phy-qcom-qmp.h" 33 + #include "phy-qcom-qmp-pcs-aon-v6.h" 34 + #include "phy-qcom-qmp-pcs-aon-v8.h" 33 35 #include "phy-qcom-qmp-pcs-misc-v3.h" 36 + #include "phy-qcom-qmp-pcs-misc-v4.h" 37 + #include "phy-qcom-qmp-pcs-misc-v5.h" 38 + #include "phy-qcom-qmp-pcs-misc-v8.h" 34 39 #include "phy-qcom-qmp-pcs-usb-v4.h" 35 40 #include "phy-qcom-qmp-pcs-usb-v5.h" 36 41 #include "phy-qcom-qmp-pcs-usb-v6.h" ··· 48 43 #include "phy-qcom-qmp-dp-phy-v4.h" 49 44 #include "phy-qcom-qmp-dp-phy-v5.h" 50 45 #include "phy-qcom-qmp-dp-phy-v6.h" 46 + #include "phy-qcom-qmp-dp-phy-v8.h" 47 + 48 + #include "phy-qcom-qmp-usb43-pcs-v8.h" 51 49 52 50 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */ 53 51 /* DP PHY soft reset */ ··· 69 61 /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */ 70 62 #define SW_PORTSELECT_VAL BIT(0) 71 63 #define SW_PORTSELECT_MUX BIT(1) 64 + #define INVERT_CC_POLARITY BIT(2) 72 65 73 66 #define PHY_INIT_COMPLETE_TIMEOUT 10000 74 67 ··· 88 79 QPHY_PCS_AUTONOMOUS_MODE_CTRL, 89 80 QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, 90 81 QPHY_PCS_POWER_DOWN_CONTROL, 82 + QPHY_PCS_CLAMP_ENABLE, 91 83 92 84 QPHY_COM_RESETSM_CNTRL, 93 85 QPHY_COM_C_READY_STATUS, ··· 104 94 QPHY_TX_HIGHZ_DRVR_EN, 105 95 QPHY_TX_TRANSCEIVER_BIAS_EN, 106 96 97 + QPHY_AON_TOGGLE_ENABLE, 98 + QPHY_DP_AON_TOGGLE_ENABLE, 107 99 /* Keep last to ensure regs_layout arrays are properly initialized */ 108 100 QPHY_LAYOUT_SIZE 109 101 }; ··· 117 105 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL, 118 106 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, 119 107 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, 108 + 109 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V3_PCS_MISC_CLAMP_ENABLE, 120 110 121 111 [QPHY_COM_RESETSM_CNTRL] = QSERDES_V3_COM_RESETSM_CNTRL, 122 112 [QPHY_COM_C_READY_STATUS] = QSERDES_V3_COM_C_READY_STATUS, ··· 145 131 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL, 146 132 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, 147 133 134 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V4_PCS_MISC_CLAMP_ENABLE, 135 + 148 136 [QPHY_COM_RESETSM_CNTRL] = QSERDES_V4_COM_RESETSM_CNTRL, 149 137 [QPHY_COM_C_READY_STATUS] = QSERDES_V4_COM_C_READY_STATUS, 150 138 [QPHY_COM_CMN_STATUS] = QSERDES_V4_COM_CMN_STATUS, ··· 171 155 /* In PCS_USB */ 172 156 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL, 173 157 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, 158 + 159 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V5_PCS_MISC_CLAMP_ENABLE, 174 160 175 161 [QPHY_COM_RESETSM_CNTRL] = QSERDES_V5_COM_RESETSM_CNTRL, 176 162 [QPHY_COM_C_READY_STATUS] = QSERDES_V5_COM_C_READY_STATUS, ··· 199 181 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, 200 182 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, 201 183 184 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, 185 + 202 186 [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, 203 187 [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, 204 188 [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, ··· 225 205 /* In PCS_USB */ 226 206 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, 227 207 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, 208 + 209 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, 228 210 229 211 [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, 230 212 [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, ··· 266 244 [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_TX_TX_EMP_POST1_LVL, 267 245 [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_TX_HIGHZ_DRVR_EN, 268 246 [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_TX_TRANSCEIVER_BIAS_EN, 247 + }; 248 + 249 + static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = { 250 + [QPHY_SW_RESET] = QPHY_V8_USB43_PCS_SW_RESET, 251 + [QPHY_START_CTRL] = QPHY_V8_USB43_PCS_START_CONTROL, 252 + [QPHY_PCS_STATUS] = QPHY_V8_USB43_PCS_PCS_STATUS1, 253 + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL, 254 + 255 + /* In PCS_USB */ 256 + [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V8_PCS_USB_AUTONOMOUS_MODE_CTRL, 257 + [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V8_PCS_USB_LFPS_RXTERM_IRQ_CLEAR, 258 + 259 + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE, 260 + [QPHY_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE, 261 + [QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE, 262 + 263 + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V8_COM_RESETSM_CNTRL, 264 + [QPHY_COM_C_READY_STATUS] = QSERDES_V8_COM_C_READY_STATUS, 265 + [QPHY_COM_CMN_STATUS] = QSERDES_V8_COM_CMN_STATUS, 266 + [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, 267 + 268 + [QPHY_DP_PHY_STATUS] = QSERDES_V8_DP_PHY_STATUS, 269 + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V8_DP_PHY_VCO_DIV, 270 + 271 + [QPHY_TX_TX_DRV_LVL] = QSERDES_V8_LALB_TX0_DRV_LVL, 272 + [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_LALB_TX0_EMP_POST1_LVL, 273 + [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_LALB_HIGHZ_DRVR_EN, 274 + [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 275 + }; 276 + 277 + static const struct qmp_phy_init_tbl glymur_usb43dp_serdes_tbl[] = { 278 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1, 0xe1), 279 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1, 0x01), 280 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE1, 0x06), 281 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x16), 282 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x36), 283 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1, 0x02), 284 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1, 0x1a), 285 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1, 0x41), 286 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE1, 0x41), 287 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1, 0x00), 288 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1, 0xab), 289 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1, 0xaa), 290 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1, 0x01), 291 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x13), 292 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), 293 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1, 0x4d), 294 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1, 0x03), 295 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x95), 296 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e), 297 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x4b), 298 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), 299 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0xe1), 300 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x01), 301 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), 302 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), 303 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), 304 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x05), 305 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x0a), 306 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x1a), 307 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x41), 308 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0, 0x00), 309 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0xab), 310 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xaa), 311 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), 312 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), 313 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 314 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0x4d), 315 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x03), 316 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), 317 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), 318 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x62), 319 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), 320 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x0a), 321 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x0f), 322 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO_MODE1, 0x0f), 323 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x1a), 324 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x04), 325 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_CFG, 0x04), 326 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), 327 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x14), 328 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0xa0), 329 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x76), 330 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x0a), 331 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x01), 332 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO, 0x40), 333 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), 334 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_2, 0x01), 335 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), 336 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x05), 337 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x33), 338 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xaf), 339 + }; 340 + 341 + static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_misc_tbl[] = { 342 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1, 0x01), 343 + }; 344 + 345 + static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_tbl[] = { 346 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1, 0xc4), 347 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2, 0x89), 348 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3, 0x20), 349 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6, 0x13), 350 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1, 0x21), 351 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_SIGDET_LVL, 0x55), 352 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), 353 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), 354 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME, 0xa4), 355 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_CONFIG, 0x0a), 356 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_DLY_TIME, 0x04), 357 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1, 0xd4), 358 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2, 0x30), 359 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG, 0x0c), 360 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG1, 0x4b), 361 + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG5, 0x10), 362 + }; 363 + 364 + static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_usb_tbl[] = { 365 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), 366 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), 367 + }; 368 + 369 + static const struct qmp_phy_init_tbl glymur_usb43dp_lalb_tbl[] = { 370 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x81), 371 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0d), 372 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1, 0x00), 373 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2, 0x00), 374 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3, 0x80), 375 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4, 0x8D), 376 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x13), 377 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0c), 378 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x00), 379 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x11), 380 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_4, 0x11), 381 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), 382 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), 383 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), 384 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL, 0x00), 385 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL, 0x00), 386 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x00), 387 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x00), 388 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0, 0xa4), 389 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1, 0xa2), 390 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2, 0x6e), 391 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3, 0x51), 392 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4, 0x0a), 393 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5, 0x26), 394 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6, 0x12), 395 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7, 0x2a), 396 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B0, 0x4c), 397 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B1, 0xc4), 398 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B2, 0x38), 399 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B3, 0x64), 400 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B4, 0x0c), 401 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B5, 0x4b), 402 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B6, 0x12), 403 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B7, 0x0a), 404 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x0c), 405 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1, 0x26), 406 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1, 0x26), 407 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2, 0x26), 408 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2, 0x26), 409 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_0_1, 0x11), 410 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_2_3, 0x11), 411 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1, 0x03), 412 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2, 0x03), 413 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1, 0x15), 414 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1, 0x00), 415 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2, 0x22), 416 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2, 0x00), 417 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3, 0x22), 418 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1, 0xff), 419 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1, 0x00), 420 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2, 0xff), 421 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2, 0x00), 422 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1, 0x07), 423 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2, 0x09), 424 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123, 0x2f), 425 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1, 0x00), 426 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2, 0x00), 427 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2, 0x85), 428 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3, 0x45), 429 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1, 0x00), 430 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2, 0x00), 431 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_ENABLES, 0x0c), 432 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CNTRL, 0xa3), 433 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_LVL, 0x04), 434 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL, 0x0e), 435 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL1, 0x14), 436 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00), 437 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_TRIM, 0x66), 438 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1, 0xff), 439 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2, 0x32), 440 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1, 0x07), 441 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2, 0x0a), 442 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1, 0x02), 443 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2, 0x04), 444 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01, 0x76), 445 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23, 0x67), 446 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1, 0x20), 447 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3, 0x02), 448 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1, 0x33), 449 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3, 0x43), 450 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1, 0x00), 451 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3, 0x51), 452 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123, 0xe5), 453 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123, 0xf5), 454 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG, 0x1f), 455 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ, 0x07), 456 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL, 0xd0), 457 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_EN, 0x1f), 458 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE0_1, 0x88), 459 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE2_3, 0x88), 460 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_AUX_CLK_CTRL, 0x20), 461 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_EOM_CTRL1, 0x10), 462 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2, 0x0a), 463 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3, 0x0a), 464 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4, 0xaa), 465 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2, 0x77), 466 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_CNTRL1, 0x00), 467 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1, 0xdd), 468 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3, 0xd8), 469 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE, 0x1c), 470 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE, 0x1c), 471 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE, 0x18), 472 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE, 0x10), 473 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_CTRL, 0x00), 474 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX, 0x10), 475 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123, 0x1C), 476 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES, 0x00), 477 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DIG_BKUP_CTRL16, 0x37), 269 478 }; 270 479 271 480 static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { ··· 1385 1132 QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), 1386 1133 }; 1387 1134 1135 + static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl[] = { 1136 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x00), 1137 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), 1138 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x10), 1139 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x01), 1140 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), 1141 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), 1142 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 1143 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 1144 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), 1145 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), 1146 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), 1147 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x00), 1148 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x00), 1149 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), 1150 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), 1151 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), 1152 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), 1153 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x3b), 1154 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x00), 1155 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), 1156 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), 1157 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), 1158 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), 1159 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x56), 1160 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), 1161 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), 1162 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), 1163 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), 1164 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x01), 1165 + }; 1166 + 1388 1167 static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { 1389 1168 QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40), 1390 1169 QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30), ··· 1442 1157 QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX, 0x11), 1443 1158 QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX, 0x11), 1444 1159 QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1), 1160 + }; 1161 + 1162 + static const struct qmp_phy_init_tbl qmp_v8_n3p_dp_tx_tbl[] = { 1163 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x3f), 1164 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VMODE_CTRL1, 0x40), 1165 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT1, 0x07), 1166 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x18), 1167 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x50), 1168 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0d), 1169 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x07), 1170 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL, 0x0a), 1171 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0f), 1172 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRAN_DRVR_EMP_EN, 0x5f), 1173 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_EMP_POST1_LVL, 0x20), 1174 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_EMP_POST1_LVL, 0x20), 1175 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_PRE1_EMPH, 0x20), 1176 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_PRE1_EMPH, 0x20), 1177 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_DRV_LVL, 0x00), 1178 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_DRV_LVL, 0x00), 1179 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_HIGHZ_DRVR_EN, 0x30), 1180 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x50), 1181 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x51), 1182 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x00), 1183 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), 1184 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), 1185 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), 1186 + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET, 0x10), 1445 1187 }; 1446 1188 1447 1189 static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = { ··· 1585 1273 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), 1586 1274 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), 1587 1275 QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), 1276 + }; 1277 + 1278 + static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_rbr[] = { 1279 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x05), 1280 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x7a), 1281 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x02), 1282 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x83), 1283 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x37), 1284 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x04), 1285 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x54), 1286 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), 1287 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x06), 1288 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xfe), 1289 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x00), 1290 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x05), 1291 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), 1292 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), 1293 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa4), 1294 + }; 1295 + 1296 + static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr[] = { 1297 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x04), 1298 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x21), 1299 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x04), 1300 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x18), 1301 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x07), 1302 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x07), 1303 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), 1304 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), 1305 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), 1306 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), 1307 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), 1308 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x04), 1309 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), 1310 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), 1311 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa3), 1312 + }; 1313 + 1314 + static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr2[] = { 1315 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x03), 1316 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xf6), 1317 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x20), 1318 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x0), 1319 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), 1320 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), 1321 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x10), 1322 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x0e), 1323 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), 1324 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), 1325 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), 1326 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), 1327 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), 1328 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x00), 1329 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xbf), 1330 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), 1331 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_RESETSM_CNTRL, 0x20), 1332 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x03), 1333 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), 1334 + }; 1335 + 1336 + static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr3[] = { 1337 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x02), 1338 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x63), 1339 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), 1340 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x5b), 1341 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x02), 1342 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), 1343 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), 1344 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), 1345 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), 1346 + 1347 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x17), 1348 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x15), 1349 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x4f), 1350 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), 1351 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xa0), 1352 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), 1353 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 1354 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 1355 + 1356 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xa0), 1357 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x01), 1358 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), 1359 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x6b), 1360 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), 1361 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), 1362 + 1363 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), 1364 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), 1365 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), 1366 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x04), 1367 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), 1368 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), 1369 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), 1370 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), 1371 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x16), 1372 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), 1373 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), 1374 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x10), 1375 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x05), 1376 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), 1377 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x02), 1378 + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0x84), 1588 1379 }; 1589 1380 1590 1381 static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = { ··· 2064 1649 { .supply = "vdda-pll", .init_load_uA = 36000, }, 2065 1650 }; 2066 1651 1652 + static struct regulator_bulk_data qmp_phy_vreg_refgen[] = { 1653 + { .supply = "vdda-phy", .init_load_uA = 21800 }, 1654 + { .supply = "vdda-pll", .init_load_uA = 36000 }, 1655 + { .supply = "refgen", .init_load_uA = 3270 }, 1656 + }; 1657 + 2067 1658 static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = { 2068 1659 { 0x00, 0x0c, 0x15, 0x1a }, 2069 1660 { 0x02, 0x0e, 0x16, 0xff }, ··· 2192 1771 u16 usb3_serdes; 2193 1772 u16 usb3_pcs_misc; 2194 1773 u16 usb3_pcs; 1774 + u16 usb3_pcs_aon; 2195 1775 u16 usb3_pcs_usb; 2196 1776 u16 dp_serdes; 2197 1777 u16 dp_txa; ··· 2214 1792 int pcs_tbl_num; 2215 1793 const struct qmp_phy_init_tbl *pcs_usb_tbl; 2216 1794 int pcs_usb_tbl_num; 1795 + const struct qmp_phy_init_tbl *pcs_misc_tbl; 1796 + int pcs_misc_tbl_num; 2217 1797 2218 1798 const struct qmp_phy_init_tbl *dp_serdes_tbl; 2219 1799 int dp_serdes_tbl_num; ··· 2239 1815 const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; 2240 1816 2241 1817 /* DP PHY callbacks */ 1818 + int (*configure_dp_clocks)(struct qmp_combo *qmp); 2242 1819 int (*configure_dp_phy)(struct qmp_combo *qmp); 2243 1820 void (*configure_dp_tx)(struct qmp_combo *qmp); 2244 1821 int (*calibrate_dp_phy)(struct qmp_combo *qmp); ··· 2261 1836 /* Offset from PCS to PCS_USB region */ 2262 1837 unsigned int pcs_usb_offset; 2263 1838 1839 + bool invert_cc_polarity; 2264 1840 }; 2265 1841 2266 1842 struct qmp_combo { ··· 2278 1852 void __iomem *tx2; 2279 1853 void __iomem *rx2; 2280 1854 void __iomem *pcs_misc; 1855 + void __iomem *pcs_aon; 2281 1856 void __iomem *pcs_usb; 2282 1857 2283 1858 void __iomem *dp_serdes; ··· 2318 1891 2319 1892 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); 2320 1893 static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp); 1894 + static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp); 2321 1895 static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp); 2322 1896 static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp); 2323 1897 ··· 2326 1898 static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp); 2327 1899 static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp); 2328 1900 static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp); 1901 + 1902 + static void qmp_v8_dp_aux_init(struct qmp_combo *qmp); 1903 + static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp); 1904 + static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp); 2329 1905 2330 1906 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) 2331 1907 { ··· 2408 1976 .usb3_serdes = 0x1000, 2409 1977 .usb3_pcs_misc = 0x1c00, 2410 1978 .usb3_pcs = 0x1e00, 1979 + .usb3_pcs_aon = 0x2000, 2411 1980 .usb3_pcs_usb = 0x2100, 2412 1981 .dp_serdes = 0x3000, 2413 1982 .dp_txa = 0x3400, 2414 1983 .dp_txb = 0x3800, 2415 1984 .dp_dp_phy = 0x3c00, 1985 + }; 1986 + 1987 + static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = { 1988 + .com = 0x0000, 1989 + .usb3_pcs_aon = 0x0100, 1990 + .usb3_serdes = 0x1000, 1991 + .usb3_pcs_misc = 0x1400, 1992 + .usb3_pcs = 0x1600, 1993 + .usb3_pcs_usb = 0x1900, 1994 + .dp_serdes = 0x2000, 1995 + .dp_dp_phy = 0x2400, 1996 + .txa = 0x4000, 1997 + .txb = 0x5000, 2416 1998 }; 2417 1999 2418 2000 static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { ··· 2464 2018 2465 2019 .dp_aux_init = qmp_v4_dp_aux_init, 2466 2020 .configure_dp_tx = qmp_v4_configure_dp_tx, 2021 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2467 2022 .configure_dp_phy = qmp_v4_configure_dp_phy, 2468 2023 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2469 2024 ··· 2473 2026 .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), 2474 2027 .vreg_list = qmp_phy_vreg_l, 2475 2028 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 2029 + .invert_cc_polarity = true, 2476 2030 }; 2477 2031 2478 2032 static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = { ··· 2601 2153 2602 2154 .dp_aux_init = qmp_v4_dp_aux_init, 2603 2155 .configure_dp_tx = qmp_v4_configure_dp_tx, 2156 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2604 2157 .configure_dp_phy = qmp_v4_configure_dp_phy, 2605 2158 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2606 2159 ··· 2648 2199 2649 2200 .dp_aux_init = qmp_v4_dp_aux_init, 2650 2201 .configure_dp_tx = qmp_v4_configure_dp_tx, 2202 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2651 2203 .configure_dp_phy = qmp_v4_configure_dp_phy, 2652 2204 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2653 2205 ··· 2694 2244 2695 2245 .dp_aux_init = qmp_v4_dp_aux_init, 2696 2246 .configure_dp_tx = qmp_v4_configure_dp_tx, 2247 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2697 2248 .configure_dp_phy = qmp_v4_configure_dp_phy, 2698 2249 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2699 2250 ··· 2783 2332 2784 2333 .dp_aux_init = qmp_v4_dp_aux_init, 2785 2334 .configure_dp_tx = qmp_v4_configure_dp_tx, 2335 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2786 2336 .configure_dp_phy = qmp_v4_configure_dp_phy, 2787 2337 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2788 2338 ··· 2832 2380 2833 2381 .dp_aux_init = qmp_v4_dp_aux_init, 2834 2382 .configure_dp_tx = qmp_v4_configure_dp_tx, 2383 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2835 2384 .configure_dp_phy = qmp_v4_configure_dp_phy, 2836 2385 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2837 2386 ··· 2880 2427 2881 2428 .dp_aux_init = qmp_v4_dp_aux_init, 2882 2429 .configure_dp_tx = qmp_v4_configure_dp_tx, 2430 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2883 2431 .configure_dp_phy = qmp_v4_configure_dp_phy, 2884 2432 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2885 2433 ··· 2926 2472 2927 2473 .dp_aux_init = qmp_v4_dp_aux_init, 2928 2474 .configure_dp_tx = qmp_v4_configure_dp_tx, 2475 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2929 2476 .configure_dp_phy = qmp_v4_configure_dp_phy, 2930 2477 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2931 2478 ··· 2972 2517 2973 2518 .dp_aux_init = qmp_v4_dp_aux_init, 2974 2519 .configure_dp_tx = qmp_v4_configure_dp_tx, 2520 + .configure_dp_clocks = qmp_v3_configure_dp_clocks, 2975 2521 .configure_dp_phy = qmp_v4_configure_dp_phy, 2976 2522 .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2977 2523 ··· 2981 2525 .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), 2982 2526 .vreg_list = qmp_phy_vreg_l, 2983 2527 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 2528 + }; 2529 + 2530 + static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { 2531 + .offsets = &qmp_combo_usb43dp_offsets_v8, 2532 + 2533 + .serdes_tbl = glymur_usb43dp_serdes_tbl, 2534 + .serdes_tbl_num = ARRAY_SIZE(glymur_usb43dp_serdes_tbl), 2535 + .tx_tbl = glymur_usb43dp_lalb_tbl, 2536 + .tx_tbl_num = ARRAY_SIZE(glymur_usb43dp_lalb_tbl), 2537 + .pcs_tbl = glymur_usb43dp_pcs_tbl, 2538 + .pcs_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_tbl), 2539 + .pcs_usb_tbl = glymur_usb43dp_pcs_usb_tbl, 2540 + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_usb_tbl), 2541 + .pcs_misc_tbl = glymur_usb43dp_pcs_misc_tbl, 2542 + .pcs_misc_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_misc_tbl), 2543 + 2544 + .dp_serdes_tbl = qmp_v8_dp_serdes_tbl, 2545 + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl), 2546 + .dp_tx_tbl = qmp_v8_n3p_dp_tx_tbl, 2547 + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v8_n3p_dp_tx_tbl), 2548 + 2549 + .serdes_tbl_rbr = qmp_v8_dp_serdes_tbl_rbr, 2550 + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_rbr), 2551 + .serdes_tbl_hbr = qmp_v8_dp_serdes_tbl_hbr, 2552 + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr), 2553 + .serdes_tbl_hbr2 = qmp_v8_dp_serdes_tbl_hbr2, 2554 + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr2), 2555 + .serdes_tbl_hbr3 = qmp_v8_dp_serdes_tbl_hbr3, 2556 + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr3), 2557 + 2558 + .swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr, 2559 + .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, 2560 + .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, 2561 + .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, 2562 + 2563 + .dp_aux_init = qmp_v8_dp_aux_init, 2564 + .configure_dp_tx = qmp_v4_configure_dp_tx, 2565 + .configure_dp_clocks = qmp_v8_configure_dp_clocks, 2566 + .configure_dp_phy = qmp_v8_configure_dp_phy, 2567 + .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, 2568 + 2569 + .regs = qmp_v8_n3_usb43dpphy_regs_layout, 2570 + .reset_list = msm8996_usb3phy_reset_l, 2571 + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), 2572 + .vreg_list = qmp_phy_vreg_refgen, 2573 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen), 2984 2574 }; 2985 2575 2986 2576 static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) ··· 3191 2689 return reverse; 3192 2690 } 3193 2691 3194 - static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp) 2692 + static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp) 3195 2693 { 3196 2694 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 3197 2695 u32 phy_vco_div; ··· 3238 2736 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL); 3239 2737 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL); 3240 2738 3241 - ret = qmp_combo_configure_dp_clocks(qmp); 2739 + ret = qmp_v3_configure_dp_clocks(qmp); 3242 2740 if (ret) 3243 2741 return ret; 3244 2742 ··· 3324 2822 qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); 3325 2823 } 3326 2824 2825 + static void qmp_v8_dp_aux_init(struct qmp_combo *qmp) 2826 + { 2827 + const struct qmp_phy_cfg *cfg = qmp->cfg; 2828 + 2829 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 2830 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 2831 + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 2832 + 2833 + /* Turn on BIAS current for PHY/PLL */ 2834 + writel(0x1c, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); 2835 + 2836 + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); 2837 + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); 2838 + writel(0x06, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); 2839 + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); 2840 + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); 2841 + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); 2842 + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); 2843 + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); 2844 + writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); 2845 + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); 2846 + qmp->dp_aux_cfg = 0; 2847 + 2848 + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 2849 + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 2850 + PHY_AUX_REQ_ERR_MASK, 2851 + qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); 2852 + } 2853 + 3327 2854 static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp) 3328 2855 { 3329 2856 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 3365 2834 writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); 3366 2835 3367 2836 qmp_combo_configure_dp_swing(qmp); 2837 + } 2838 + 2839 + static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp) 2840 + { 2841 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 2842 + u32 phy_vco_div; 2843 + unsigned long pixel_freq; 2844 + const struct qmp_phy_cfg *cfg = qmp->cfg; 2845 + 2846 + switch (dp_opts->link_rate) { 2847 + case 1620: 2848 + phy_vco_div = 0x4; 2849 + pixel_freq = 1620000000UL / 2; 2850 + break; 2851 + case 2700: 2852 + phy_vco_div = 0x2; 2853 + pixel_freq = 2700000000UL / 2; 2854 + break; 2855 + case 5400: 2856 + phy_vco_div = 0x4; 2857 + pixel_freq = 5400000000UL / 4; 2858 + break; 2859 + case 8100: 2860 + phy_vco_div = 0x3; 2861 + pixel_freq = 8100000000UL / 6; 2862 + break; 2863 + default: 2864 + /* Other link rates aren't supported */ 2865 + return -EINVAL; 2866 + } 2867 + writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]); 2868 + 2869 + /* disable core reset tsync */ 2870 + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 2871 + 2872 + writel(0x04, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC); 2873 + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC); 2874 + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_CYC); 2875 + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); 2876 + 2877 + writel(0x3e, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TSYNC_OVRD); 2878 + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL); 2879 + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL); 2880 + writel(0x01, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_CFG1); 2881 + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); 2882 + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN0_DRV_LVL); 2883 + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN1_DRV_LVL); 2884 + 2885 + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); 2886 + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); 2887 + 2888 + return 0; 3368 2889 } 3369 2890 3370 2891 static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp) ··· 3435 2852 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL); 3436 2853 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL); 3437 2854 3438 - ret = qmp_combo_configure_dp_clocks(qmp); 2855 + ret = qmp->cfg->configure_dp_clocks(qmp); 3439 2856 if (ret) 3440 2857 return ret; 3441 2858 ··· 3549 2966 return 0; 3550 2967 } 3551 2968 2969 + static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp) 2970 + { 2971 + const struct qmp_phy_cfg *cfg = qmp->cfg; 2972 + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); 2973 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 2974 + u32 bias0_en, drvr0_en, bias1_en, drvr1_en; 2975 + u32 status; 2976 + int ret; 2977 + 2978 + ret = qmp_v456_configure_dp_phy(qmp); 2979 + if (ret < 0) 2980 + return ret; 2981 + 2982 + if (dp_opts->lanes == 1) { 2983 + bias0_en = reverse ? 0x3e : 0x15; 2984 + bias1_en = reverse ? 0x15 : 0x3e; 2985 + drvr0_en = reverse ? 0x13 : 0x10; 2986 + drvr1_en = reverse ? 0x10 : 0x13; 2987 + } else if (dp_opts->lanes == 2) { 2988 + bias0_en = reverse ? 0x3f : 0x15; 2989 + bias1_en = reverse ? 0x15 : 0x3f; 2990 + drvr0_en = 0x10; 2991 + drvr1_en = 0x10; 2992 + } else { 2993 + bias0_en = 0x3f; 2994 + bias1_en = 0x3f; 2995 + drvr0_en = 0x34; 2996 + drvr1_en = 0x34; 2997 + } 2998 + 2999 + writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); 3000 + writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); 3001 + writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); 3002 + writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); 3003 + 3004 + writel(0x08, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 3005 + udelay(100); 3006 + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 3007 + udelay(500); 3008 + 3009 + if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], 3010 + status, 3011 + ((status & BIT(1)) > 0), 3012 + 500, 3013 + 10000)) 3014 + return -ETIMEDOUT; 3015 + 3016 + writel(0x00, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); 3017 + writel(0x00, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); 3018 + 3019 + writel(0x2b, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); 3020 + writel(0x2b, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); 3021 + 3022 + return 0; 3023 + } 3024 + 3552 3025 /* 3553 3026 * We need to calibrate the aux setting here as many times 3554 3027 * as the caller tries ··· 3662 3023 { 3663 3024 const struct qmp_phy_cfg *cfg = qmp->cfg; 3664 3025 void __iomem *com = qmp->com; 3026 + void __iomem *pcs_aon = qmp->pcs_aon; 3665 3027 int ret; 3666 3028 u32 val; 3667 3029 ··· 3698 3058 SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | 3699 3059 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 3700 3060 3061 + /* override hardware control for reset of qmp phy */ 3062 + if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) { 3063 + qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1); 3064 + qphy_clrbits(pcs_aon, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1); 3065 + } 3066 + 3701 3067 /* Use software based port select and switch on typec orientation */ 3702 3068 val = SW_PORTSELECT_MUX; 3703 3069 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) 3704 3070 val |= SW_PORTSELECT_VAL; 3071 + 3072 + if (cfg->invert_cc_polarity) 3073 + val |= INVERT_CC_POLARITY; 3074 + 3705 3075 writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); 3706 3076 3707 3077 switch (qmp->qmpphy_mode) { ··· 3885 3235 qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); 3886 3236 3887 3237 qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); 3238 + qmp_configure(qmp->dev, qmp->pcs_misc, cfg->pcs_misc_tbl, cfg->pcs_misc_tbl_num); 3239 + 3888 3240 3889 3241 if (pcs_usb) 3890 3242 qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl, ··· 4013 3361 const struct qmp_phy_cfg *cfg = qmp->cfg; 4014 3362 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; 4015 3363 void __iomem *pcs_misc = qmp->pcs_misc; 3364 + void __iomem *pcs_aon = qmp->pcs_aon; 4016 3365 u32 intr_mask; 4017 3366 4018 3367 if (qmp->phy_mode == PHY_MODE_USB_HOST_SS || ··· 4033 3380 /* Enable required PHY autonomous mode interrupts */ 4034 3381 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); 4035 3382 4036 - /* Enable i/o clamp_n for autonomous mode */ 4037 - if (pcs_misc) 4038 - qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); 3383 + /* 3384 + * Enable i/o clamp_n for autonomous mode 3385 + * V6 and later versions use pcs aon clamp register 3386 + */ 3387 + if (pcs_aon) 3388 + qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); 3389 + else if (pcs_misc) 3390 + qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); 4039 3391 } 4040 3392 4041 3393 static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp) ··· 4048 3390 const struct qmp_phy_cfg *cfg = qmp->cfg; 4049 3391 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; 4050 3392 void __iomem *pcs_misc = qmp->pcs_misc; 3393 + void __iomem *pcs_aon = qmp->pcs_aon; 4051 3394 4052 3395 /* Disable i/o clamp_n on resume for normal mode */ 4053 - if (pcs_misc) 4054 - qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); 3396 + if (pcs_aon) 3397 + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); 3398 + else if (pcs_misc) 3399 + qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); 4055 3400 4056 3401 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], 4057 3402 ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN); ··· 4719 4058 qmp->serdes = base + offs->usb3_serdes; 4720 4059 qmp->pcs_misc = base + offs->usb3_pcs_misc; 4721 4060 qmp->pcs = base + offs->usb3_pcs; 4061 + if (offs->usb3_pcs_aon) 4062 + qmp->pcs_aon = base + offs->usb3_pcs_aon; 4722 4063 qmp->pcs_usb = base + offs->usb3_pcs_usb; 4723 4064 4724 4065 qmp->dp_serdes = base + offs->dp_serdes; ··· 4982 4319 } 4983 4320 4984 4321 static const struct of_device_id qmp_combo_of_match_table[] = { 4322 + { 4323 + .compatible = "qcom,glymur-qmp-usb3-dp-phy", 4324 + .data = &glymur_usb3dpphy_cfg, 4325 + }, 4985 4326 { 4986 4327 .compatible = "qcom,sar2130p-qmp-usb3-dp-phy", 4987 4328 .data = &sar2130p_usb3dpphy_cfg,
+21
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_DP_PHY_V2_H_ 7 + #define QCOM_PHY_QMP_DP_PHY_V2_H_ 8 + 9 + // /* Only for QMP V2 PHY - DP PHY registers */ 10 + #define QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK 0x048 11 + #define QSERDES_V2_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c 12 + #define QSERDES_V2_DP_PHY_AUX_BIST_CFG 0x050 13 + 14 + #define QSERDES_V2_DP_PHY_VCO_DIV 0x068 15 + #define QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL 0x06c 16 + #define QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL 0x088 17 + 18 + #define QSERDES_V2_DP_PHY_SPARE0 0x0ac 19 + #define QSERDES_V2_DP_PHY_STATUS 0x0c0 20 + 21 + #endif
+25
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_DP_PHY_V8_H_ 7 + #define QCOM_PHY_QMP_DP_PHY_V8_H_ 8 + 9 + /* Only for QMP V8 PHY - DP PHY registers */ 10 + #define QSERDES_V8_DP_PHY_VCO_DIV 0x070 11 + #define QSERDES_V8_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0 12 + #define QSERDES_V8_DP_PHY_TSYNC_OVRD 0x074 13 + #define QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL 0x078 14 + #define QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL 0x0bc 15 + #define QSERDES_V8_DP_PHY_AUXLESS_CFG1 0x0c8 16 + #define QSERDES_V8_DP_PHY_LFPS_PERIOD 0x0d0 17 + #define QSERDES_V8_DP_PHY_LFPS_CYC 0x0d4 18 + #define QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC 0x0d8 19 + #define QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC 0x0d8 20 + #define QSERDES_V8_DP_PHY_LN0_DRV_LVL 0x0e0 21 + #define QSERDES_V8_DP_PHY_LN1_DRV_LVL 0x0e4 22 + #define QSERDES_V8_DP_PHY_STATUS 0x114 23 + 24 + 25 + #endif
+52
drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2025 Linaro Ltd. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ 7 + #define QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ 8 + 9 + /* Only for DP QMP V8 PHY - QSERDES COM registers */ 10 + #define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c 11 + #define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 12 + #define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c 13 + #define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060 14 + #define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064 15 + #define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070 16 + #define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 17 + #define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 18 + #define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c 19 + #define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 20 + #define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 21 + #define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088 22 + #define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 23 + #define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 24 + #define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 25 + #define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 26 + #define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 27 + #define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 28 + #define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac 29 + #define DP_QSERDES_V8_COM_BG_TIMER 0x0bc 30 + #define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0 31 + #define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4 32 + #define DP_QSERDES_V8_COM_SSC_PER1 0x0cc 33 + #define DP_QSERDES_V8_COM_SSC_PER2 0x0d0 34 + #define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc 35 + #define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0 36 + #define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 37 + #define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 38 + #define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4 39 + #define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 40 + #define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118 41 + #define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120 42 + #define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c 43 + #define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140 44 + #define DP_QSERDES_V8_COM_CLK_SELECT 0x164 45 + #define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170 46 + #define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174 47 + #define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180 48 + #define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4 49 + #define DP_QSERDES_V8_COM_CMN_STATUS 0x314 50 + #define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c 51 + 52 + #endif
+213
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
··· 37 37 #include "phy-qcom-qmp-pcs-pcie-v6_30.h" 38 38 #include "phy-qcom-qmp-pcs-v6_30.h" 39 39 #include "phy-qcom-qmp-pcie-qhp.h" 40 + #include "phy-qcom-qmp-qserdes-com-v8.h" 41 + #include "phy-qcom-qmp-pcs-pcie-v8.h" 42 + #include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h" 40 43 41 44 #define PHY_INIT_COMPLETE_TIMEOUT 10000 42 45 ··· 101 98 [QPHY_START_CTRL] = QPHY_V7_PCS_START_CONTROL, 102 99 [QPHY_PCS_STATUS] = QPHY_V7_PCS_PCS_STATUS1, 103 100 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, 101 + }; 102 + 103 + static const unsigned int pciephy_v8_regs_layout[QPHY_LAYOUT_SIZE] = { 104 + [QPHY_SW_RESET] = QPHY_V8_PCS_SW_RESET, 105 + [QPHY_START_CTRL] = QPHY_V8_PCS_START_CONTROL, 106 + [QPHY_PCS_STATUS] = QPHY_V8_PCS_PCS_STATUS1, 107 + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_PCS_POWER_DOWN_CONTROL, 104 108 }; 105 109 106 110 static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { ··· 3077 3067 QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), 3078 3068 }; 3079 3069 3070 + static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_serdes_tbl[] = { 3071 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0x93), 3072 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), 3073 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06), 3074 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), 3075 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), 3076 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), 3077 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x0a), 3078 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x1a), 3079 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x34), 3080 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), 3081 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x55), 3082 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), 3083 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), 3084 + 3085 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xf8), 3086 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), 3087 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06), 3088 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), 3089 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), 3090 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE0, 0x0a), 3091 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x04), 3092 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x0d), 3093 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), 3094 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0xab), 3095 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0xaa), 3096 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), 3097 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), 3098 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), 3099 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), 3100 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), 3101 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, 0x14), 3102 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_ENABLE1, 0x90), 3103 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYS_CLK_CTRL, 0x82), 3104 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x0f), 3105 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x08), 3106 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x46), 3107 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x04), 3108 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x14), 3109 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_SELECT, 0x34), 3110 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0xa0), 3111 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), 3112 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MISC_1, 0x88), 3113 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MODE, 0x04), 3114 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_DC_LEVEL_CTRL, 0x0f), 3115 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_SPARE_FOR_ECO, 0x02), 3116 + }; 3117 + 3118 + static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_tx_tbl[] = { 3119 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX, 0x1b), 3120 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX, 0x14), 3121 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_1, 0x00), 3122 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_2, 0x40), 3123 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_3, 0x00), 3124 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN, 0x04), 3125 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND0, 0x05), 3126 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND1, 0x00), 3127 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_10B_8B, 0x07), 3128 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_20B_10B, 0x1f), 3129 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN, 0x90), 3130 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1, 0x02), 3131 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2, 0x0d), 3132 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3, 0x53), 3133 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4, 0x54), 3134 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PHPRE_CTRL, 0x20), 3135 + }; 3136 + 3137 + static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_rx_tbl[] = { 3138 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4, 0x0b), 3139 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3, 0x04), 3140 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4, 0x05), 3141 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS, 0x15), 3142 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1, 0x00), 3143 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL, 0x89), 3144 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4, 0x2d), 3145 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_ENABLES, 0x1c), 3146 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_LVL, 0x04), 3147 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL, 0x01), 3148 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_BAND_CTRL0, 0x05), 3149 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0, 0x00), 3150 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1, 0x00), 3151 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SVS_MODE_CTRL, 0x00), 3152 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1, 0x40), 3153 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2, 0x42), 3154 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3, 0x18), 3155 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3, 0x12), 3156 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3, 0x18), 3157 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0, 0xc2), 3158 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1, 0xc2), 3159 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2, 0x18), 3160 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4, 0x0f), 3161 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7, 0x62), 3162 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0, 0xe4), 3163 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1, 0x63), 3164 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2, 0xd8), 3165 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3, 0x99), 3166 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4, 0x67), 3167 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0, 0xa4), 3168 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1, 0xa4), 3169 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2, 0x28), 3170 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3, 0x9f), 3171 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4, 0x48), 3172 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5, 0x24), 3173 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x01), 3174 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4, 0x00), 3175 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB, 0xff), 3176 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB, 0xff), 3177 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23, 0x30), 3178 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4, 0x03), 3179 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3, 0x1f), 3180 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4, 0x1f), 3181 + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_GM_CAL, 0x0d), 3182 + }; 3183 + 3184 + static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_tbl[] = { 3185 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB, 0x17), 3186 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN, 0x2e), 3187 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_SIGDET_LVL, 0xcc), 3188 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL, 0x40), 3189 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1, 0x04), 3190 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2, 0x02), 3191 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG4, 0x00), 3192 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG5, 0x22), 3193 + }; 3194 + 3195 + static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] = { 3196 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_TX_RX_CONFIG, 0xc0), 3197 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2, 0x1d), 3198 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), 3199 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS, 0x00), 3200 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG1, 0x16), 3201 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME, 0x27), 3202 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME, 0x27), 3203 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5, 0x02), 3204 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_PRE_GAIN, 0x2e), 3205 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1, 0x03), 3206 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3, 0x28), 3207 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5, 0x0f), 3208 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5, 0xf2), 3209 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5, 0xf2), 3210 + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f), 3211 + }; 3212 + 3080 3213 struct qmp_pcie_offsets { 3081 3214 u16 serdes; 3082 3215 u16 pcs; ··· 3514 3361 .txz = 0xe000, 3515 3362 .rxz = 0xe200, 3516 3363 .ln_shrd = 0x8000, 3364 + }; 3365 + 3366 + static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_0 = { 3367 + .serdes = 0x1000, 3368 + .pcs = 0x1400, 3369 + .pcs_misc = 0x1800, 3370 + .tx = 0x0000, 3371 + .rx = 0x0200, 3372 + .tx2 = 0x0800, 3373 + .rx2 = 0x0a00, 3517 3374 }; 3518 3375 3519 3376 static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = { ··· 4588 4425 .phy_status = PHYSTATUS_4_20, 4589 4426 }; 4590 4427 4428 + static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = { 4429 + .lanes = 2, 4430 + 4431 + .offsets = &qmp_pcie_offsets_v8_0, 4432 + 4433 + .tbls = { 4434 + .serdes = kaanapali_qmp_gen3x2_pcie_serdes_tbl, 4435 + .serdes_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_serdes_tbl), 4436 + .tx = kaanapali_qmp_gen3x2_pcie_tx_tbl, 4437 + .tx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_tx_tbl), 4438 + .rx = kaanapali_qmp_gen3x2_pcie_rx_tbl, 4439 + .rx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_rx_tbl), 4440 + .pcs = kaanapali_qmp_gen3x2_pcie_pcs_tbl, 4441 + .pcs_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_tbl), 4442 + .pcs_misc = kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl, 4443 + .pcs_misc_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl), 4444 + }, 4445 + 4446 + .reset_list = sdm845_pciephy_reset_l, 4447 + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), 4448 + .vreg_list = qmp_phy_vreg_l, 4449 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4450 + .regs = pciephy_v8_regs_layout, 4451 + 4452 + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4453 + .phy_status = PHYSTATUS_4_20, 4454 + }; 4455 + 4591 4456 static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { 4592 4457 .lanes = 4, 4593 4458 ··· 4627 4436 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4628 4437 4629 4438 .regs = pciephy_v8_50_regs_layout, 4439 + 4440 + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4441 + .phy_status = PHYSTATUS_4_20, 4442 + }; 4443 + 4444 + static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = { 4445 + .lanes = 2, 4446 + 4447 + .offsets = &qmp_pcie_offsets_v8_0, 4448 + 4449 + .reset_list = sdm845_pciephy_reset_l, 4450 + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), 4451 + .vreg_list = qmp_phy_vreg_l, 4452 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4453 + 4454 + .regs = pciephy_v8_regs_layout, 4630 4455 4631 4456 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4632 4457 .phy_status = PHYSTATUS_4_20, ··· 5399 5192 5400 5193 static const struct of_device_id qmp_pcie_of_match_table[] = { 5401 5194 { 5195 + .compatible = "qcom,glymur-qmp-gen4x2-pcie-phy", 5196 + .data = &glymur_qmp_gen4x2_pciephy_cfg, 5197 + }, { 5402 5198 .compatible = "qcom,glymur-qmp-gen5x4-pcie-phy", 5403 5199 .data = &glymur_qmp_gen5x4_pciephy_cfg, 5404 5200 }, { ··· 5419 5209 }, { 5420 5210 .compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy", 5421 5211 .data = &ipq9574_gen3x2_pciephy_cfg, 5212 + }, { 5213 + .compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy", 5214 + .data = &qmp_v8_gen3x2_pciephy_cfg, 5422 5215 }, { 5423 5216 .compatible = "qcom,msm8998-qmp-pcie-phy", 5424 5217 .data = &msm8998_pciephy_cfg,
+12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_AON_V6_H_ 7 + #define QCOM_PHY_QMP_PCS_AON_V6_H_ 8 + 9 + /* Only for QMP V6 PHY - PCS_AON registers */ 10 + #define QPHY_V6_PCS_AON_CLAMP_ENABLE 0x00 11 + 12 + #endif
+17
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_AON_V8_H_ 7 + #define QCOM_PHY_QMP_PCS_AON_V8_H_ 8 + 9 + /* Only for QMP V8 PHY - PCS_AON registers */ 10 + #define QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE 0x00 11 + #define QPHY_V8_PCS_AON_USB4_AON_CLAMP_ENABLE 0x04 12 + #define QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE 0x08 13 + #define QPHY_V8_PCS_AON_USB4_AON_TOGGLE_ENABLE 0x0c 14 + #define QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE 0x10 15 + #define QPHY_V8_PCS_AON_DUMMY_STATUS 0x14 16 + 17 + #endif
+12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_MISC_V5_H_ 7 + #define QCOM_PHY_QMP_PCS_MISC_V5_H_ 8 + 9 + /* Only for QMP V5 PHY - PCS_MISC registers */ 10 + #define QPHY_V5_PCS_MISC_CLAMP_ENABLE 0x0c 11 + 12 + #endif
+12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_MISC_V8_H_ 7 + #define QCOM_PHY_QMP_PCS_MISC_V8_H_ 8 + 9 + /* Only for QMP V8 PHY - PCS_MISC registers */ 10 + #define QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1 0x08 11 + 12 + #endif
+34
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_PCS_PCIE_V8_H_ 7 + #define QCOM_PHY_QMP_PCS_PCIE_V8_H_ 8 + 9 + /* Only for QMP V8 PHY - PCIE PCS registers */ 10 + 11 + #define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2 0x00c 12 + #define QPHY_PCIE_V8_PCS_TX_RX_CONFIG 0x018 13 + #define QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE 0x01c 14 + #define QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS 0x090 15 + #define QPHY_PCIE_V8_PCS_EQ_CONFIG1 0x0a0 16 + #define QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME 0x0f0 17 + #define QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME 0x0f4 18 + #define QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5 0x108 19 + #define QPHY_PCIE_V8_PCS_G4_PRE_GAIN 0x15c 20 + #define QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB 0x170 21 + #define QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN 0x178 22 + #define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1 0x17c 23 + #define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3 0x184 24 + #define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5 0x18c 25 + #define QPHY_PCIE_V8_PCS_RX_SIGDET_LVL 0x190 26 + #define QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5 0x1ac 27 + #define QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL 0x1b8 28 + #define QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5 0x1c0 29 + #define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6 0x1d0 30 + #define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1 0x1dc 31 + #define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2 0x1e0 32 + #define QPHY_PCIE_V8_PCS_EQ_CONFIG4 0x1f8 33 + #define QPHY_PCIE_V8_PCS_EQ_CONFIG5 0x1fc 34 + #endif
+106
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_QSERDES_COM_V2_H_ 7 + #define QCOM_PHY_QMP_QSERDES_COM_V2_H_ 8 + 9 + /* Only for QMP V2 PHY - QSERDES COM registers */ 10 + #define QSERDES_V2_COM_ATB_SEL1 0x000 11 + #define QSERDES_V2_COM_ATB_SEL2 0x004 12 + #define QSERDES_V2_COM_FREQ_UPDATE 0x008 13 + #define QSERDES_V2_COM_BG_TIMER 0x00c 14 + #define QSERDES_V2_COM_SSC_EN_CENTER 0x010 15 + #define QSERDES_V2_COM_SSC_ADJ_PER1 0x014 16 + #define QSERDES_V2_COM_SSC_ADJ_PER2 0x018 17 + #define QSERDES_V2_COM_SSC_PER1 0x01c 18 + #define QSERDES_V2_COM_SSC_PER2 0x020 19 + #define QSERDES_V2_COM_SSC_STEP_SIZE1 0x024 20 + #define QSERDES_V2_COM_SSC_STEP_SIZE2 0x028 21 + #define QSERDES_V2_COM_POST_DIV 0x02c 22 + #define QSERDES_V2_COM_POST_DIV_MUX 0x030 23 + #define QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN 0x034 24 + #define QSERDES_V2_COM_CLK_ENABLE1 0x038 25 + #define QSERDES_V2_COM_SYS_CLK_CTRL 0x03c 26 + #define QSERDES_V2_COM_SYSCLK_BUF_ENABLE 0x040 27 + #define QSERDES_V2_COM_PLL_EN 0x044 28 + #define QSERDES_V2_COM_PLL_IVCO 0x048 29 + #define QSERDES_V2_COM_LOCK_CMP1_MODE0 0x04c 30 + #define QSERDES_V2_COM_LOCK_CMP2_MODE0 0x050 31 + #define QSERDES_V2_COM_LOCK_CMP3_MODE0 0x054 32 + #define QSERDES_V2_COM_LOCK_CMP1_MODE1 0x058 33 + #define QSERDES_V2_COM_LOCK_CMP2_MODE1 0x05c 34 + #define QSERDES_V2_COM_LOCK_CMP3_MODE1 0x060 35 + #define QSERDES_V2_COM_EP_CLOCK_DETECT_CTR 0x068 36 + #define QSERDES_V2_COM_SYSCLK_DET_COMP_STATUS 0x06c 37 + #define QSERDES_V2_COM_CLK_EP_DIV 0x074 38 + #define QSERDES_V2_COM_CP_CTRL_MODE0 0x078 39 + #define QSERDES_V2_COM_CP_CTRL_MODE1 0x07c 40 + #define QSERDES_V2_COM_PLL_RCTRL_MODE0 0x084 41 + #define QSERDES_V2_COM_PLL_RCTRL_MODE1 0x088 42 + #define QSERDES_V2_COM_PLL_CCTRL_MODE0 0x090 43 + #define QSERDES_V2_COM_PLL_CCTRL_MODE1 0x094 44 + #define QSERDES_V2_COM_PLL_CNTRL 0x09c 45 + #define QSERDES_V2_COM_BIAS_EN_CTRL_BY_PSM 0x0a8 46 + #define QSERDES_V2_COM_SYSCLK_EN_SEL 0x0ac 47 + #define QSERDES_V2_COM_CML_SYSCLK_SEL 0x0b0 48 + #define QSERDES_V2_COM_RESETSM_CNTRL 0x0b4 49 + #define QSERDES_V2_COM_RESETSM_CNTRL2 0x0b8 50 + #define QSERDES_V2_COM_LOCK_CMP_EN 0x0c8 51 + #define QSERDES_V2_COM_LOCK_CMP_CFG 0x0cc 52 + #define QSERDES_V2_COM_DEC_START_MODE0 0x0d0 53 + #define QSERDES_V2_COM_DEC_START_MODE1 0x0d4 54 + #define QSERDES_V2_COM_VCOCAL_DEADMAN_CTRL 0x0d8 55 + #define QSERDES_V2_COM_DIV_FRAC_START1_MODE0 0x0dc 56 + #define QSERDES_V2_COM_DIV_FRAC_START2_MODE0 0x0e0 57 + #define QSERDES_V2_COM_DIV_FRAC_START3_MODE0 0x0e4 58 + #define QSERDES_V2_COM_DIV_FRAC_START1_MODE1 0x0e8 59 + #define QSERDES_V2_COM_DIV_FRAC_START2_MODE1 0x0ec 60 + #define QSERDES_V2_COM_DIV_FRAC_START3_MODE1 0x0f0 61 + #define QSERDES_V2_COM_VCO_TUNE_MINVAL1 0x0f4 62 + #define QSERDES_V2_COM_VCO_TUNE_MINVAL2 0x0f8 63 + #define QSERDES_V2_COM_INTEGLOOP_INITVAL 0x100 64 + #define QSERDES_V2_COM_INTEGLOOP_EN 0x104 65 + #define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE0 0x108 66 + #define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE0 0x10c 67 + #define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE1 0x110 68 + #define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE1 0x114 69 + #define QSERDES_V2_COM_VCO_TUNE_MAXVAL1 0x118 70 + #define QSERDES_V2_COM_VCO_TUNE_MAXVAL2 0x11c 71 + #define QSERDES_V2_COM_VCO_TUNE_CTRL 0x124 72 + #define QSERDES_V2_COM_VCO_TUNE_MAP 0x128 73 + #define QSERDES_V2_COM_VCO_TUNE1_MODE0 0x12c 74 + #define QSERDES_V2_COM_VCO_TUNE2_MODE0 0x130 75 + #define QSERDES_V2_COM_VCO_TUNE1_MODE1 0x134 76 + #define QSERDES_V2_COM_VCO_TUNE2_MODE1 0x138 77 + #define QSERDES_V2_COM_VCO_TUNE_INITVAL1 0x13c 78 + #define QSERDES_V2_COM_VCO_TUNE_INITVAL2 0x140 79 + #define QSERDES_V2_COM_VCO_TUNE_TIMER1 0x144 80 + #define QSERDES_V2_COM_VCO_TUNE_TIMER2 0x148 81 + #define QSERDES_V2_COM_CMN_STATUS 0x15c 82 + #define QSERDES_V2_COM_RESET_SM_STATUS 0x160 83 + #define QSERDES_V2_COM_RESTRIM_CODE_STATUS 0x164 84 + #define QSERDES_V2_COM_PLLCAL_CODE1_STATUS 0x168 85 + #define QSERDES_V2_COM_PLLCAL_CODE2_STATUS 0x16c 86 + #define QSERDES_V2_COM_CLK_SELECT 0x174 87 + #define QSERDES_V2_COM_HSCLK_SEL 0x178 88 + #define QSERDES_V2_COM_INTEGLOOP_BINCODE_STATUS 0x17c 89 + #define QSERDES_V2_COM_PLL_ANALOG 0x180 90 + #define QSERDES_V2_COM_CORECLK_DIV 0x184 91 + #define QSERDES_V2_COM_SW_RESET 0x188 92 + #define QSERDES_V2_COM_CORE_CLK_EN 0x18c 93 + #define QSERDES_V2_COM_C_READY_STATUS 0x190 94 + #define QSERDES_V2_COM_CMN_CONFIG 0x194 95 + #define QSERDES_V2_COM_CMN_RATE_OVERRIDE 0x198 96 + #define QSERDES_V2_COM_SVS_MODE_CLK_SEL 0x19c 97 + #define QSERDES_V2_COM_DEBUG_BUS0 0x1a0 98 + #define QSERDES_V2_COM_DEBUG_BUS1 0x1a4 99 + #define QSERDES_V2_COM_DEBUG_BUS2 0x1a8 100 + #define QSERDES_V2_COM_DEBUG_BUS3 0x1ac 101 + #define QSERDES_V2_COM_DEBUG_BUS_SEL 0x1b0 102 + #define QSERDES_V2_COM_CMN_MISC1 0x1b4 103 + #define QSERDES_V2_COM_CMN_MISC2 0x1b8 104 + #define QSERDES_V2_COM_CORECLK_DIV_MODE1 0x1bc 105 + 106 + #endif
+11
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h
··· 33 33 #define QSERDES_V8_COM_CP_CTRL_MODE0 0x070 34 34 #define QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 35 35 #define QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 36 + #define QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c 36 37 #define QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 37 38 #define QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 38 39 #define QSERDES_V8_COM_DEC_START_MODE0 0x088 ··· 41 40 #define QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 42 41 #define QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 43 42 #define QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 43 + #define QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1 0x09c 44 44 #define QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 45 45 #define QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac 46 46 #define QSERDES_V8_COM_BG_TIMER 0x0bc ··· 49 47 #define QSERDES_V8_COM_SSC_PER1 0x0cc 50 48 #define QSERDES_V8_COM_SSC_PER2 0x0d0 51 49 #define QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc 50 + #define QSERDES_V8_COM_CLK_ENABLE1 0x0e0 51 + #define QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 52 + #define QSERDES_V8_COM_PLL_IVCO 0x0f4 52 53 #define QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 53 54 #define QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 54 55 #define QSERDES_V8_COM_RESETSM_CNTRL 0x118 56 + #define QSERDES_V8_COM_LOCK_CMP_EN 0x120 55 57 #define QSERDES_V8_COM_LOCK_CMP_CFG 0x124 56 58 #define QSERDES_V8_COM_VCO_TUNE_MAP 0x140 59 + #define QSERDES_V8_COM_CLK_SELECT 0x164 57 60 #define QSERDES_V8_COM_CORE_CLK_EN 0x170 58 61 #define QSERDES_V8_COM_CMN_CONFIG_1 0x174 62 + #define QSERDES_V8_COM_CMN_MISC_1 0x184 63 + #define QSERDES_V8_COM_CMN_MODE 0x188 64 + #define QSERDES_V8_COM_VCO_DC_LEVEL_CTRL 0x198 65 + #define QSERDES_V8_COM_PLL_SPARE_FOR_ECO 0x2b4 59 66 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4 60 67 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8 61 68 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
+52
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2025 Linaro Ltd. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_QSERDES_DP_COM_V8_H_ 7 + #define QCOM_PHY_QMP_QSERDES_DP_COM_V8_H_ 8 + 9 + /* Only for DP QMP V8 PHY - QSERDES COM registers */ 10 + #define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c 11 + #define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 12 + #define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c 13 + #define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060 14 + #define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064 15 + #define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070 16 + #define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 17 + #define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 18 + #define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c 19 + #define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 20 + #define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 21 + #define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088 22 + #define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 23 + #define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 24 + #define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 25 + #define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 26 + #define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 27 + #define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 28 + #define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac 29 + #define DP_QSERDES_V8_COM_BG_TIMER 0x0bc 30 + #define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0 31 + #define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4 32 + #define DP_QSERDES_V8_COM_SSC_PER1 0x0cc 33 + #define DP_QSERDES_V8_COM_SSC_PER2 0x0d0 34 + #define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc 35 + #define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0 36 + #define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 37 + #define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 38 + #define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4 39 + #define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 40 + #define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118 41 + #define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120 42 + #define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c 43 + #define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140 44 + #define DP_QSERDES_V8_COM_CLK_SELECT 0x164 45 + #define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170 46 + #define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174 47 + #define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180 48 + #define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4 49 + #define DP_QSERDES_V8_COM_CMN_STATUS 0x314 50 + #define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c 51 + 52 + #endif
+639
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_QSERDES_V8_LALBH_ 7 + #define QCOM_PHY_QMP_QSERDES_V8_LALBH_ 8 + 9 + #define QSERDES_V8_LALB_BIST_MODE_LANENO 0x0 10 + #define QSERDES_V8_LALB_BIST_INVERT 0x4 11 + #define QSERDES_V8_LALB_PERL_LENGTH1 0x8 12 + #define QSERDES_V8_LALB_PERL_LENGTH2 0xc 13 + #define QSERDES_V8_LALB_BIST_PATTERN1 0x10 14 + #define QSERDES_V8_LALB_BIST_PATTERN2 0x14 15 + #define QSERDES_V8_LALB_BIST_PATTERN3 0x18 16 + #define QSERDES_V8_LALB_BIST_PATTERN4 0x1c 17 + #define QSERDES_V8_LALB_BIST_PATTERN5 0x20 18 + #define QSERDES_V8_LALB_BIST_PATTERN6 0x24 19 + #define QSERDES_V8_LALB_BIST_PATTERN7 0x28 20 + #define QSERDES_V8_LALB_BIST_PATTERN8 0x2c 21 + #define QSERDES_V8_LALB_PRBS_SEED1 0x30 22 + #define QSERDES_V8_LALB_PRBS_SEED2 0x34 23 + #define QSERDES_V8_LALB_PRBS_SEED3 0x38 24 + #define QSERDES_V8_LALB_PRBS_SEED4 0x3c 25 + #define QSERDES_V8_LALB_PRBS_SEED5 0x40 26 + #define QSERDES_V8_LALB_PRBS_SEED6 0x44 27 + #define QSERDES_V8_LALB_PRBS_SEED7 0x48 28 + #define QSERDES_V8_LALB_SW_RESET_PWRDNB 0x4c 29 + #define QSERDES_V8_LALB_RESET_GEN 0x50 30 + #define QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL 0x54 31 + #define QSERDES_V8_LALB_CDR_EN_RXEQ_RESET 0x58 32 + #define QSERDES_V8_LALB_CLKBUF_ENABLE 0x5c 33 + #define QSERDES_V8_LALB_TX0_EMP_POST1_LVL 0x60 34 + #define QSERDES_V8_LALB_TX1_EMP_POST1_LVL 0x64 35 + #define QSERDES_V8_LALB_TX0_IDLE_CTRL 0x68 36 + #define QSERDES_V8_LALB_TX1_IDLE_CTRL 0x6c 37 + #define QSERDES_V8_LALB_TX0_DRV_LVL 0x70 38 + #define QSERDES_V8_LALB_TX0_DRV_LVL_OFFSET 0x74 39 + #define QSERDES_V8_LALB_TX1_DRV_LVL 0x78 40 + #define QSERDES_V8_LALB_TX1_DRV_LVL_OFFSET 0x7c 41 + #define QSERDES_V8_LALB_TRAN_DRVR_EMP_EN 0x80 42 + #define QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL 0x84 43 + #define QSERDES_V8_LALB_TX0_PRE1_EMPH 0x88 44 + #define QSERDES_V8_LALB_TX1_PRE1_EMPH 0x8c 45 + #define QSERDES_V8_LALB_TX0_PRE2_EMPH 0x90 46 + #define QSERDES_V8_LALB_TX1_PRE2_EMPH 0x94 47 + #define QSERDES_V8_LALB_STALL_LDO_BOOST_EN 0x98 48 + #define QSERDES_V8_LALB_PRE_EMPH_EN_CTRL 0x9c 49 + #define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1 0xa0 50 + #define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2 0xa4 51 + #define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3 0xa8 52 + #define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4 0xac 53 + #define QSERDES_V8_LALB_TRANSMITTER_EN_CTRL 0xb0 54 + #define QSERDES_V8_LALB_HIGHZ_DRVR_EN 0xb4 55 + #define QSERDES_V8_LALB_TX_MISC_CTRL1 0xb8 56 + #define QSERDES_V8_LALB_LPB_EN_CTRL1 0xbc 57 + #define QSERDES_V8_LALB_LBP_EN_CTRL2 0xc0 58 + #define QSERDES_V8_LALB_TX0_SERDES_BYP_CTRL 0xc4 59 + #define QSERDES_V8_LALB_TX1_SERDES_BYP_CTRL 0xc8 60 + #define QSERDES_V8_LALB_LANE_MODE_1 0xcc 61 + #define QSERDES_V8_LALB_LANE_MODE_2 0xd0 62 + #define QSERDES_V8_LALB_LANE_MODE_3 0xd4 63 + #define QSERDES_V8_LALB_LANE_MODE_4 0xd8 64 + #define QSERDES_V8_LALB_ATB_SEL1 0xdc 65 + #define QSERDES_V8_LALB_ATB_SEL2 0xe0 66 + #define QSERDES_V8_LALB_TX0_RES_CODE_LANE 0xe4 67 + #define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_OVRD 0xe8 68 + #define QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL 0xec 69 + #define QSERDES_V8_LALB_TX0_RESTRIM_INIT_CODE 0xf0 70 + #define QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET 0xf4 71 + #define QSERDES_V8_LALB_TX1_RES_CODE_LANE 0xf8 72 + #define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_OVRD 0xfc 73 + #define QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL 0x100 74 + #define QSERDES_V8_LALB_TX1_RESTRIM_INIT_CODE 0x104 75 + #define QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET 0x108 76 + #define QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL 0x10c 77 + #define QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL 0x110 78 + #define QSERDES_V8_LALB_VMODE_CTRL1 0x114 79 + #define QSERDES_V8_LALB_SLEW_CNTL_RATE01 0x118 80 + #define QSERDES_V8_LALB_SLEW_CNTL_RATE23 0x11c 81 + #define QSERDES_V8_LALB_SLEW_CNTL_RATE4 0x120 82 + #define QSERDES_V8_LALB_ANA_INTERFACE_SELECT1 0x124 83 + #define QSERDES_V8_LALB_ANA_INTERFACE_SELECT2 0x128 84 + #define QSERDES_V8_LALB_ANA_INTERFACE_SELECT3 0x12c 85 + #define QSERDES_V8_LALB_PCS_INTERFACE_SELECT1 0x130 86 + #define QSERDES_V8_LALB_PCS_INTERFACE_SELECT2 0x134 87 + #define QSERDES_V8_LALB_LDO_TIMER_CTRL 0x138 88 + #define QSERDES_V8_LALB_AC_JTAG_ENABLE 0x13c 89 + #define QSERDES_V8_LALB_AC_JTAG_INITP 0x140 90 + #define QSERDES_V8_LALB_AC_JTAG_INITN 0x144 91 + #define QSERDES_V8_LALB_AC_JTAG_LVL 0x148 92 + #define QSERDES_V8_LALB_AC_JTAG_MODE 0x14c 93 + #define QSERDES_V8_LALB_AC_JTAG_RESET 0x150 94 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0 0x154 95 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1 0x158 96 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2 0x15c 97 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3 0x160 98 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4 0x164 99 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5 0x168 100 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6 0x16c 101 + #define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7 0x170 102 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B0 0x174 103 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B1 0x178 104 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B2 0x17c 105 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B3 0x180 106 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B4 0x184 107 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B5 0x188 108 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B6 0x18c 109 + #define QSERDES_V8_LALB_RX_MODE_RATE2_B7 0x190 110 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B0 0x194 111 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B1 0x198 112 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B2 0x19c 113 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B3 0x1a0 114 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B4 0x1a4 115 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B5 0x1a8 116 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B6 0x1ac 117 + #define QSERDES_V8_LALB_RX_MODE_RATE3_B7 0x1b0 118 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B0 0x1b4 119 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B1 0x1b8 120 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B2 0x1bc 121 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B3 0x1c0 122 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B4 0x1c4 123 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B5 0x1c8 124 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B6 0x1cc 125 + #define QSERDES_V8_LALB_RX_MODE_RATE4_B7 0x1d0 126 + #define QSERDES_V8_LALB_TX_DCC_ANA_CTRL1 0x1d4 127 + #define QSERDES_V8_LALB_TX_DCC_ANA_CTRL2 0x1d8 128 + #define QSERDES_V8_LALB_CMUX_DCC_CTRL1 0x1dc 129 + #define QSERDES_V8_LALB_CMUX_DCC_POSTCAL_OFFSET 0x1e0 130 + #define QSERDES_V8_LALB_CMUX_DCC_OVRD 0x1e4 131 + #define QSERDES_V8_LALB_TX_DCC_CTRL 0x1e8 132 + #define QSERDES_V8_LALB_TX0_CTUNE_DCC_CONFIG 0x1ec 133 + #define QSERDES_V8_LALB_TX0_CTUNE_DCC_POSTCAL_OFFSET 0x1f0 134 + #define QSERDES_V8_LALB_TX0_CTUNE_DCC_OVRD 0x1f4 135 + #define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_CONFIG 0x1f8 136 + #define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x1fc 137 + #define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_CONFIG 0x200 138 + #define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x204 139 + #define QSERDES_V8_LALB_TX1_CTUNE_DCC_CONFIG 0x208 140 + #define QSERDES_V8_LALB_TX1_CTUNE_DCC_POSTCAL_OFFSET 0x20c 141 + #define QSERDES_V8_LALB_TX1_CTUNE_DCC_OVRD 0x210 142 + #define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_CONFIG 0x214 143 + #define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x218 144 + #define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_CONFIG 0x21c 145 + #define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x220 146 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CTRL 0x224 147 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE0 0x228 148 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE1 0x22c 149 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE2 0x230 150 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE3 0x234 151 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE4 0x238 152 + #define QSERDES_V8_LALB_CDR_VCO_CAL_CTRL 0x23c 153 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE0 0x240 154 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE0 0x244 155 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1 0x248 156 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1 0x24c 157 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2 0x250 158 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2 0x254 159 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE3 0x258 160 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE3 0x25c 161 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE4 0x260 162 + #define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE4 0x264 163 + #define QSERDES_V8_LALB_CDR_VCTRL_RATE_0_1 0x268 164 + #define QSERDES_V8_LALB_CDR_VCTRL_RATE_2_3 0x26c 165 + #define QSERDES_V8_LALB_CDR_VCTRL_RATE_4 0x270 166 + #define QSERDES_V8_LALB_KVCO_INIT_RATE_0_1 0x274 167 + #define QSERDES_V8_LALB_KVCO_INIT_RATE_2_3 0x278 168 + #define QSERDES_V8_LALB_KVCO_INIT_RATE_4 0x27c 169 + #define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE0 0x280 170 + #define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1 0x284 171 + #define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2 0x288 172 + #define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE3 0x28c 173 + #define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE4 0x290 174 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_0_1 0x294 175 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_2_3 0x298 176 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_4 0x29c 177 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_0_1 0x2a0 178 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_2_3 0x2a4 179 + #define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_4 0x2a8 180 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE0 0x2ac 181 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE0 0x2b0 182 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1 0x2b4 183 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1 0x2b8 184 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2 0x2bc 185 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2 0x2c0 186 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE3 0x2c4 187 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE3 0x2c8 188 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE4 0x2cc 189 + #define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE4 0x2d0 190 + #define QSERDES_V8_LALB_KP_CDR_UP_DN 0x2d4 191 + #define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_0_1 0x2d8 192 + #define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3 0x2dc 193 + #define QSERDES_V8_LALB_KP_CODE_OVRD_RATE4 0x2e0 194 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0 0x2e4 195 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE0 0x2e8 196 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1 0x2ec 197 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1 0x2f0 198 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2 0x2f4 199 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2 0x2f8 200 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3 0x2fc 201 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE3 0x300 202 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4 0x304 203 + #define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE4 0x308 204 + #define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0 0x30c 205 + #define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1 0x310 206 + #define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2 0x314 207 + #define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3 0x318 208 + #define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4 0x31c 209 + #define QSERDES_V8_LALB_CDR_KVCO_KP_CAL_FREQ_MEAS_CTRL 0x320 210 + #define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CTRL 0x324 211 + #define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT1 0x328 212 + #define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT2 0x32c 213 + #define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT3 0x330 214 + #define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123 0x334 215 + #define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_4 0x338 216 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE0 0x33c 217 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1 0x340 218 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2 0x344 219 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE3 0x348 220 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE4 0x34c 221 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL1 0x350 222 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2 0x354 223 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3 0x358 224 + #define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL4 0x35c 225 + #define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE0 0x360 226 + #define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1 0x364 227 + #define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2 0x368 228 + #define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE3 0x36c 229 + #define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE4 0x370 230 + #define QSERDES_V8_LALB_RX_IDAC_I0_DC_OFFSETS 0x374 231 + #define QSERDES_V8_LALB_RX_IDAC_I0BAR_DC_OFFSETS 0x378 232 + #define QSERDES_V8_LALB_RX_IDAC_I1_DC_OFFSETS 0x37c 233 + #define QSERDES_V8_LALB_RX_IDAC_I1BAR_DC_OFFSETS 0x380 234 + #define QSERDES_V8_LALB_RX_IDAC_Q_DC_OFFSETS 0x384 235 + #define QSERDES_V8_LALB_RX_IDAC_QBAR_DC_OFFSETS 0x388 236 + #define QSERDES_V8_LALB_RX_IDAC_A_DC_OFFSETS 0x38c 237 + #define QSERDES_V8_LALB_RX_IDAC_ABAR_DC_OFFSETS 0x390 238 + #define QSERDES_V8_LALB_RX_IDAC_EN 0x394 239 + #define QSERDES_V8_LALB_DATA_SLICER_INIT_TIMER_CTRL 0x398 240 + #define QSERDES_V8_LALB_RX_IDAC_ENABLES 0x39c 241 + #define QSERDES_V8_LALB_RX_IDAC_SIGN 0x3a0 242 + #define QSERDES_V8_LALB_RX_IDAC_TSETTLE 0x3a4 243 + #define QSERDES_V8_LALB_SIGDET_ENABLES 0x3a8 244 + #define QSERDES_V8_LALB_SIGDET_CNTRL 0x3ac 245 + #define QSERDES_V8_LALB_SIGDET_LVL 0x3b0 246 + #define QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL 0x3b4 247 + #define QSERDES_V8_LALB_SIGDET_CAL_CTRL1 0x3b8 248 + #define QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x3bc 249 + #define QSERDES_V8_LALB_SIGDET_CAL_TRIM 0x3c0 250 + #define QSERDES_V8_LALB_IA_OFFSET_CENTER_CAL_CTRL 0x3c4 251 + #define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE0 0x3c8 252 + #define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1 0x3cc 253 + #define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2 0x3d0 254 + #define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE3 0x3d4 255 + #define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE4 0x3d8 256 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE0 0x3dc 257 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE1 0x3e0 258 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE2 0x3e4 259 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE3 0x3e8 260 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE4 0x3ec 261 + #define QSERDES_V8_LALB_CDR_LOCK_CTRL 0x3f0 262 + #define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE0 0x3f4 263 + #define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1 0x3f8 264 + #define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2 0x3fc 265 + #define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE3 0x400 266 + #define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE4 0x404 267 + #define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE0 0x408 268 + #define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1 0x40c 269 + #define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2 0x410 270 + #define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE3 0x414 271 + #define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE4 0x418 272 + #define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123 0x41c 273 + #define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE4 0x420 274 + #define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01 0x424 275 + #define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23 0x428 276 + #define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE4 0x42c 277 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1 0x430 278 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3 0x434 279 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE4 0x438 280 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1 0x43c 281 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3 0x440 282 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE4 0x444 283 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1 0x448 284 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3 0x44c 285 + #define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE4 0x450 286 + #define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123 0x454 287 + #define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE4 0x458 288 + #define QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG 0x45c 289 + #define QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ 0x460 290 + #define QSERDES_V8_LALB_CDR_FAST_SLOW_VCO_OVRD 0x464 291 + #define QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL 0x468 292 + #define QSERDES_V8_LALB_CDR_FAST_LOCK_EN_CTRL 0x46c 293 + #define QSERDES_V8_LALB_RX_RCVR_EN 0x470 294 + #define QSERDES_V8_LALB_LANE_RATE_CTRL 0x474 295 + #define QSERDES_V8_LALB_RX_TERM_RCVR_CTRL 0x478 296 + #define QSERDES_V8_LALB_REC_DETECT_CTRL 0x47c 297 + #define QSERDES_V8_LALB_RCV_DETECT_LVL 0x480 298 + #define QSERDES_V8_LALB_GM_CAL_EN 0x484 299 + #define QSERDES_V8_LALB_GM_CAL_RES_RATE0_1 0x488 300 + #define QSERDES_V8_LALB_GM_CAL_RES_RATE2_3 0x48c 301 + #define QSERDES_V8_LALB_GM_CAL_RES_RATE4 0x490 302 + #define QSERDES_V8_LALB_RX_TERM_BW_RATE_0123 0x494 303 + #define QSERDES_V8_LALB_RX_TERM_BW_RATE4 0x498 304 + #define QSERDES_V8_LALB_AUX_CLK_CTRL 0x49c 305 + #define QSERDES_V8_LALB_AUX_OFFSET_CONTROL 0x4a0 306 + #define QSERDES_V8_LALB_AUXDATA_TB 0x4a4 307 + #define QSERDES_V8_LALB_EOM_CTRL1 0x4a8 308 + #define QSERDES_V8_LALB_EOM_CTRL2 0x4ac 309 + #define QSERDES_V8_LALB_EOM_CTRL3 0x4b0 310 + #define QSERDES_V8_LALB_EOM_CTRL4 0x4b4 311 + #define QSERDES_V8_LALB_DFE_EN_TIMER 0x4b8 312 + #define QSERDES_V8_LALB_RX_EQ_OFFSET_LSB 0x4bc 313 + #define QSERDES_V8_LALB_RX_EQ_OFFSET_MSB 0x4c0 314 + #define QSERDES_V8_LALB_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x4c4 315 + #define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL2 0x4c8 316 + #define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL3 0x4cc 317 + #define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL1 0x4d0 318 + #define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2 0x4d4 319 + #define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3 0x4d8 320 + #define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4 0x4dc 321 + #define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL5 0x4e0 322 + #define QSERDES_V8_LALB_RX_EQU_KEQ_UP_LSB 0x4e4 323 + #define QSERDES_V8_LALB_RX_EQU_KEQ_UP_MSB 0x4e8 324 + #define QSERDES_V8_LALB_RX_EQU_KEQ_DN_LSB 0x4ec 325 + #define QSERDES_V8_LALB_RX_EQU_KEQ_DN_MSB 0x4f0 326 + #define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_0_1_2 0x4f4 327 + #define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_3_4 0x4f8 328 + #define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2 0x4fc 329 + #define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_3_4 0x500 330 + #define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK1 0x504 331 + #define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK2 0x508 332 + #define QSERDES_V8_LALB_VGA_CAL_CNTRL1 0x50c 333 + #define QSERDES_V8_LALB_VGA_CAL_CNTRL2 0x510 334 + #define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1 0x514 335 + #define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3 0x518 336 + #define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE4 0x51c 337 + #define QSERDES_V8_LALB_KVGA_CTRL1 0x520 338 + #define QSERDES_V8_LALB_KVGA_CTRL2 0x524 339 + #define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL1 0x528 340 + #define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL2 0x52c 341 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE0 0x530 342 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE1 0x534 343 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE2 0x538 344 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE3 0x53c 345 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE4 0x540 346 + #define QSERDES_V8_LALB_VTHRESH_CAL_MAN_CAL_PAM3 0x544 347 + #define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_0_1 0x548 348 + #define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_2_3 0x54c 349 + #define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE4 0x550 350 + #define QSERDES_V8_LALB_DFE_TAP1_CTRL 0x554 351 + #define QSERDES_V8_LALB_DFE_TAP1_MANVAL_KTAP 0x558 352 + #define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_0_1_2 0x55c 353 + #define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_3_4 0x560 354 + #define QSERDES_V8_LALB_DFE_TAP2_CTRL 0x564 355 + #define QSERDES_V8_LALB_DFE_TAP2_MANVAL_KTAP 0x568 356 + #define QSERDES_V8_LALB_DFE_TAP3_CTRL 0x56c 357 + #define QSERDES_V8_LALB_DFE_TAP3_MANVAL_KTAP 0x570 358 + #define QSERDES_V8_LALB_DFE_TAP4_CTRL 0x574 359 + #define QSERDES_V8_LALB_DFE_TAP4_MANVAL_KTAP 0x578 360 + #define QSERDES_V8_LALB_DFE_TAP5_CTRL 0x57c 361 + #define QSERDES_V8_LALB_DFE_TAP5_MANVAL_KTAP 0x580 362 + #define QSERDES_V8_LALB_DFE_TAP6_CTRL 0x584 363 + #define QSERDES_V8_LALB_DFE_TAP6_MANVAL_KTAP 0x588 364 + #define QSERDES_V8_LALB_DFE_TAP7_CTRL 0x58c 365 + #define QSERDES_V8_LALB_DFE_TAP7_MANVAL_KTAP 0x590 366 + #define QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE 0x594 367 + #define QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE 0x598 368 + #define QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE 0x59c 369 + #define QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE 0x5a0 370 + #define QSERDES_V8_LALB_CDR_IQTUNE_CTRL 0x5a4 371 + #define QSERDES_V8_LALB_CDR_IQTUNE_GAIN 0x5a8 372 + #define QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX 0x5ac 373 + #define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL1 0x5b0 374 + #define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL2 0x5b4 375 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE0 0x5b8 376 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE1 0x5bc 377 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE2 0x5c0 378 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE3 0x5c4 379 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE4 0x5c8 380 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE0 0x5cc 381 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE1 0x5d0 382 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE2 0x5d4 383 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE3 0x5d8 384 + #define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE4 0x5dc 385 + #define QSERDES_V8_LALB_CDR_IQTUNE_ANA_CTRL 0x5e0 386 + #define QSERDES_V8_LALB_CDR_IQTUNE_VDCC_CTRL 0x5e4 387 + #define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123 0x5e8 388 + #define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE4 0x5ec 389 + #define QSERDES_V8_LALB_BLW_CTRL 0x5f0 390 + #define QSERDES_V8_LALB_BLW_ANA_VER_CTRL 0x5f4 391 + #define QSERDES_V8_LALB_BLW_GAIN_CAL_CTRL 0x5f8 392 + #define QSERDES_V8_LALB_BLW_GAIN_FORCE_CODE 0x5fc 393 + #define QSERDES_V8_LALB_BLW_MAN_VAL_RATE3 0x600 394 + #define QSERDES_V8_LALB_BLW_MAN_VAL_RATE4 0x604 395 + #define QSERDES_V8_LALB_IVTH_CAL_CTRL1 0x608 396 + #define QSERDES_V8_LALB_IVTH_CAL_CTRL2 0x60c 397 + #define QSERDES_V8_LALB_IVTH_CAL_CTRL3 0x610 398 + #define QSERDES_V8_LALB_VTH_I_UP_CNTRL_VAL 0x614 399 + #define QSERDES_V8_LALB_VTH_I_DN_CNTRL_VAL 0x618 400 + #define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_VAL 0x61c 401 + #define QSERDES_V8_LALB_IVTH_CAL_VAL_OVRD_MUX 0x620 402 + #define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES 0x624 403 + #define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE0 0x628 404 + #define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE1 0x62c 405 + #define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE2 0x630 406 + #define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE3 0x634 407 + #define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE4 0x638 408 + #define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE0 0x63c 409 + #define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE1 0x640 410 + #define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE2 0x644 411 + #define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE3 0x648 412 + #define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE4 0x64c 413 + #define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE0 0x650 414 + #define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE1 0x654 415 + #define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE2 0x658 416 + #define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE3 0x65c 417 + #define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE4 0x660 418 + #define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE0 0x664 419 + #define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE1 0x668 420 + #define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE2 0x66c 421 + #define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE3 0x670 422 + #define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE4 0x674 423 + #define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE0 0x678 424 + #define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE1 0x67c 425 + #define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE2 0x680 426 + #define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE3 0x684 427 + #define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE4 0x688 428 + #define QSERDES_V8_LALB_DEBUG_BUS_SEL 0x68c 429 + #define QSERDES_V8_LALB_BIST_STATUS 0x690 430 + #define QSERDES_V8_LALB_BIST_ERROR_COUNT1 0x694 431 + #define QSERDES_V8_LALB_BIST_ERROR_COUNT2 0x698 432 + #define QSERDES_V8_LALB_AC_JTAG_OUTP 0x69c 433 + #define QSERDES_V8_LALB_AC_JTAG_OUTN 0x6a0 434 + #define QSERDES_V8_LALB_DATA_SLICER_DEBUG_STATUS 0x6a4 435 + #define QSERDES_V8_LALB_DATA_SLICER_TIMER1_STATUS 0x6a8 436 + #define QSERDES_V8_LALB_DATA_SLICER_TIMER2_STATUS 0x6ac 437 + #define QSERDES_V8_LALB_TX0_RESTRIM_CODE_STATUS 0x6b0 438 + #define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_CODE_STATUS 0x6b4 439 + #define QSERDES_V8_LALB_TX0_RESTRIM_CAL_STATUS 0x6b8 440 + #define QSERDES_V8_LALB_TX1_RESTRIM_CODE_STATUS 0x6bc 441 + #define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_CODE_STATUS 0x6c0 442 + #define QSERDES_V8_LALB_TX1_RESTRIM_CAL_STATUS 0x6c4 443 + #define QSERDES_V8_LALB_CMUX_DCC_CAL_FSM_STATUS 0x6c8 444 + #define QSERDES_V8_LALB_CMUX_DCC_READCODE_STATUS 0x6cc 445 + #define QSERDES_V8_LALB_TX_DCC_CAL_ANA_STATUS 0x6d0 446 + #define QSERDES_V8_LALB_TX0_CTUNE_DCC_FSM_DEBUG_STATUS 0x6d4 447 + #define QSERDES_V8_LALB_TX0_COARSE_DCC_READCODE_STATUS 0x6d8 448 + #define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6dc 449 + #define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6e0 450 + #define QSERDES_V8_LALB_TX0_FINE_DCC_READCODE_STATUS 0x6e4 451 + #define QSERDES_V8_LALB_TX1_CTUNE_DCC_FSM_DEBUG_STATUS 0x6e8 452 + #define QSERDES_V8_LALB_TX1_COARSE_DCC_READCODE_STATUS 0x6ec 453 + #define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6f0 454 + #define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6f4 455 + #define QSERDES_V8_LALB_TX1_FINE_DCC_READCODE_STATUS 0x6f8 456 + #define QSERDES_V8_LALB_CDR_VCO_CAL_STATUS 0x6fc 457 + #define QSERDES_V8_LALB_CDR_VCTRL_STATUS 0x700 458 + #define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_STATUS 0x704 459 + #define QSERDES_V8_LALB_KVCO_CAL_DEBUG1_STATUS 0x708 460 + #define QSERDES_V8_LALB_KVCO_CAL_DEBUG2_STATUS 0x70c 461 + #define QSERDES_V8_LALB_KP_CAL_DEBUG1_STATUS 0x710 462 + #define QSERDES_V8_LALB_KP_CAL_DEBUG2_STATUS 0x714 463 + #define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG1_STATUS 0x718 464 + #define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG2_STATUS 0x71c 465 + #define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG3_STATUS 0x720 466 + #define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG4_STATUS 0x724 467 + #define QSERDES_V8_LALB_IVCM_CAL_STATUS 0x728 468 + #define QSERDES_V8_LALB_IVCM_CAL_DEBUG_STATUS 0x72c 469 + #define QSERDES_V8_LALB_IDAC_STATUS_I0 0x730 470 + #define QSERDES_V8_LALB_IDAC_STATUS_I0BAR 0x734 471 + #define QSERDES_V8_LALB_IDAC_STATUS_I1 0x738 472 + #define QSERDES_V8_LALB_IDAC_STATUS_I1BAR 0x73c 473 + #define QSERDES_V8_LALB_IDAC_STATUS_Q 0x740 474 + #define QSERDES_V8_LALB_IDAC_STATUS_QBAR 0x744 475 + #define QSERDES_V8_LALB_IDAC_STATUS_A 0x748 476 + #define QSERDES_V8_LALB_IDAC_STATUS_ABAR 0x74c 477 + #define QSERDES_V8_LALB_IDAC_STATUS_SM_ON 0x750 478 + #define QSERDES_V8_LALB_IDAC_STATUS_SIGNERROR 0x754 479 + #define QSERDES_V8_LALB_RX_SIGDET_STATUS 0x758 480 + #define QSERDES_V8_LALB_SIGDET_CAL_CODE_STATUS 0x75c 481 + #define QSERDES_V8_LALB_SIGDET_CAL_FSM_DEBUG_STATUS 0x760 482 + #define QSERDES_V8_LALB_CDR_FREQ_LOCK_CNT_STATUS 0x764 483 + #define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_STATUS 0x768 484 + #define QSERDES_V8_LALB_CDR_LOCK_DEBUG_STATUS 0x76c 485 + #define QSERDES_V8_LALB_IDATA_HIGH_STATUS1 0x770 486 + #define QSERDES_V8_LALB_IDATA_HIGH_STATUS2 0x774 487 + #define QSERDES_V8_LALB_IDATA_HIGH_STATUS3 0x778 488 + #define QSERDES_V8_LALB_IDATA_HIGH_STATUS4 0x77c 489 + #define QSERDES_V8_LALB_IDATA_LOW_STATUS1 0x780 490 + #define QSERDES_V8_LALB_IDATA_LOW_STATUS2 0x784 491 + #define QSERDES_V8_LALB_IDATA_LOW_STATUS3 0x788 492 + #define QSERDES_V8_LALB_IDATA_LOW_STATUS4 0x78c 493 + #define QSERDES_V8_LALB_QDATA_STATUS1 0x790 494 + #define QSERDES_V8_LALB_QDATA_STATUS2 0x794 495 + #define QSERDES_V8_LALB_QDATA_STATUS3 0x798 496 + #define QSERDES_V8_LALB_QDATA_STATUS4 0x79c 497 + #define QSERDES_V8_LALB_IA_ERROR_COUNTER_LOW 0x7a0 498 + #define QSERDES_V8_LALB_IA_ERROR_COUNTER_HIGH 0x7a4 499 + #define QSERDES_V8_LALB_EOM_ERR_CNT_LSB_STATUS 0x7a8 500 + #define QSERDES_V8_LALB_EOM_ERR_CNT_MSB_STATUS 0x7ac 501 + #define QSERDES_V8_LALB_EOM_OP_STATUS 0x7b0 502 + #define QSERDES_V8_LALB_AUX_MIXER_INDEX_STATUS 0x7b4 503 + #define QSERDES_V8_LALB_AUX_OFFSET_STATUS 0x7b8 504 + #define QSERDES_V8_LALB_AUXDATA_TB_STATUS 0x7bc 505 + #define QSERDES_V8_LALB_AUX_MIXER_CTRL_0_STATUS 0x7c0 506 + #define QSERDES_V8_LALB_AUX_MIXER_CTRL_90_STATUS 0x7c4 507 + #define QSERDES_V8_LALB_AUX_MIXER_CTRL_180_STATUS 0x7c8 508 + #define QSERDES_V8_LALB_IQ_MIXER_INDEX_STATUS 0x7cc 509 + #define QSERDES_V8_LALB_IQTUNE_FLTR_INDEX_STATUS 0x7d0 510 + #define QSERDES_V8_LALB_IQ_MIXER_CTRL_0_STATUS 0x7d4 511 + #define QSERDES_V8_LALB_IQ_MIXER_CTRL_90_STATUS 0x7d8 512 + #define QSERDES_V8_LALB_IQ_MIXER_CTRL_180_STATUS 0x7dc 513 + #define QSERDES_V8_LALB_READ_EQCODE 0x7e0 514 + #define QSERDES_V8_LALB_READ_OFFSETCODE 0x7e4 515 + #define QSERDES_V8_LALB_VGA_READ_CODE 0x7e8 516 + #define QSERDES_V8_LALB_VTHRESH_READ_CODE 0x7ec 517 + #define QSERDES_V8_LALB_DFE_TAP1_READ_CODE 0x7f0 518 + #define QSERDES_V8_LALB_DFE_TAP2_READ_CODE 0x7f4 519 + #define QSERDES_V8_LALB_DFE_TAP3_READ_CODE 0x7f8 520 + #define QSERDES_V8_LALB_DFE_TAP4_READ_CODE 0x7fc 521 + #define QSERDES_V8_LALB_DFE_TAP5_READ_CODE 0x800 522 + #define QSERDES_V8_LALB_DFE_TAP6_READ_CODE 0x804 523 + #define QSERDES_V8_LALB_DFE_TAP7_READ_CODE 0x808 524 + #define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_BIN_CODE 0x80c 525 + #define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK0_CODE 0x810 526 + #define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK90_CODE 0x814 527 + #define QSERDES_V8_LALB_BLW_READ_CODE 0x818 528 + #define QSERDES_V8_LALB_IA_OFFSET_CAL_DEBUG_STATUS 0x81c 529 + #define QSERDES_V8_LALB_IA_OFFSET_CAL_STATUS 0x820 530 + #define QSERDES_V8_LALB_IVTH_CAL_STATUS 0x824 531 + #define QSERDES_V8_LALB_IVTH_NRZ_EYE_HEIGHT_STATUS 0x828 532 + #define QSERDES_V8_LALB_IVTH_UPPER_EYE_MAX_STATUS 0x82c 533 + #define QSERDES_V8_LALB_IVTH_UPPER_EYE_MIN_STATUS 0x830 534 + #define QSERDES_V8_LALB_IVTH_LOWER_EYE_MAX_STATUS 0x834 535 + #define QSERDES_V8_LALB_IVTH_LOWER_EYE_MIN_STATUS 0x838 536 + #define QSERDES_V8_LALB_IVTH_UP_INIT_CTR_STATUS 0x83c 537 + #define QSERDES_V8_LALB_VTH_I_UP_CNTRL_STATUS 0x840 538 + #define QSERDES_V8_LALB_VTH_I_DN_CNTRL_STATUS 0x844 539 + #define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_STATUS 0x848 540 + #define QSERDES_V8_LALB_DEBUG_BUS0 0x84c 541 + #define QSERDES_V8_LALB_DEBUG_BUS1 0x850 542 + #define QSERDES_V8_LALB_DEBUG_BUS2 0x854 543 + #define QSERDES_V8_LALB_DEBUG_BUS3 0x858 544 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL1 0x85c 545 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL2 0x860 546 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL3 0x864 547 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL4 0x868 548 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL5 0x86c 549 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL6 0x870 550 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL7 0x874 551 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL8 0x878 552 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL9 0x87c 553 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL10 0x880 554 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL11 0x884 555 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL12 0x888 556 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL13 0x88c 557 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL14 0x890 558 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL15 0x894 559 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL16 0x898 560 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL17 0x89c 561 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL18 0x8a0 562 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL19 0x8a4 563 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL20 0x8a8 564 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL21 0x8ac 565 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL22 0x8b0 566 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL23 0x8b4 567 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL24 0x8b8 568 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL25 0x8bc 569 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL26 0x8c0 570 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL27 0x8c4 571 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL28 0x8c8 572 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL29 0x8cc 573 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL30 0x8d0 574 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL31 0x8d4 575 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL32 0x8d8 576 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_1 0x8dc 577 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_2 0x8e0 578 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_3 0x8e4 579 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_4 0x8e8 580 + #define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_5 0x8ec 581 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS1 0x8f0 582 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS2 0x8f4 583 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS3 0x8f8 584 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS4 0x8fc 585 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS5 0x900 586 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS6 0x904 587 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS7 0x908 588 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS8 0x90c 589 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS9 0x910 590 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS10 0x914 591 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS11 0x918 592 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS12 0x91c 593 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS13 0x920 594 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS14 0x924 595 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS15 0x928 596 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS16 0x92c 597 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS17 0x930 598 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS18 0x934 599 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS19 0x938 600 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS20 0x93c 601 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS21 0x940 602 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS22 0x944 603 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS23 0x948 604 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS24 0x94c 605 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS25 0x950 606 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS26 0x954 607 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS27 0x958 608 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS28 0x95c 609 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS29 0x960 610 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS30 0x964 611 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS31 0x968 612 + #define QSERDES_V8_LALB_DIG_BKUP_RO_BUS32 0x96c 613 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS1 0x970 614 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS2 0x974 615 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS3 0x978 616 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS4 0x97c 617 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS5 0x980 618 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS6 0x984 619 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS7 0x988 620 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS8 0x98c 621 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS9 0x990 622 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS10 0x994 623 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS11 0x998 624 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS12 0x99c 625 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS13 0x9a0 626 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS14 0x9a4 627 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS15 0x9a8 628 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS16 0x9ac 629 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS17 0x9b0 630 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS18 0x9b4 631 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS19 0x9b8 632 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS20 0x9bc 633 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS21 0x9c0 634 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS22 0x9c4 635 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS23 0x9c8 636 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS24 0x9cc 637 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS25 0x9d0 638 + #define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS26 0x9d4 639 + #endif /* QCOM_PHY_QMP_QSERDES_V8_LALBH_ */
+71
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ 7 + #define QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ 8 + 9 + #define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX 0x030 10 + #define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX 0x034 11 + #define QSERDES_V8_PCIE_TX_LANE_MODE_1 0x07c 12 + #define QSERDES_V8_PCIE_TX_LANE_MODE_2 0x080 13 + #define QSERDES_V8_PCIE_TX_LANE_MODE_3 0x084 14 + #define QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN 0x0b4 15 + #define QSERDES_V8_PCIE_TX_TX_BAND0 0x0e0 16 + #define QSERDES_V8_PCIE_TX_TX_BAND1 0x0e4 17 + #define QSERDES_V8_PCIE_TX_SEL_10B_8B 0x0f4 18 + #define QSERDES_V8_PCIE_TX_SEL_20B_10B 0x0f8 19 + #define QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN 0x058 20 + #define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1 0x118 21 + #define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2 0x11c 22 + #define QSERDES_V8_PCIE_TX_PHPRE_CTRL 0x128 23 + #define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3 0x148 24 + #define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4 0x14c 25 + 26 + #define QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4 0x0dc 27 + #define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3 0x0ec 28 + #define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4 0x0f0 29 + #define QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS 0x0f4 30 + #define QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1 0x170 31 + #define QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL 0x178 32 + #define QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4 0x1b4 33 + #define QSERDES_V8_PCIE_RX_SIGDET_ENABLES 0x1d8 34 + #define QSERDES_V8_PCIE_RX_SIGDET_LVL 0x1e0 35 + #define QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL 0x0b8 36 + #define QSERDES_V8_PCIE_RX_RX_BAND_CTRL0 0x0bc 37 + #define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0 0x0c4 38 + #define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1 0x0c8 39 + #define QSERDES_V8_PCIE_RX_SVS_MODE_CTRL 0x0b4 40 + #define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1 0x058 41 + #define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2 0x05c 42 + #define QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3 0x084 43 + #define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3 0x098 44 + #define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3 0x0ac 45 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0 0x218 46 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1 0x21c 47 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2 0x220 48 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4 0x228 49 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7 0x234 50 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0 0x260 51 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1 0x264 52 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2 0x268 53 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3 0x26c 54 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4 0x270 55 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0 0x284 56 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1 0x288 57 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2 0x28c 58 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3 0x290 59 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4 0x294 60 + #define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5 0x298 61 + #define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x31c 62 + #define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4 0x320 63 + #define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB 0x11c 64 + #define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB 0x120 65 + #define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23 0x108 66 + #define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4 0x10c 67 + #define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3 0x198 68 + #define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4 0x19c 69 + #define QSERDES_V8_PCIE_RX_GM_CAL 0x1a0 70 + 71 + #endif
+68
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2017, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ 7 + #define QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ 8 + 9 + /* Only for QMP V2 PHY - TX registers */ 10 + #define QSERDES_V2_TX_BIST_MODE_LANENO 0x000 11 + #define QSERDES_V2_TX_CLKBUF_ENABLE 0x008 12 + #define QSERDES_V2_TX_TX_EMP_POST1_LVL 0x00c 13 + #define QSERDES_V2_TX_TX_DRV_LVL 0x01c 14 + #define QSERDES_V2_TX_RESET_TSYNC_EN 0x024 15 + #define QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN 0x028 16 + #define QSERDES_V2_TX_TX_BAND 0x02c 17 + #define QSERDES_V2_TX_SLEW_CNTL 0x030 18 + #define QSERDES_V2_TX_INTERFACE_SELECT 0x034 19 + #define QSERDES_V2_TX_RES_CODE_LANE_TX 0x03c 20 + #define QSERDES_V2_TX_RES_CODE_LANE_RX 0x040 21 + #define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX 0x044 22 + #define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX 0x048 23 + #define QSERDES_V2_TX_DEBUG_BUS_SEL 0x058 24 + #define QSERDES_V2_TX_TRANSCEIVER_BIAS_EN 0x05c 25 + #define QSERDES_V2_TX_HIGHZ_DRVR_EN 0x060 26 + #define QSERDES_V2_TX_TX_POL_INV 0x064 27 + #define QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN 0x068 28 + #define QSERDES_V2_TX_LANE_MODE_1 0x08c 29 + #define QSERDES_V2_TX_LANE_MODE_2 0x090 30 + #define QSERDES_V2_TX_LANE_MODE_3 0x094 31 + #define QSERDES_V2_TX_RCV_DETECT_LVL_2 0x0a4 32 + #define QSERDES_V2_TX_TRAN_DRVR_EMP_EN 0x0c0 33 + #define QSERDES_V2_TX_TX_INTERFACE_MODE 0x0c4 34 + #define QSERDES_V2_TX_VMODE_CTRL1 0x0f0 35 + 36 + /* Only for QMP V2 PHY - RX registers */ 37 + #define QSERDES_V2_RX_UCDR_FO_GAIN 0x008 38 + #define QSERDES_V2_RX_UCDR_SO_GAIN_HALF 0x00c 39 + #define QSERDES_V2_RX_UCDR_SO_GAIN 0x014 40 + #define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_HALF 0x024 41 + #define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028 42 + #define QSERDES_V2_RX_UCDR_SVS_SO_GAIN 0x02c 43 + #define QSERDES_V2_RX_UCDR_FASTLOCK_FO_GAIN 0x030 44 + #define QSERDES_V2_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 45 + #define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c 46 + #define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040 47 + #define QSERDES_V2_RX_UCDR_PI_CONTROLS 0x044 48 + #define QSERDES_V2_RX_RX_TERM_BW 0x07c 49 + #define QSERDES_V2_RX_VGA_CAL_CNTRL1 0x0bc 50 + #define QSERDES_V2_RX_VGA_CAL_CNTRL2 0x0c0 51 + #define QSERDES_V2_RX_RX_EQ_GAIN2_LSB 0x0c8 52 + #define QSERDES_V2_RX_RX_EQ_GAIN2_MSB 0x0cc 53 + #define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d0 54 + #define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4 55 + #define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8 56 + #define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc 57 + #define QSERDES_V2_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8 58 + #define QSERDES_V2_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc 59 + #define QSERDES_V2_RX_SIGDET_ENABLES 0x100 60 + #define QSERDES_V2_RX_SIGDET_CNTRL 0x104 61 + #define QSERDES_V2_RX_SIGDET_LVL 0x108 62 + #define QSERDES_V2_RX_SIGDET_DEGLITCH_CNTRL 0x10c 63 + #define QSERDES_V2_RX_RX_BAND 0x110 64 + #define QSERDES_V2_RX_RX_INTERFACE_MODE 0x11c 65 + #define QSERDES_V2_RX_RX_MODE_00 0x164 66 + #define QSERDES_V2_RX_RX_MODE_01 0x168 67 + 68 + #endif
+96
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
··· 84 84 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL, 85 85 }; 86 86 87 + static const struct qmp_phy_init_tbl milos_ufsphy_serdes[] = { 88 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9), 89 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16), 90 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11), 91 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), 92 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01), 93 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), 94 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a), 95 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17), 96 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04), 97 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e), 98 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00), 99 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82), 100 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14), 101 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), 102 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18), 103 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff), 104 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c), 105 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98), 106 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14), 107 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18), 108 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18), 109 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32), 110 + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f), 111 + }; 112 + 113 + static const struct qmp_phy_init_tbl milos_ufsphy_tx[] = { 114 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05), 115 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07), 116 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e), 117 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0xcc), 118 + }; 119 + 120 + static const struct qmp_phy_init_tbl milos_ufsphy_rx[] = { 121 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c), 122 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e), 123 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f), 124 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce), 125 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce), 126 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18), 127 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a), 128 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f), 129 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60), 130 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e), 131 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60), 132 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e), 133 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e), 134 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36), 135 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02), 136 + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94), 137 + }; 138 + 139 + static const struct qmp_phy_init_tbl milos_ufsphy_pcs[] = { 140 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 141 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 142 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b), 143 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), 144 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68), 145 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04), 146 + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04), 147 + }; 148 + 87 149 static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = { 88 150 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), 89 151 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7), ··· 1227 1165 } 1228 1166 1229 1167 /* Regulator bulk data with load values for specific configurations */ 1168 + static const struct regulator_bulk_data milos_ufsphy_vreg_l[] = { 1169 + { .supply = "vdda-phy", .init_load_uA = 140120 }, 1170 + { .supply = "vdda-pll", .init_load_uA = 18340 }, 1171 + }; 1172 + 1230 1173 static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = { 1231 1174 { .supply = "vdda-phy", .init_load_uA = 51400 }, 1232 1175 { .supply = "vdda-pll", .init_load_uA = 14600 }, ··· 1323 1256 .rx = 0x1200, 1324 1257 .tx2 = 0x1800, 1325 1258 .rx2 = 0x1a00, 1259 + }; 1260 + 1261 + static const struct qmp_phy_cfg milos_ufsphy_cfg = { 1262 + .lanes = 2, 1263 + 1264 + .offsets = &qmp_ufs_offsets_v6, 1265 + .max_supported_gear = UFS_HS_G4, 1266 + 1267 + .tbls = { 1268 + .serdes = milos_ufsphy_serdes, 1269 + .serdes_num = ARRAY_SIZE(milos_ufsphy_serdes), 1270 + .tx = milos_ufsphy_tx, 1271 + .tx_num = ARRAY_SIZE(milos_ufsphy_tx), 1272 + .rx = milos_ufsphy_rx, 1273 + .rx_num = ARRAY_SIZE(milos_ufsphy_rx), 1274 + .pcs = milos_ufsphy_pcs, 1275 + .pcs_num = ARRAY_SIZE(milos_ufsphy_pcs), 1276 + }, 1277 + .tbls_hs_b = { 1278 + .serdes = sm8550_ufsphy_hs_b_serdes, 1279 + .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes), 1280 + }, 1281 + 1282 + .vreg_list = milos_ufsphy_vreg_l, 1283 + .num_vregs = ARRAY_SIZE(milos_ufsphy_vreg_l), 1284 + .regs = ufsphy_v6_regs_layout, 1326 1285 }; 1327 1286 1328 1287 static const struct qmp_phy_cfg msm8996_ufsphy_cfg = { ··· 2259 2166 2260 2167 static const struct of_device_id qmp_ufs_of_match_table[] = { 2261 2168 { 2169 + .compatible = "qcom,milos-qmp-ufs-phy", 2170 + .data = &milos_ufsphy_cfg, 2171 + }, { 2262 2172 .compatible = "qcom,msm8996-qmp-ufs-phy", 2263 2173 .data = &msm8996_ufsphy_cfg, 2264 2174 }, {
+169 -21
drivers/phy/qualcomm/phy-qcom-qmp-usb.c
··· 28 28 #include "phy-qcom-qmp-pcs-usb-v5.h" 29 29 #include "phy-qcom-qmp-pcs-usb-v6.h" 30 30 #include "phy-qcom-qmp-pcs-usb-v7.h" 31 + #include "phy-qcom-qmp-pcs-usb-v8.h" 31 32 32 33 #define PHY_INIT_COMPLETE_TIMEOUT 10000 33 34 ··· 108 107 /* In PCS_USB */ 109 108 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V7_PCS_USB3_AUTONOMOUS_MODE_CTRL, 110 109 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V7_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, 110 + }; 111 + 112 + static const struct qmp_phy_init_tbl glymur_usb3_uniphy_serdes_tbl[] = { 113 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0xc0), 114 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), 115 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x02), 116 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), 117 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), 118 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), 119 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x16), 120 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x41), 121 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x41), 122 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE1, 0x00), 123 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), 124 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x75), 125 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), 126 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), 127 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE1, 0x25), 128 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE1, 0x02), 129 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c), 130 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f), 131 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c), 132 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), 133 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xc0), 134 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), 135 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x02), 136 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), 137 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), 138 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x08), 139 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x1a), 140 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), 141 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE0, 0x00), 142 + 143 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0x55), 144 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0x75), 145 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), 146 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE0, 0x25), 147 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE0, 0x02), 148 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), 149 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_EN_CENTER, 0x01), 150 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), 151 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), 152 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_BUF_ENABLE, 0x0c), 153 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x1a), 154 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x14), 155 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04), 156 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0x20), 157 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), 158 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6), 159 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a), 160 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36), 161 + QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADDITIONAL_MISC, 0x0c), 162 + }; 163 + 164 + static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_tbl[] = { 165 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG1, 0xc4), 166 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG2, 0x89), 167 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG3, 0x20), 168 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG6, 0x13), 169 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_REFGEN_REQ_CONFIG1, 0x21), 170 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RX_SIGDET_LVL, 0x55), 171 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), 172 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), 173 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_CDR_RESET_TIME, 0x0a), 174 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG1, 0xd4), 175 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG2, 0x30), 176 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_PCS_TX_RX_CONFIG, 0x0c), 177 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG1, 0x4b), 178 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG5, 0x10), 179 + }; 180 + 181 + static const struct qmp_phy_init_tbl glymur_usb3_uniphy_tx_tbl[] = { 182 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_TX, 0x00), 183 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_RX, 0x00), 184 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x1f), 185 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x09), 186 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_1, 0xf5), 187 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_3, 0x11), 188 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_4, 0x30), 189 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_5, 0x5f), 190 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RCV_DETECT_LVL_2, 0x12), 191 + QMP_PHY_INIT_CFG(QSERDES_V8_TX_PI_QEC_CTRL, 0x21), 192 + }; 193 + 194 + static const struct qmp_phy_init_tbl glymur_usb3_uniphy_rx_tbl[] = { 195 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FO_GAIN, 0x09), 196 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_GAIN, 0x04), 197 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f), 198 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f), 199 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff), 200 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f), 201 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_PI_CONTROLS, 0x99), 202 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH1, 0x08), 203 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH2, 0x08), 204 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN1, 0x00), 205 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN2, 0x0a), 206 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_AUX_DATA_TCOARSE_TFINE, 0x20), 207 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL1, 0x54), 208 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL2, 0x0f), 209 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_GM_CAL, 0x1b), 210 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e), 211 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), 212 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a), 213 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_LOW, 0x07), 214 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 215 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27), 216 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_ENABLES, 0x0c), 217 + 218 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CNTRL, 0x04), 219 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), 220 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_LOW, 0xbf), 221 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH, 0xbf), 222 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH2, 0xff), 223 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH3, 0xdf), 224 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH4, 0xed), 225 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_LOW, 0x19), 226 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH, 0x09), 227 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH2, 0x91), 228 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH3, 0xb7), 229 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH4, 0xaa), 230 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_EN_TIMER, 0x04), 231 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), 232 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DCC_CTRL1, 0x0c), 233 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VTH_CODE, 0x10), 234 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_CTRL1, 0x14), 235 + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_TRIM, 0x08), 236 + }; 237 + 238 + static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_usb_tbl[] = { 239 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), 240 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), 241 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_WAIT_TIME, 0x75), 242 + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RCVR_DTCT_DLY_U3_L, 0x40), 111 243 }; 112 244 113 245 static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = { ··· 1400 1266 int pcs_usb_tbl_num; 1401 1267 1402 1268 /* regulators to be requested */ 1403 - const char * const *vreg_list; 1269 + const struct regulator_bulk_data *vreg_list; 1404 1270 int num_vregs; 1405 1271 1406 1272 /* array of registers with different offsets */ ··· 1478 1344 }; 1479 1345 1480 1346 /* list of regulators */ 1481 - static const char * const qmp_phy_vreg_l[] = { 1482 - "vdda-phy", "vdda-pll", 1347 + static const struct regulator_bulk_data qmp_phy_vreg_l[] = { 1348 + { .supply = "vdda-phy", .init_load_uA = 21800, }, 1349 + { .supply = "vdda-pll", .init_load_uA = 36000, }, 1483 1350 }; 1484 1351 1485 1352 static const struct qmp_usb_offsets qmp_usb_offsets_v3 = { ··· 1533 1398 static const struct qmp_usb_offsets qmp_usb_offsets_v7 = { 1534 1399 .serdes = 0, 1535 1400 .pcs = 0x0200, 1401 + .pcs_usb = 0x1200, 1402 + .tx = 0x0e00, 1403 + .rx = 0x1000, 1404 + }; 1405 + 1406 + static const struct qmp_usb_offsets qmp_usb_offsets_v8 = { 1407 + .serdes = 0, 1408 + .pcs = 0x0400, 1536 1409 .pcs_usb = 0x1200, 1537 1410 .tx = 0x0e00, 1538 1411 .rx = 0x1000, ··· 1847 1704 .regs = qmp_v7_usb3phy_regs_layout, 1848 1705 }; 1849 1706 1707 + static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { 1708 + .offsets = &qmp_usb_offsets_v8, 1709 + 1710 + .serdes_tbl = glymur_usb3_uniphy_serdes_tbl, 1711 + .serdes_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_serdes_tbl), 1712 + .tx_tbl = glymur_usb3_uniphy_tx_tbl, 1713 + .tx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_tx_tbl), 1714 + .rx_tbl = glymur_usb3_uniphy_rx_tbl, 1715 + .rx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_rx_tbl), 1716 + .pcs_tbl = glymur_usb3_uniphy_pcs_tbl, 1717 + .pcs_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_tbl), 1718 + .pcs_usb_tbl = glymur_usb3_uniphy_pcs_usb_tbl, 1719 + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_usb_tbl), 1720 + .vreg_list = qmp_phy_vreg_l, 1721 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1722 + .regs = qmp_v7_usb3phy_regs_layout, 1723 + }; 1724 + 1850 1725 static int qmp_usb_serdes_init(struct qmp_usb *qmp) 1851 1726 { 1852 1727 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 2147 1986 qmp_usb_runtime_resume, NULL) 2148 1987 }; 2149 1988 2150 - static int qmp_usb_vreg_init(struct qmp_usb *qmp) 2151 - { 2152 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2153 - struct device *dev = qmp->dev; 2154 - int num = cfg->num_vregs; 2155 - int i; 2156 - 2157 - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 2158 - if (!qmp->vregs) 2159 - return -ENOMEM; 2160 - 2161 - for (i = 0; i < num; i++) 2162 - qmp->vregs[i].supply = cfg->vreg_list[i]; 2163 - 2164 - return devm_regulator_bulk_get(dev, num, qmp->vregs); 2165 - } 2166 - 2167 1989 static int qmp_usb_reset_init(struct qmp_usb *qmp, 2168 1990 const char *const *reset_list, 2169 1991 int num_resets) ··· 2395 2251 if (!qmp->cfg) 2396 2252 return -EINVAL; 2397 2253 2398 - ret = qmp_usb_vreg_init(qmp); 2254 + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, 2255 + qmp->cfg->vreg_list, &qmp->vregs); 2399 2256 if (ret) 2400 2257 return ret; 2401 2258 ··· 2447 2302 2448 2303 static const struct of_device_id qmp_usb_of_match_table[] = { 2449 2304 { 2305 + .compatible = "qcom,glymur-qmp-usb3-uni-phy", 2306 + .data = &glymur_usb3_uniphy_cfg, 2307 + }, { 2450 2308 .compatible = "qcom,ipq5424-qmp-usb3-phy", 2451 2309 .data = &ipq9574_usb3phy_cfg, 2452 2310 }, {
+33
drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_USB43_PCS_V8_H_ 7 + #define QCOM_PHY_QMP_USB43_PCS_V8_H_ 8 + 9 + #define QPHY_V8_USB43_PCS_SW_RESET 0x000 10 + #define QPHY_V8_USB43_PCS_PCS_STATUS1 0x014 11 + #define QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL 0x040 12 + #define QPHY_V8_USB43_PCS_START_CONTROL 0x044 13 + #define QPHY_V8_USB43_PCS_POWER_STATE_CONFIG1 0x090 14 + #define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1 0x0c4 15 + #define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2 0x0c8 16 + #define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3 0x0cc 17 + #define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6 0x0d8 18 + #define QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1 0x0dc 19 + #define QPHY_V8_USB43_PCS_RX_SIGDET_LVL 0x188 20 + #define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 21 + #define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 22 + #define QPHY_V8_USB43_PCS_RATE_SLEW_CNTRL1 0x198 23 + #define QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME 0x1ac 24 + #define QPHY_V8_USB43_PCS_RX_CONFIG 0x1b0 25 + #define QPHY_V8_USB43_PCS_TSYNC_DLY_TIME 0x1b4 26 + #define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1 0x1c0 27 + #define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2 0x1c4 28 + #define QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG 0x1d0 29 + #define QPHY_V8_USB43_PCS_EQ_CONFIG1 0x1dc 30 + #define QPHY_V8_USB43_PCS_EQ_CONFIG2 0x1e0 31 + #define QPHY_V8_USB43_PCS_EQ_CONFIG5 0x1ec 32 + 33 + #endif
+224
drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ 7 + #define QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ 8 + 9 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1 0x000 10 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1 0x004 11 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE1 0x008 12 + #define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE1 0x00c 13 + #define QSERDES_V8_USB43_COM_CP_CTRL_MODE1 0x010 14 + #define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1 0x014 15 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1 0x018 16 + #define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1 0x01c 17 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1 0x020 18 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1 0x024 19 + #define QSERDES_V8_USB43_COM_DEC_START_MODE1 0x028 20 + #define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1 0x02c 21 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1 0x030 22 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1 0x034 23 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1 0x038 24 + #define QSERDES_V8_USB43_COM_HSCLK_SEL_1 0x03c 25 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1 0x040 26 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE1 0x044 27 + #define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1 0x048 28 + #define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1 0x04c 29 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x050 30 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x054 31 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 32 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c 33 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0 0x060 34 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0 0x064 35 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE0 0x068 36 + #define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE0 0x06c 37 + #define QSERDES_V8_USB43_COM_CP_CTRL_MODE0 0x070 38 + #define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0 0x074 39 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0 0x078 40 + #define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0 0x07c 41 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0 0x080 42 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0 0x084 43 + #define QSERDES_V8_USB43_COM_DEC_START_MODE0 0x088 44 + #define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0 0x08c 45 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0 0x090 46 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0 0x094 47 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0 0x098 48 + #define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1 0x09c 49 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 50 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 51 + #define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0 0x0a8 52 + #define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0 0x0ac 53 + #define QSERDES_V8_USB43_COM_ATB_SEL1 0x0b0 54 + #define QSERDES_V8_USB43_COM_ATB_SEL2 0x0b4 55 + #define QSERDES_V8_USB43_COM_FREQ_UPDATE 0x0b8 56 + #define QSERDES_V8_USB43_COM_BG_TIMER 0x0bc 57 + #define QSERDES_V8_USB43_COM_SSC_EN_CENTER 0x0c0 58 + #define QSERDES_V8_USB43_COM_SSC_ADJ_PER1 0x0c4 59 + #define QSERDES_V8_USB43_COM_SSC_ADJ_PER2 0x0c8 60 + #define QSERDES_V8_USB43_COM_SSC_PER1 0x0cc 61 + #define QSERDES_V8_USB43_COM_SSC_PER2 0x0d0 62 + #define QSERDES_V8_USB43_COM_POST_DIV 0x0d4 63 + #define QSERDES_V8_USB43_COM_POST_DIV_MUX 0x0d8 64 + #define QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN 0x0dc 65 + #define QSERDES_V8_USB43_COM_CLK_ENABLE1 0x0e0 66 + #define QSERDES_V8_USB43_COM_SYS_CLK_CTRL 0x0e4 67 + #define QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE 0x0e8 68 + #define QSERDES_V8_USB43_COM_PLL_EN 0x0ec 69 + #define QSERDES_V8_USB43_COM_DEBUG_BUS_OVRD 0x0f0 70 + #define QSERDES_V8_USB43_COM_PLL_IVCO 0x0f4 71 + #define QSERDES_V8_USB43_COM_PLL_IVCO_MODE1 0x0f8 72 + #define QSERDES_V8_USB43_COM_CMN_IETRIM 0x0fc 73 + #define QSERDES_V8_USB43_COM_CMN_IPTRIM 0x100 74 + #define QSERDES_V8_USB43_COM_EP_CLOCK_DETECT_CTRL 0x104 75 + #define QSERDES_V8_USB43_COM_PLL_CNTRL 0x108 76 + #define QSERDES_V8_USB43_COM_BIAS_EN_CTRL_BY_PSM 0x10c 77 + #define QSERDES_V8_USB43_COM_SYSCLK_EN_SEL 0x110 78 + #define QSERDES_V8_USB43_COM_CML_SYSCLK_SEL 0x114 79 + #define QSERDES_V8_USB43_COM_RESETSM_CNTRL 0x118 80 + #define QSERDES_V8_USB43_COM_RESETSM_CNTRL2 0x11c 81 + #define QSERDES_V8_USB43_COM_LOCK_CMP_EN 0x120 82 + #define QSERDES_V8_USB43_COM_LOCK_CMP_CFG 0x124 83 + #define QSERDES_V8_USB43_COM_INTEGLOOP_INITVAL 0x128 84 + #define QSERDES_V8_USB43_COM_INTEGLOOP_EN 0x12c 85 + #define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN0 0x130 86 + #define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN1 0x134 87 + #define QSERDES_V8_USB43_COM_VCOCAL_DEADMAN_CTRL 0x138 88 + #define QSERDES_V8_USB43_COM_VCO_TUNE_CTRL 0x13c 89 + #define QSERDES_V8_USB43_COM_VCO_TUNE_MAP 0x140 90 + #define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL1 0x144 91 + #define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL2 0x148 92 + #define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL1 0x14c 93 + #define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL2 0x150 94 + #define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL1 0x154 95 + #define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL2 0x158 96 + #define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER1 0x15c 97 + #define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER2 0x160 98 + #define QSERDES_V8_USB43_COM_CLK_SELECT 0x164 99 + #define QSERDES_V8_USB43_COM_PLL_ANALOG 0x168 100 + #define QSERDES_V8_USB43_COM_SW_RESET 0x16c 101 + #define QSERDES_V8_USB43_COM_CORE_CLK_EN 0x170 102 + #define QSERDES_V8_USB43_COM_CMN_CONFIG_1 0x174 103 + #define QSERDES_V8_USB43_COM_CMN_CONFIG_3 0x178 104 + #define QSERDES_V8_USB43_COM_CMN_RATE_OVERRIDE 0x17c 105 + #define QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL 0x180 106 + #define QSERDES_V8_USB43_COM_DEBUG_BUS_SEL 0x184 107 + #define QSERDES_V8_USB43_COM_CMN_MISC1 0x188 108 + #define QSERDES_V8_USB43_COM_CMN_MODE 0x18c 109 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD 0x190 110 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD1 0x194 111 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD2 0x198 112 + #define QSERDES_V8_USB43_COM_VCO_DC_LEVEL_CTRL 0x19c 113 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1 0x1a0 114 + #define QSERDES_V8_USB43_COM_ADDITIONAL_CTRL_1 0x1a4 115 + #define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a8 116 + #define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_2 0x1ac 117 + #define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_3 0x1b0 118 + #define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_4 0x1b4 119 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC 0x1b8 120 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_2 0x1bc 121 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_3 0x1c0 122 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_4 0x1c4 123 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_5 0x1c8 124 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE2 0x1cc 125 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE2 0x1d0 126 + #define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE2 0x1d4 127 + #define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE2 0x1d8 128 + #define QSERDES_V8_USB43_COM_CP_CTRL_MODE2 0x1dc 129 + #define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE2 0x1e0 130 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE2 0x1e4 131 + #define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE2 0x1e8 132 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE2 0x1ec 133 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE2 0x1f0 134 + #define QSERDES_V8_USB43_COM_DEC_START_MODE2 0x1f4 135 + #define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE2 0x1f8 136 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE2 0x1fc 137 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE2 0x200 138 + #define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE2 0x204 139 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE2 0x208 140 + #define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE2 0x20c 141 + #define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE2 0x210 142 + #define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE2 0x214 143 + #define QSERDES_V8_USB43_COM_PLL_IVCO_MODE2 0x218 144 + #define QSERDES_V8_USB43_COM_HSCLK_SEL_2 0x21c 145 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE2 0x220 146 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE2 0x224 147 + #define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_2 0x228 148 + #define QSERDES_V8_USB43_COM_CMN_CONFIG_2 0x22c 149 + #define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_2 0x230 150 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_0 0x234 151 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_1 0x238 152 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_2 0x23c 153 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_3 0x240 154 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_4 0x244 155 + #define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_5 0x248 156 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE0 0x24c 157 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE0 0x250 158 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE1 0x254 159 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE1 0x258 160 + #define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE2 0x25c 161 + #define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE2 0x260 162 + #define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_0 0x264 163 + #define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_1 0x268 164 + #define QSERDES_V8_USB43_COM_ADAPTIVE_ANALOG_CONFIG 0x26c 165 + #define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE0 0x270 166 + #define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x274 167 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x278 168 + #define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE1 0x27c 169 + #define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x280 170 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x284 171 + #define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE2 0x288 172 + #define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE2 0x28c 173 + #define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE2 0x290 174 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD3 0x294 175 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD4 0x298 176 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD5 0x29c 177 + #define QSERDES_V8_USB43_COM_CMN_MODE_CONTD6 0x2a0 178 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_6 0x2a4 179 + #define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_7 0x2a8 180 + #define QSERDES_V8_USB43_COM_VCO_WAIT_CYCLES 0x2ac 181 + #define QSERDES_V8_USB43_COM_BIAS_WAIT_CYCLES 0x2b0 182 + #define QSERDES_V8_USB43_COM_AUX_CLK_PSM_ENABLE 0x2b4 183 + #define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO 0x2b8 184 + #define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_1 0x2bc 185 + #define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_2 0x2c0 186 + #define QSERDES_V8_USB43_COM_LDO_CAL_1 0x2c4 187 + #define QSERDES_V8_USB43_COM_LDO_CAL_2 0x2c8 188 + #define QSERDES_V8_USB43_COM_LDO_CAL_3 0x2cc 189 + #define QSERDES_V8_USB43_COM_LDO_CAL_4 0x2d0 190 + #define QSERDES_V8_USB43_COM_LDO_CAL_5 0x2d4 191 + #define QSERDES_V8_USB43_COM_DCC_CAL_1 0x2d8 192 + #define QSERDES_V8_USB43_COM_DCC_CAL_2 0x2dc 193 + #define QSERDES_V8_USB43_COM_DCC_CAL_3 0x2e0 194 + #define QSERDES_V8_USB43_COM_DCC_CAL_4 0x2e4 195 + #define QSERDES_V8_USB43_COM_DCC_CAL_5 0x2e8 196 + #define QSERDES_V8_USB43_COM_DCC_CAL_6 0x2ec 197 + #define QSERDES_V8_USB43_COM_PSM_CAL_EN 0x2f0 198 + #define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1 0x2f4 199 + #define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_2 0x2f8 200 + #define QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL 0x2fc 201 + #define QSERDES_V8_USB43_COM_DCC_CAL_7 0x300 202 + #define QSERDES_V8_USB43_COM_DCC_CAL_8 0x304 203 + #define QSERDES_V8_USB43_COM_DCC_CAL_9 0x308 204 + #define QSERDES_V8_USB43_COM_MODE_OPERATION_STATUS 0x30c 205 + #define QSERDES_V8_USB43_COM_SYSCLK_DET_COMP_STATUS 0x310 206 + #define QSERDES_V8_USB43_COM_CMN_STATUS 0x314 207 + #define QSERDES_V8_USB43_COM_RESET_SM_STATUS 0x318 208 + #define QSERDES_V8_USB43_COM_RESTRIM_CODE_STATUS 0x31c 209 + #define QSERDES_V8_USB43_COM_PLLCAL_CODE1_STATUS 0x320 210 + #define QSERDES_V8_USB43_COM_PLLCAL_CODE2_STATUS 0x324 211 + #define QSERDES_V8_USB43_COM_INTEGLOOP_BINCODE_STATUS 0x328 212 + #define QSERDES_V8_USB43_COM_DEBUG_BUS0 0x32c 213 + #define QSERDES_V8_USB43_COM_DEBUG_BUS1 0x330 214 + #define QSERDES_V8_USB43_COM_DEBUG_BUS2 0x334 215 + #define QSERDES_V8_USB43_COM_DEBUG_BUS3 0x338 216 + #define QSERDES_V8_USB43_COM_C_READY_STATUS 0x33c 217 + #define QSERDES_V8_USB43_COM_READ_DUMMY_1 0x340 218 + #define QSERDES_V8_USB43_COM_READ_DUMMY_2 0x344 219 + #define QSERDES_V8_USB43_COM_READ_DUMMY_3 0x348 220 + #define QSERDES_V8_USB43_COM_IVCO_CAL_CODE_STATUS 0x34c 221 + #define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_2 0x350 222 + #define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_3 0x354 223 + 224 + #endif
+980 -91
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/usb/typec.h> 24 24 #include <linux/usb/typec_mux.h> 25 + #include <dt-bindings/phy/phy-qcom-qmp.h> 25 26 26 27 #include "phy-qcom-qmp-common.h" 27 28 28 29 #include "phy-qcom-qmp.h" 29 30 #include "phy-qcom-qmp-pcs-misc-v3.h" 30 31 32 + #include "phy-qcom-qmp-dp-phy.h" 33 + #include "phy-qcom-qmp-dp-phy-v2.h" 34 + 31 35 #define PHY_INIT_COMPLETE_TIMEOUT 10000 36 + #define SW_PORTSELECT_VAL BIT(0) 37 + #define SW_PORTSELECT_MUX BIT(1) 32 38 33 39 /* set of registers with offsets different per-PHY */ 34 40 enum qphy_reg_layout { ··· 290 284 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88), 291 285 }; 292 286 287 + static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl[] = { 288 + QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), 289 + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37), 290 + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00), 291 + QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), 292 + QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f), 293 + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e), 294 + QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f), 295 + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06), 296 + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), 297 + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), 298 + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), 299 + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), 300 + QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), 301 + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40), 302 + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 303 + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), 304 + QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08), 305 + QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05), 306 + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), 307 + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00), 308 + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00), 309 + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), 310 + QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f), 311 + QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02), 312 + }; 313 + 314 + static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_rbr[] = { 315 + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c), 316 + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), 317 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 318 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), 319 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), 320 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf), 321 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21), 322 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 323 + }; 324 + 325 + static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr[] = { 326 + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24), 327 + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), 328 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 329 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), 330 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), 331 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f), 332 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38), 333 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 334 + }; 335 + 336 + static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr2[] = { 337 + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20), 338 + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c), 339 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), 340 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), 341 + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a), 342 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f), 343 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70), 344 + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), 345 + }; 346 + 347 + static const struct qmp_phy_init_tbl qmp_v2_dp_tx_tbl[] = { 348 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRANSCEIVER_BIAS_EN, 0x1a), 349 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_VMODE_CTRL1, 0x40), 350 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN, 0x30), 351 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_INTERFACE_SELECT, 0x3d), 352 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_CLKBUF_ENABLE, 0x0f), 353 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RESET_TSYNC_EN, 0x03), 354 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRAN_DRVR_EMP_EN, 0x03), 355 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), 356 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_INTERFACE_MODE, 0x00), 357 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_EMP_POST1_LVL, 0x2b), 358 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_DRV_LVL, 0x2f), 359 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_BAND, 0x4), 360 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX, 0x12), 361 + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX, 0x12), 362 + }; 363 + 293 364 struct qmp_usbc_offsets { 294 365 u16 serdes; 295 366 u16 pcs; ··· 376 293 /* for PHYs with >= 2 lanes */ 377 294 u16 tx2; 378 295 u16 rx2; 296 + 297 + u16 dp_serdes; 298 + u16 dp_txa; 299 + u16 dp_txb; 300 + u16 dp_dp_phy; 379 301 }; 380 302 381 - /* struct qmp_phy_cfg - per-PHY initialization config */ 303 + struct qmp_usbc; 382 304 struct qmp_phy_cfg { 383 305 const struct qmp_usbc_offsets *offsets; 384 306 385 - /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ 307 + /* Init sequence for USB PHY blocks - serdes, tx, rx, pcs */ 386 308 const struct qmp_phy_init_tbl *serdes_tbl; 387 309 int serdes_tbl_num; 388 310 const struct qmp_phy_init_tbl *tx_tbl; ··· 397 309 const struct qmp_phy_init_tbl *pcs_tbl; 398 310 int pcs_tbl_num; 399 311 400 - /* regulators to be requested */ 401 - const char * const *vreg_list; 312 + /* Init sequence for DP PHY blocks - serdes, tx, rbr, hbr, hbr2 */ 313 + const struct qmp_phy_init_tbl *dp_serdes_tbl; 314 + int dp_serdes_tbl_num; 315 + const struct qmp_phy_init_tbl *dp_tx_tbl; 316 + int dp_tx_tbl_num; 317 + const struct qmp_phy_init_tbl *serdes_tbl_rbr; 318 + int serdes_tbl_rbr_num; 319 + const struct qmp_phy_init_tbl *serdes_tbl_hbr; 320 + int serdes_tbl_hbr_num; 321 + const struct qmp_phy_init_tbl *serdes_tbl_hbr2; 322 + int serdes_tbl_hbr2_num; 323 + 324 + const u8 (*swing_tbl)[4][4]; 325 + const u8 (*pre_emphasis_tbl)[4][4]; 326 + 327 + /* DP PHY callbacks */ 328 + void (*dp_aux_init)(struct qmp_usbc *qmp); 329 + void (*configure_dp_tx)(struct qmp_usbc *qmp); 330 + int (*configure_dp_phy)(struct qmp_usbc *qmp); 331 + int (*calibrate_dp_phy)(struct qmp_usbc *qmp); 332 + 333 + const char * const *reset_list; 334 + int num_resets; 335 + const struct regulator_bulk_data *vreg_list; 402 336 int num_vregs; 403 337 404 338 /* array of registers with different offsets */ ··· 439 329 void __iomem *rx; 440 330 void __iomem *tx2; 441 331 void __iomem *rx2; 442 - 443 - struct regmap *tcsr_map; 444 - u32 vls_clamp_reg; 332 + void __iomem *dp_dp_phy; 333 + void __iomem *dp_tx; 334 + void __iomem *dp_tx2; 335 + void __iomem *dp_serdes; 445 336 446 337 struct clk *pipe_clk; 338 + struct clk_fixed_rate pipe_clk_fixed; 339 + 340 + struct clk_hw dp_link_hw; 341 + struct clk_hw dp_pixel_hw; 447 342 struct clk_bulk_data *clks; 448 343 int num_clks; 449 344 int num_resets; 450 345 struct reset_control_bulk_data *resets; 451 346 struct regulator_bulk_data *vregs; 452 347 348 + struct regmap *tcsr_map; 349 + u32 vls_clamp_reg; 350 + u32 dp_phy_mode_reg; 351 + 453 352 struct mutex phy_mutex; 454 353 354 + struct phy *usb_phy; 455 355 enum phy_mode mode; 456 356 unsigned int usb_init_count; 457 357 458 - struct phy *phy; 459 - 460 - struct clk_fixed_rate pipe_clk_fixed; 358 + struct phy *dp_phy; 359 + unsigned int dp_aux_cfg; 360 + struct phy_configure_opts_dp dp_opts; 361 + unsigned int dp_init_count; 461 362 462 363 struct typec_switch_dev *sw; 463 364 enum typec_orientation orientation; ··· 512 391 "phy_phy", "phy", 513 392 }; 514 393 515 - /* list of regulators */ 516 - static const char * const qmp_phy_vreg_l[] = { 517 - "vdda-phy", "vdda-pll", 394 + static const char * const usb3dpphy_reset_l[] = { 395 + "phy_phy", "dp_phy", 396 + }; 397 + 398 + static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = { 399 + { .supply = "vdda-phy", .init_load_uA = 68600 }, 400 + { .supply = "vdda-pll", .init_load_uA = 14200 }, 401 + }; 402 + 403 + static const struct regulator_bulk_data qmp_phy_sm2290_vreg_l[] = { 404 + { .supply = "vdda-phy", .init_load_uA = 66100 }, 405 + { .supply = "vdda-pll", .init_load_uA = 13300 }, 406 + }; 407 + 408 + static const struct regulator_bulk_data qmp_phy_qcs615_vreg_l[] = { 409 + { .supply = "vdda-phy", .init_load_uA = 50000 }, 410 + { .supply = "vdda-pll", .init_load_uA = 20000 }, 518 411 }; 519 412 520 413 static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { ··· 539 404 .rx = 0x400, 540 405 .tx2 = 0x600, 541 406 .rx2 = 0x800, 407 + }; 408 + 409 + static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = { 410 + .serdes = 0x0, 411 + .pcs = 0xc00, 412 + .pcs_misc = 0xa00, 413 + .tx = 0x200, 414 + .rx = 0x400, 415 + .tx2 = 0x600, 416 + .rx2 = 0x800, 417 + .dp_serdes = 0x1c00, 418 + .dp_txa = 0x1400, 419 + .dp_txb = 0x1800, 420 + .dp_dp_phy = 0x1000, 421 + }; 422 + 423 + static const u8 qmp_v2_dp_pre_emphasis_hbr2_rbr[4][4] = { 424 + {0x00, 0x0b, 0x12, 0xff}, 425 + {0x00, 0x0a, 0x12, 0xff}, 426 + {0x00, 0x0c, 0xff, 0xff}, 427 + {0xff, 0xff, 0xff, 0xff} 428 + }; 429 + 430 + static const u8 qmp_v2_dp_voltage_swing_hbr2_rbr[4][4] = { 431 + {0x07, 0x0f, 0x14, 0xff}, 432 + {0x11, 0x1d, 0x1f, 0xff}, 433 + {0x18, 0x1f, 0xff, 0xff}, 434 + {0xff, 0xff, 0xff, 0xff} 542 435 }; 543 436 544 437 static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { ··· 580 417 .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), 581 418 .pcs_tbl = msm8998_usb3_pcs_tbl, 582 419 .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), 583 - .vreg_list = qmp_phy_vreg_l, 584 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 420 + .reset_list = usb3phy_reset_l, 421 + .num_resets = ARRAY_SIZE(usb3phy_reset_l), 422 + .vreg_list = qmp_phy_msm8998_vreg_l, 423 + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), 585 424 .regs = qmp_v3_usb3phy_regs_layout, 586 425 }; 587 426 ··· 598 433 .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), 599 434 .pcs_tbl = qcm2290_usb3_pcs_tbl, 600 435 .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), 601 - .vreg_list = qmp_phy_vreg_l, 602 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 436 + .reset_list = usb3phy_reset_l, 437 + .num_resets = ARRAY_SIZE(usb3phy_reset_l), 438 + .vreg_list = qmp_phy_sm2290_vreg_l, 439 + .num_vregs = ARRAY_SIZE(qmp_phy_sm2290_vreg_l), 603 440 .regs = qmp_v3_usb3phy_regs_layout_qcm2290, 604 441 }; 605 442 ··· 616 449 .rx_tbl_num = ARRAY_SIZE(sdm660_usb3_rx_tbl), 617 450 .pcs_tbl = qcm2290_usb3_pcs_tbl, 618 451 .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), 619 - .vreg_list = qmp_phy_vreg_l, 620 - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 452 + .reset_list = usb3phy_reset_l, 453 + .num_resets = ARRAY_SIZE(usb3phy_reset_l), 454 + .vreg_list = qmp_phy_msm8998_vreg_l, 455 + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), 621 456 .regs = qmp_v3_usb3phy_regs_layout_qcm2290, 622 457 }; 623 458 624 - static int qmp_usbc_init(struct phy *phy) 459 + static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { 460 + .offsets = &qmp_usbc_offsets_v3_qcm2290, 461 + 462 + .serdes_tbl = qcm2290_usb3_serdes_tbl, 463 + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), 464 + .tx_tbl = qcm2290_usb3_tx_tbl, 465 + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), 466 + .rx_tbl = qcm2290_usb3_rx_tbl, 467 + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), 468 + .pcs_tbl = qcm2290_usb3_pcs_tbl, 469 + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), 470 + .reset_list = usb3phy_reset_l, 471 + .num_resets = ARRAY_SIZE(usb3phy_reset_l), 472 + .vreg_list = qmp_phy_qcs615_vreg_l, 473 + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), 474 + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, 475 + }; 476 + 477 + static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp); 478 + static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp); 479 + static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp); 480 + static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp); 481 + 482 + static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = { 483 + .offsets = &qmp_usbc_usb3dp_offsets_qcs615, 484 + 485 + .serdes_tbl = qcm2290_usb3_serdes_tbl, 486 + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), 487 + .tx_tbl = qcm2290_usb3_tx_tbl, 488 + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), 489 + .rx_tbl = qcm2290_usb3_rx_tbl, 490 + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), 491 + .pcs_tbl = qcm2290_usb3_pcs_tbl, 492 + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), 493 + 494 + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, 495 + 496 + .dp_serdes_tbl = qmp_v2_dp_serdes_tbl, 497 + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl), 498 + .dp_tx_tbl = qmp_v2_dp_tx_tbl, 499 + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v2_dp_tx_tbl), 500 + 501 + .serdes_tbl_rbr = qmp_v2_dp_serdes_tbl_rbr, 502 + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_rbr), 503 + .serdes_tbl_hbr = qmp_v2_dp_serdes_tbl_hbr, 504 + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr), 505 + .serdes_tbl_hbr2 = qmp_v2_dp_serdes_tbl_hbr2, 506 + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr2), 507 + 508 + .swing_tbl = &qmp_v2_dp_voltage_swing_hbr2_rbr, 509 + .pre_emphasis_tbl = &qmp_v2_dp_pre_emphasis_hbr2_rbr, 510 + 511 + .dp_aux_init = qmp_v2_dp_aux_init, 512 + .configure_dp_tx = qmp_v2_configure_dp_tx, 513 + .configure_dp_phy = qmp_v2_configure_dp_phy, 514 + .calibrate_dp_phy = qmp_v2_calibrate_dp_phy, 515 + 516 + .reset_list = usb3dpphy_reset_l, 517 + .num_resets = ARRAY_SIZE(usb3dpphy_reset_l), 518 + .vreg_list = qmp_phy_qcs615_vreg_l, 519 + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), 520 + }; 521 + 522 + static void qmp_usbc_set_phy_mode(struct qmp_usbc *qmp, bool is_dp) 523 + { 524 + if (qmp->tcsr_map && qmp->dp_phy_mode_reg) 525 + regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp); 526 + } 527 + 528 + static int qmp_usbc_com_init(struct phy *phy) 625 529 { 626 530 struct qmp_usbc *qmp = phy_get_drvdata(phy); 627 531 const struct qmp_phy_cfg *cfg = qmp->cfg; 628 - void __iomem *pcs = qmp->pcs; 629 - u32 val = 0; 630 532 int ret; 631 533 632 534 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); ··· 720 484 if (ret) 721 485 goto err_assert_reset; 722 486 723 - qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); 724 - 725 - #define SW_PORTSELECT_VAL BIT(0) 726 - #define SW_PORTSELECT_MUX BIT(1) 727 - /* Use software based port select and switch on typec orientation */ 728 - val = SW_PORTSELECT_MUX; 729 - if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) 730 - val |= SW_PORTSELECT_VAL; 731 - writel(val, qmp->pcs_misc); 732 - 733 487 return 0; 734 488 735 489 err_assert_reset: ··· 730 504 return ret; 731 505 } 732 506 733 - static int qmp_usbc_exit(struct phy *phy) 507 + static int qmp_usbc_com_exit(struct phy *phy) 734 508 { 735 509 struct qmp_usbc *qmp = phy_get_drvdata(phy); 736 510 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 744 518 return 0; 745 519 } 746 520 747 - static int qmp_usbc_power_on(struct phy *phy) 521 + static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp) 522 + { 523 + writel(DP_PHY_PD_CTL_AUX_PWRDN | 524 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 525 + DP_PHY_PD_CTL_PLL_PWRDN, 526 + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 527 + 528 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 529 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 530 + DP_PHY_PD_CTL_PLL_PWRDN, 531 + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 532 + 533 + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); 534 + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); 535 + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); 536 + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); 537 + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); 538 + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); 539 + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); 540 + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); 541 + writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); 542 + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); 543 + qmp->dp_aux_cfg = 0; 544 + 545 + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 546 + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 547 + PHY_AUX_REQ_ERR_MASK, 548 + qmp->dp_dp_phy + QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK); 549 + } 550 + 551 + static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp) 552 + { 553 + const struct qmp_phy_cfg *cfg = qmp->cfg; 554 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 555 + void __iomem *tx = qmp->dp_tx; 556 + void __iomem *tx2 = qmp->dp_tx2; 557 + unsigned int v_level = 0, p_level = 0; 558 + u8 voltage_swing_cfg, pre_emphasis_cfg; 559 + int i; 560 + 561 + if (dp_opts->lanes > 4) { 562 + dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes); 563 + return -EINVAL; 564 + } 565 + 566 + for (i = 0; i < dp_opts->lanes; i++) { 567 + v_level = max(v_level, dp_opts->voltage[i]); 568 + p_level = max(p_level, dp_opts->pre[i]); 569 + } 570 + 571 + if (v_level > 4 || p_level > 4) { 572 + dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n", 573 + v_level, p_level); 574 + return -EINVAL; 575 + } 576 + 577 + voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level]; 578 + pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level]; 579 + 580 + voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN; 581 + pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN; 582 + 583 + if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff) 584 + return -EINVAL; 585 + 586 + writel(voltage_swing_cfg, tx + QSERDES_V2_TX_TX_DRV_LVL); 587 + writel(pre_emphasis_cfg, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); 588 + writel(voltage_swing_cfg, tx2 + QSERDES_V2_TX_TX_DRV_LVL); 589 + writel(pre_emphasis_cfg, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); 590 + 591 + return 0; 592 + } 593 + 594 + static void qmp_usbc_configure_dp_mode(struct qmp_usbc *qmp) 595 + { 596 + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); 597 + u32 val; 598 + 599 + val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 600 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN; 601 + 602 + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 603 + 604 + if (reverse) 605 + writel(0xc9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); 606 + else 607 + writel(0xd9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); 608 + } 609 + 610 + static int qmp_usbc_configure_dp_clocks(struct qmp_usbc *qmp) 611 + { 612 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 613 + u32 phy_vco_div; 614 + unsigned long pixel_freq; 615 + 616 + switch (dp_opts->link_rate) { 617 + case 1620: 618 + phy_vco_div = 0x1; 619 + pixel_freq = 1620000000UL / 2; 620 + break; 621 + case 2700: 622 + phy_vco_div = 0x1; 623 + pixel_freq = 2700000000UL / 2; 624 + break; 625 + case 5400: 626 + phy_vco_div = 0x2; 627 + pixel_freq = 5400000000UL / 4; 628 + break; 629 + default: 630 + dev_err(qmp->dev, "link rate:%d not supported\n", dp_opts->link_rate); 631 + return -EINVAL; 632 + } 633 + writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_VCO_DIV); 634 + 635 + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); 636 + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); 637 + 638 + return 0; 639 + } 640 + 641 + static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp) 642 + { 643 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 644 + void __iomem *tx = qmp->dp_tx; 645 + void __iomem *tx2 = qmp->dp_tx2; 646 + 647 + /* program default setting first */ 648 + writel(0x2a, tx + QSERDES_V2_TX_TX_DRV_LVL); 649 + writel(0x20, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); 650 + writel(0x2a, tx2 + QSERDES_V2_TX_TX_DRV_LVL); 651 + writel(0x20, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); 652 + 653 + if (dp_opts->link_rate >= 2700) { 654 + writel(0xc4, tx + QSERDES_V2_TX_LANE_MODE_1); 655 + writel(0xc4, tx2 + QSERDES_V2_TX_LANE_MODE_1); 656 + } else { 657 + writel(0xc6, tx + QSERDES_V2_TX_LANE_MODE_1); 658 + writel(0xc6, tx2 + QSERDES_V2_TX_LANE_MODE_1); 659 + } 660 + 661 + qmp_v2_configure_dp_swing(qmp); 662 + } 663 + 664 + static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp) 665 + { 666 + u32 status; 667 + int ret; 668 + 669 + qmp_usbc_configure_dp_mode(qmp); 670 + 671 + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL); 672 + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL); 673 + 674 + ret = qmp_usbc_configure_dp_clocks(qmp); 675 + if (ret) 676 + return ret; 677 + 678 + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 679 + writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 680 + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 681 + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 682 + 683 + writel(0x20, qmp->dp_serdes + QSERDES_COM_RESETSM_CNTRL); 684 + 685 + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_C_READY_STATUS, 686 + status, 687 + ((status & BIT(0)) > 0), 688 + 500, 689 + 10000)) { 690 + dev_err(qmp->dev, "C_READY not ready\n"); 691 + return -ETIMEDOUT; 692 + } 693 + 694 + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, 695 + status, 696 + ((status & BIT(0)) > 0), 697 + 500, 698 + 10000)){ 699 + dev_err(qmp->dev, "FREQ_DONE not ready\n"); 700 + return -ETIMEDOUT; 701 + } 702 + 703 + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, 704 + status, 705 + ((status & BIT(1)) > 0), 706 + 500, 707 + 10000)){ 708 + dev_err(qmp->dev, "PLL_LOCKED not ready\n"); 709 + return -ETIMEDOUT; 710 + } 711 + 712 + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 713 + 714 + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, 715 + status, 716 + ((status & BIT(0)) > 0), 717 + 500, 718 + 10000)){ 719 + dev_err(qmp->dev, "TSYNC_DONE not ready\n"); 720 + return -ETIMEDOUT; 721 + } 722 + 723 + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, 724 + status, 725 + ((status & BIT(1)) > 0), 726 + 500, 727 + 10000)){ 728 + dev_err(qmp->dev, "PHY_READY not ready\n"); 729 + return -ETIMEDOUT; 730 + } 731 + 732 + writel(0x3f, qmp->dp_tx + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); 733 + writel(0x10, qmp->dp_tx + QSERDES_V2_TX_HIGHZ_DRVR_EN); 734 + writel(0x0a, qmp->dp_tx + QSERDES_V2_TX_TX_POL_INV); 735 + writel(0x3f, qmp->dp_tx2 + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); 736 + writel(0x10, qmp->dp_tx2 + QSERDES_V2_TX_HIGHZ_DRVR_EN); 737 + writel(0x0a, qmp->dp_tx2 + QSERDES_V2_TX_TX_POL_INV); 738 + 739 + writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 740 + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); 741 + 742 + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, 743 + status, 744 + ((status & BIT(1)) > 0), 745 + 500, 746 + 10000)){ 747 + dev_err(qmp->dev, "PHY_READY not ready\n"); 748 + return -ETIMEDOUT; 749 + } 750 + 751 + return 0; 752 + } 753 + 754 + static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp) 755 + { 756 + static const u8 cfg1_settings[] = {0x13, 0x23, 0x1d}; 757 + u8 val; 758 + 759 + qmp->dp_aux_cfg++; 760 + qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); 761 + val = cfg1_settings[qmp->dp_aux_cfg]; 762 + 763 + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); 764 + 765 + return 0; 766 + } 767 + 768 + static int qmp_usbc_usb_power_on(struct phy *phy) 748 769 { 749 770 struct qmp_usbc *qmp = phy_get_drvdata(phy); 750 771 const struct qmp_phy_cfg *cfg = qmp->cfg; 751 772 void __iomem *status; 752 773 unsigned int val; 753 774 int ret; 775 + 776 + qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); 777 + 778 + /* Use software based port select and switch on typec orientation */ 779 + val = SW_PORTSELECT_MUX; 780 + if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) 781 + val |= SW_PORTSELECT_VAL; 782 + writel(val, qmp->pcs_misc); 754 783 755 784 qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl, 756 785 cfg->serdes_tbl_num); ··· 1047 566 return ret; 1048 567 } 1049 568 1050 - static int qmp_usbc_power_off(struct phy *phy) 569 + static int qmp_usbc_usb_power_off(struct phy *phy) 1051 570 { 1052 571 struct qmp_usbc *qmp = phy_get_drvdata(phy); 1053 572 const struct qmp_phy_cfg *cfg = qmp->cfg; ··· 1068 587 return 0; 1069 588 } 1070 589 1071 - static int qmp_usbc_enable(struct phy *phy) 590 + static int qmp_usbc_check_phy_status(struct qmp_usbc *qmp, bool is_dp) 591 + { 592 + if ((is_dp && qmp->usb_init_count) || 593 + (!is_dp && qmp->dp_init_count)) { 594 + dev_err(qmp->dev, 595 + "PHY is configured for %s, can not enable %s\n", 596 + is_dp ? "USB" : "DP", is_dp ? "DP" : "USB"); 597 + return -EBUSY; 598 + } 599 + 600 + return 0; 601 + } 602 + 603 + static int qmp_usbc_usb_enable(struct phy *phy) 1072 604 { 1073 605 struct qmp_usbc *qmp = phy_get_drvdata(phy); 1074 606 int ret; 1075 607 1076 608 mutex_lock(&qmp->phy_mutex); 1077 609 1078 - ret = qmp_usbc_init(phy); 610 + ret = qmp_usbc_check_phy_status(qmp, false); 1079 611 if (ret) 1080 612 goto out_unlock; 1081 613 1082 - ret = qmp_usbc_power_on(phy); 614 + ret = qmp_usbc_com_init(phy); 615 + if (ret) 616 + goto out_unlock; 617 + 618 + qmp_usbc_set_phy_mode(qmp, false); 619 + 620 + ret = qmp_usbc_usb_power_on(phy); 1083 621 if (ret) { 1084 - qmp_usbc_exit(phy); 622 + qmp_usbc_com_exit(phy); 1085 623 goto out_unlock; 1086 624 } 1087 625 ··· 1111 611 return ret; 1112 612 } 1113 613 1114 - static int qmp_usbc_disable(struct phy *phy) 614 + static int qmp_usbc_usb_disable(struct phy *phy) 1115 615 { 1116 616 struct qmp_usbc *qmp = phy_get_drvdata(phy); 1117 617 int ret; 1118 618 1119 619 qmp->usb_init_count--; 1120 - ret = qmp_usbc_power_off(phy); 620 + ret = qmp_usbc_usb_power_off(phy); 1121 621 if (ret) 1122 622 return ret; 1123 - return qmp_usbc_exit(phy); 623 + return qmp_usbc_com_exit(phy); 1124 624 } 1125 625 1126 - static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) 626 + static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1127 627 { 1128 628 struct qmp_usbc *qmp = phy_get_drvdata(phy); 1129 629 ··· 1132 632 return 0; 1133 633 } 1134 634 1135 - static const struct phy_ops qmp_usbc_phy_ops = { 1136 - .init = qmp_usbc_enable, 1137 - .exit = qmp_usbc_disable, 1138 - .set_mode = qmp_usbc_set_mode, 635 + static int qmp_usbc_dp_enable(struct phy *phy) 636 + { 637 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 638 + const struct qmp_phy_cfg *cfg = qmp->cfg; 639 + int ret; 640 + 641 + if (qmp->dp_init_count) { 642 + dev_err(qmp->dev, "DP already inited\n"); 643 + return 0; 644 + } 645 + 646 + mutex_lock(&qmp->phy_mutex); 647 + 648 + ret = qmp_usbc_check_phy_status(qmp, true); 649 + if (ret) 650 + goto dp_init_unlock; 651 + 652 + ret = qmp_usbc_com_init(phy); 653 + if (ret) 654 + goto dp_init_unlock; 655 + 656 + qmp_usbc_set_phy_mode(qmp, true); 657 + 658 + cfg->dp_aux_init(qmp); 659 + 660 + qmp->dp_init_count++; 661 + 662 + dp_init_unlock: 663 + mutex_unlock(&qmp->phy_mutex); 664 + return ret; 665 + } 666 + 667 + static int qmp_usbc_dp_disable(struct phy *phy) 668 + { 669 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 670 + 671 + mutex_lock(&qmp->phy_mutex); 672 + 673 + qmp_usbc_com_exit(phy); 674 + 675 + qmp->dp_init_count--; 676 + 677 + mutex_unlock(&qmp->phy_mutex); 678 + 679 + return 0; 680 + } 681 + 682 + static int qmp_usbc_dp_configure(struct phy *phy, union phy_configure_opts *opts) 683 + { 684 + const struct phy_configure_opts_dp *dp_opts = &opts->dp; 685 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 686 + const struct qmp_phy_cfg *cfg = qmp->cfg; 687 + 688 + mutex_lock(&qmp->phy_mutex); 689 + 690 + memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts)); 691 + if (qmp->dp_opts.set_voltages) { 692 + cfg->configure_dp_tx(qmp); 693 + qmp->dp_opts.set_voltages = 0; 694 + } 695 + 696 + mutex_unlock(&qmp->phy_mutex); 697 + 698 + return 0; 699 + } 700 + 701 + static int qmp_usbc_dp_calibrate(struct phy *phy) 702 + { 703 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 704 + const struct qmp_phy_cfg *cfg = qmp->cfg; 705 + int ret = 0; 706 + 707 + mutex_lock(&qmp->phy_mutex); 708 + 709 + if (cfg->calibrate_dp_phy) { 710 + ret = cfg->calibrate_dp_phy(qmp); 711 + if (ret) { 712 + dev_err(qmp->dev, "dp calibrate err(%d)\n", ret); 713 + mutex_unlock(&qmp->phy_mutex); 714 + return ret; 715 + } 716 + } 717 + 718 + mutex_unlock(&qmp->phy_mutex); 719 + return 0; 720 + } 721 + 722 + static int qmp_usbc_dp_serdes_init(struct qmp_usbc *qmp) 723 + { 724 + const struct qmp_phy_cfg *cfg = qmp->cfg; 725 + void __iomem *serdes = qmp->dp_serdes; 726 + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 727 + 728 + qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl, 729 + cfg->dp_serdes_tbl_num); 730 + 731 + switch (dp_opts->link_rate) { 732 + case 1620: 733 + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_rbr, 734 + cfg->serdes_tbl_rbr_num); 735 + break; 736 + case 2700: 737 + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr, 738 + cfg->serdes_tbl_hbr_num); 739 + break; 740 + case 5400: 741 + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr2, 742 + cfg->serdes_tbl_hbr2_num); 743 + break; 744 + default: 745 + /* Other link rates aren't supported */ 746 + return -EINVAL; 747 + } 748 + 749 + return 0; 750 + } 751 + 752 + static int qmp_usbc_dp_power_on(struct phy *phy) 753 + { 754 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 755 + const struct qmp_phy_cfg *cfg = qmp->cfg; 756 + 757 + void __iomem *tx = qmp->dp_tx; 758 + void __iomem *tx2 = qmp->dp_tx2; 759 + 760 + /* 761 + * FIXME: SW_PORTSELECT handling for DP orientation flip is not implemented. 762 + * Expected: 763 + * - For standard lane mapping: configure SW_PORTSELECT in QSERDES_DP_PHY_CFG_1. 764 + * - For non-standard mapping: pass orientation to dp_ctrl and handle flip 765 + * via logical2physical lane remapping. 766 + */ 767 + 768 + mutex_lock(&qmp->phy_mutex); 769 + 770 + qmp_usbc_dp_serdes_init(qmp); 771 + 772 + qmp_configure_lane(qmp->dev, tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); 773 + qmp_configure_lane(qmp->dev, tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2); 774 + 775 + /* Configure special DP tx tunings */ 776 + cfg->configure_dp_tx(qmp); 777 + 778 + /* Configure link rate, swing, etc. */ 779 + cfg->configure_dp_phy(qmp); 780 + 781 + mutex_unlock(&qmp->phy_mutex); 782 + 783 + return 0; 784 + } 785 + 786 + static int qmp_usbc_dp_power_off(struct phy *phy) 787 + { 788 + struct qmp_usbc *qmp = phy_get_drvdata(phy); 789 + 790 + mutex_lock(&qmp->phy_mutex); 791 + 792 + /* Assert DP PHY power down */ 793 + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 794 + 795 + mutex_unlock(&qmp->phy_mutex); 796 + 797 + return 0; 798 + } 799 + 800 + static const struct phy_ops qmp_usbc_usb_phy_ops = { 801 + .init = qmp_usbc_usb_enable, 802 + .exit = qmp_usbc_usb_disable, 803 + .set_mode = qmp_usbc_usb_set_mode, 804 + .owner = THIS_MODULE, 805 + }; 806 + 807 + static const struct phy_ops qmp_usbc_dp_phy_ops = { 808 + .init = qmp_usbc_dp_enable, 809 + .exit = qmp_usbc_dp_disable, 810 + .configure = qmp_usbc_dp_configure, 811 + .calibrate = qmp_usbc_dp_calibrate, 812 + .power_on = qmp_usbc_dp_power_on, 813 + .power_off = qmp_usbc_dp_power_off, 1139 814 .owner = THIS_MODULE, 1140 815 }; 1141 816 ··· 1365 690 1366 691 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); 1367 692 1368 - if (!qmp->phy->init_count) { 693 + if (!qmp->usb_init_count && !qmp->dp_init_count) { 1369 694 dev_vdbg(dev, "PHY not initialized, bailing out\n"); 1370 695 return 0; 1371 696 } ··· 1385 710 1386 711 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); 1387 712 1388 - if (!qmp->phy->init_count) { 713 + if (!qmp->usb_init_count && !qmp->dp_init_count) { 1389 714 dev_vdbg(dev, "PHY not initialized, bailing out\n"); 1390 715 return 0; 1391 716 } ··· 1410 735 SET_RUNTIME_PM_OPS(qmp_usbc_runtime_suspend, 1411 736 qmp_usbc_runtime_resume, NULL) 1412 737 }; 1413 - 1414 - static int qmp_usbc_vreg_init(struct qmp_usbc *qmp) 1415 - { 1416 - const struct qmp_phy_cfg *cfg = qmp->cfg; 1417 - struct device *dev = qmp->dev; 1418 - int num = cfg->num_vregs; 1419 - int i; 1420 - 1421 - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); 1422 - if (!qmp->vregs) 1423 - return -ENOMEM; 1424 - 1425 - for (i = 0; i < num; i++) 1426 - qmp->vregs[i].supply = cfg->vreg_list[i]; 1427 - 1428 - return devm_regulator_bulk_get(dev, num, qmp->vregs); 1429 - } 1430 738 1431 739 static int qmp_usbc_reset_init(struct qmp_usbc *qmp, 1432 740 const char *const *reset_list, ··· 1454 796 return devm_clk_bulk_get_optional(dev, num, qmp->clks); 1455 797 } 1456 798 1457 - static void phy_clk_release_provider(void *res) 799 + static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data) 1458 800 { 1459 - of_clk_del_provider(res); 801 + struct qmp_usbc *qmp = data; 802 + 803 + if (clkspec->args_count == 0) 804 + return &qmp->pipe_clk_fixed.hw; 805 + 806 + switch (clkspec->args[0]) { 807 + case QMP_USB43DP_USB3_PIPE_CLK: 808 + return &qmp->pipe_clk_fixed.hw; 809 + case QMP_USB43DP_DP_LINK_CLK: 810 + return &qmp->dp_link_hw; 811 + case QMP_USB43DP_DP_VCO_DIV_CLK: 812 + return &qmp->dp_pixel_hw; 813 + } 814 + 815 + return ERR_PTR(-EINVAL); 1460 816 } 1461 817 1462 818 /* ··· 1495 823 { 1496 824 struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; 1497 825 struct clk_init_data init = { }; 826 + char name[64]; 1498 827 int ret; 1499 828 1500 829 ret = of_property_read_string(np, "clock-output-names", &init.name); 1501 830 if (ret) { 1502 - dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); 1503 - return ret; 831 + /* Clock name is not mandatory. */ 832 + snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev)); 833 + init.name = name; 1504 834 } 1505 835 1506 836 init.ops = &clk_fixed_rate_ops; ··· 1511 837 fixed->fixed_rate = 125000000; 1512 838 fixed->hw.init = &init; 1513 839 1514 - ret = devm_clk_hw_register(qmp->dev, &fixed->hw); 840 + return devm_clk_hw_register(qmp->dev, &fixed->hw); 841 + } 842 + 843 + /* 844 + * Display Port PLL driver block diagram for branch clocks 845 + * 846 + * +------------------------------+ 847 + * | DP_VCO_CLK | 848 + * | | 849 + * | +-------------------+ | 850 + * | | (DP PLL/VCO) | | 851 + * | +---------+---------+ | 852 + * | v | 853 + * | +----------+-----------+ | 854 + * | | hsclk_divsel_clk_src | | 855 + * | +----------+-----------+ | 856 + * +------------------------------+ 857 + * | 858 + * +---------<---------v------------>----------+ 859 + * | | 860 + * +--------v----------------+ | 861 + * | dp_phy_pll_link_clk | | 862 + * | link_clk | | 863 + * +--------+----------------+ | 864 + * | | 865 + * | | 866 + * v v 867 + * Input to DISPCC block | 868 + * for link clk, crypto clk | 869 + * and interface clock | 870 + * | 871 + * | 872 + * +--------<------------+-----------------+---<---+ 873 + * | | | 874 + * +----v---------+ +--------v-----+ +--------v------+ 875 + * | vco_divided | | vco_divided | | vco_divided | 876 + * | _clk_src | | _clk_src | | _clk_src | 877 + * | | | | | | 878 + * |divsel_six | | divsel_two | | divsel_four | 879 + * +-------+------+ +-----+--------+ +--------+------+ 880 + * | | | 881 + * v---->----------v-------------<------v 882 + * | 883 + * +----------+-----------------+ 884 + * | dp_phy_pll_vco_div_clk | 885 + * +---------+------------------+ 886 + * | 887 + * v 888 + * Input to DISPCC block 889 + * for DP pixel clock 890 + * 891 + */ 892 + static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) 893 + { 894 + switch (req->rate) { 895 + case 1620000000UL / 2: 896 + case 2700000000UL / 2: 897 + /* 5.4 is same link rate as 2.7GHz, i.e. div 4 */ 898 + return 0; 899 + default: 900 + return -EINVAL; 901 + } 902 + } 903 + 904 + static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 905 + { 906 + const struct qmp_usbc *qmp; 907 + const struct phy_configure_opts_dp *dp_opts; 908 + 909 + qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw); 910 + 911 + dp_opts = &qmp->dp_opts; 912 + 913 + switch (dp_opts->link_rate) { 914 + case 1620: 915 + return 1620000000UL / 2; 916 + case 2700: 917 + return 2700000000UL / 2; 918 + case 5400: 919 + return 5400000000UL / 4; 920 + default: 921 + return 0; 922 + } 923 + } 924 + 925 + static const struct clk_ops qmp_dp_pixel_clk_ops = { 926 + .determine_rate = qmp_dp_pixel_clk_determine_rate, 927 + .recalc_rate = qmp_dp_pixel_clk_recalc_rate, 928 + }; 929 + 930 + static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) 931 + { 932 + switch (req->rate) { 933 + case 162000000: 934 + case 270000000: 935 + case 540000000: 936 + return 0; 937 + default: 938 + return -EINVAL; 939 + } 940 + } 941 + 942 + static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 943 + { 944 + const struct qmp_usbc *qmp; 945 + const struct phy_configure_opts_dp *dp_opts; 946 + 947 + qmp = container_of(hw, struct qmp_usbc, dp_link_hw); 948 + dp_opts = &qmp->dp_opts; 949 + 950 + switch (dp_opts->link_rate) { 951 + case 1620: 952 + case 2700: 953 + case 5400: 954 + return dp_opts->link_rate * 100000; 955 + default: 956 + return 0; 957 + } 958 + } 959 + 960 + static const struct clk_ops qmp_dp_link_clk_ops = { 961 + .determine_rate = qmp_dp_link_clk_determine_rate, 962 + .recalc_rate = qmp_dp_link_clk_recalc_rate, 963 + }; 964 + 965 + static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np) 966 + { 967 + struct clk_init_data init = { }; 968 + char name[64]; 969 + int ret; 970 + 971 + snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev)); 972 + init.ops = &qmp_dp_link_clk_ops; 973 + init.name = name; 974 + qmp->dp_link_hw.init = &init; 975 + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw); 976 + if (ret < 0) { 977 + dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret); 978 + return ret; 979 + } 980 + 981 + snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev)); 982 + init.ops = &qmp_dp_pixel_clk_ops; 983 + init.name = name; 984 + qmp->dp_pixel_hw.init = &init; 985 + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw); 986 + if (ret) { 987 + dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret); 988 + return ret; 989 + } 990 + 991 + return 0; 992 + } 993 + 994 + static void phy_clk_release_provider(void *res) 995 + { 996 + of_clk_del_provider(res); 997 + } 998 + 999 + static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np) 1000 + { 1001 + struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; 1002 + int ret; 1003 + 1004 + ret = phy_pipe_clk_register(qmp, np); 1515 1005 if (ret) 1516 1006 return ret; 1007 + 1008 + if (qmp->dp_serdes != 0) { 1009 + ret = phy_dp_clks_register(qmp, np); 1010 + if (ret) 1011 + return ret; 1012 + } 1013 + 1014 + if (np == qmp->dev->of_node) 1015 + return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp); 1517 1016 1518 1017 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); 1519 1018 if (ret) ··· 1712 865 qmp->orientation = orientation; 1713 866 1714 867 if (qmp->usb_init_count) { 1715 - qmp_usbc_power_off(qmp->phy); 1716 - qmp_usbc_exit(qmp->phy); 868 + qmp_usbc_usb_power_off(qmp->usb_phy); 869 + qmp_usbc_com_exit(qmp->usb_phy); 1717 870 1718 - qmp_usbc_init(qmp->phy); 1719 - qmp_usbc_power_on(qmp->phy); 871 + qmp_usbc_com_init(qmp->usb_phy); 872 + qmp_usbc_set_phy_mode(qmp, false); 873 + qmp_usbc_usb_power_on(qmp->usb_phy); 1720 874 } 1721 875 1722 876 mutex_unlock(&qmp->phy_mutex); ··· 1833 985 if (IS_ERR(base)) 1834 986 return PTR_ERR(base); 1835 987 988 + if (offs->dp_serdes != 0) { 989 + qmp->dp_serdes = base + offs->dp_serdes; 990 + qmp->dp_tx = base + offs->dp_txa; 991 + qmp->dp_tx2 = base + offs->dp_txb; 992 + qmp->dp_dp_phy = base + offs->dp_dp_phy; 993 + } 994 + 1836 995 qmp->serdes = base + offs->serdes; 1837 996 qmp->pcs = base + offs->pcs; 1838 997 if (offs->pcs_misc) ··· 1860 1005 "failed to get pipe clock\n"); 1861 1006 } 1862 1007 1863 - ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l, 1864 - ARRAY_SIZE(usb3phy_reset_l)); 1008 + ret = qmp_usbc_reset_init(qmp, cfg->reset_list, cfg->num_resets); 1865 1009 if (ret) 1866 1010 return ret; 1867 1011 1868 1012 return 0; 1869 1013 } 1870 1014 1871 - static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) 1015 + static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp) 1872 1016 { 1873 1017 struct of_phandle_args tcsr_args; 1874 1018 struct device *dev = qmp->dev; 1875 - int ret; 1019 + int ret, args_count; 1876 1020 1877 - /* for backwards compatibility ignore if there is no property */ 1878 - ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0, 1879 - &tcsr_args); 1021 + args_count = of_property_count_u32_elems(dev->of_node, "qcom,tcsr-reg"); 1022 + args_count = args_count - 1; 1023 + ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1024 + args_count, 0, &tcsr_args); 1880 1025 if (ret == -ENOENT) 1881 1026 return 0; 1882 1027 else if (ret < 0) ··· 1889 1034 1890 1035 qmp->vls_clamp_reg = tcsr_args.args[0]; 1891 1036 1037 + if (args_count > 1) 1038 + qmp->dp_phy_mode_reg = tcsr_args.args[1]; 1039 + 1892 1040 return 0; 1041 + } 1042 + 1043 + static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args) 1044 + { 1045 + struct qmp_usbc *qmp = dev_get_drvdata(dev); 1046 + 1047 + if (args->args_count == 0) 1048 + return qmp->usb_phy; 1049 + 1050 + switch (args->args[0]) { 1051 + case QMP_USB43DP_USB3_PHY: 1052 + return qmp->usb_phy; 1053 + case QMP_USB43DP_DP_PHY: 1054 + return qmp->dp_phy ?: ERR_PTR(-ENODEV); 1055 + } 1056 + 1057 + return ERR_PTR(-EINVAL); 1893 1058 } 1894 1059 1895 1060 static int qmp_usbc_probe(struct platform_device *pdev) ··· 1935 1060 1936 1061 mutex_init(&qmp->phy_mutex); 1937 1062 1938 - ret = qmp_usbc_vreg_init(qmp); 1063 + ret = devm_regulator_bulk_get_const(qmp->dev, qmp->cfg->num_vregs, 1064 + qmp->cfg->vreg_list, &qmp->vregs); 1939 1065 if (ret) 1940 1066 return ret; 1941 1067 ··· 1944 1068 if (ret) 1945 1069 return ret; 1946 1070 1947 - ret = qmp_usbc_parse_vls_clamp(qmp); 1071 + ret = qmp_usbc_parse_tcsr(qmp); 1948 1072 if (ret) 1949 1073 return ret; 1950 1074 ··· 1969 1093 */ 1970 1094 pm_runtime_forbid(dev); 1971 1095 1972 - ret = phy_pipe_clk_register(qmp, np); 1096 + ret = qmp_usbc_register_clocks(qmp, np); 1973 1097 if (ret) 1974 1098 goto err_node_put; 1975 1099 1976 - qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops); 1977 - if (IS_ERR(qmp->phy)) { 1978 - ret = PTR_ERR(qmp->phy); 1100 + qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops); 1101 + if (IS_ERR(qmp->usb_phy)) { 1102 + ret = PTR_ERR(qmp->usb_phy); 1979 1103 dev_err(dev, "failed to create PHY: %d\n", ret); 1980 1104 goto err_node_put; 1981 1105 } 1982 1106 1983 - phy_set_drvdata(qmp->phy, qmp); 1107 + phy_set_drvdata(qmp->usb_phy, qmp); 1108 + 1109 + if (qmp->dp_serdes != 0) { 1110 + qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops); 1111 + if (IS_ERR(qmp->dp_phy)) { 1112 + ret = PTR_ERR(qmp->dp_phy); 1113 + dev_err(dev, "failed to create PHY: %d\n", ret); 1114 + goto err_node_put; 1115 + } 1116 + phy_set_drvdata(qmp->dp_phy, qmp); 1117 + } 1984 1118 1985 1119 of_node_put(np); 1986 1120 1987 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1121 + phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate); 1988 1122 1989 1123 return PTR_ERR_OR_ZERO(phy_provider); 1990 1124 ··· 2011 1125 .compatible = "qcom,qcm2290-qmp-usb3-phy", 2012 1126 .data = &qcm2290_usb3phy_cfg, 2013 1127 }, { 1128 + .compatible = "qcom,qcs615-qmp-usb3-dp-phy", 1129 + .data = &qcs615_usb3dp_phy_cfg, 1130 + }, { 2014 1131 .compatible = "qcom,qcs615-qmp-usb3-phy", 2015 - .data = &qcm2290_usb3phy_cfg, 1132 + .data = &qcs615_usb3phy_cfg, 2016 1133 }, { 2017 1134 .compatible = "qcom,sdm660-qmp-usb3-phy", 2018 1135 .data = &sdm660_usb3phy_cfg,
+5
drivers/phy/qualcomm/phy-qcom-qmp.h
··· 9 9 #include "phy-qcom-qmp-qserdes-com.h" 10 10 #include "phy-qcom-qmp-qserdes-txrx.h" 11 11 12 + #include "phy-qcom-qmp-qserdes-com-v2.h" 13 + #include "phy-qcom-qmp-qserdes-txrx-v2.h" 14 + 12 15 #include "phy-qcom-qmp-qserdes-com-v3.h" 13 16 #include "phy-qcom-qmp-qserdes-txrx-v3.h" 14 17 ··· 35 32 #include "phy-qcom-qmp-qserdes-txrx-v7.h" 36 33 37 34 #include "phy-qcom-qmp-qserdes-com-v8.h" 35 + #include "phy-qcom-qmp-usb43-qserdes-com-v8.h" 38 36 #include "phy-qcom-qmp-qserdes-txrx-v8.h" 37 + #include "phy-qcom-qmp-qserdes-lalb-v8.h" 39 38 40 39 #include "phy-qcom-qmp-qserdes-pll.h" 41 40
+2
drivers/phy/renesas/Kconfig
··· 29 29 depends on ARCH_RENESAS 30 30 depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in 31 31 depends on USB_SUPPORT 32 + depends on REGULATOR 32 33 select GENERIC_PHY 34 + select MULTIPLEXER 33 35 select USB_COMMON 34 36 help 35 37 Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
+2 -4
drivers/phy/renesas/phy-rcar-gen2.c
··· 85 85 * Try to acquire exclusive access to PHY. The first driver calling 86 86 * phy_init() on a given channel wins, and all attempts to use another 87 87 * PHY on this channel will fail until phy_exit() is called by the first 88 - * driver. Achieving this with cmpxcgh() should be SMP-safe. 88 + * driver. Achieving this with cmpxchg() should be SMP-safe. 89 89 */ 90 90 if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1) 91 91 return -EBUSY; ··· 337 337 struct device *dev = &pdev->dev; 338 338 struct rcar_gen2_phy_driver *drv; 339 339 struct phy_provider *provider; 340 - struct device_node *np; 341 340 void __iomem *base; 342 341 struct clk *clk; 343 342 const struct rcar_gen2_phy_data *data; ··· 378 379 if (!drv->channels) 379 380 return -ENOMEM; 380 381 381 - for_each_child_of_node(dev->of_node, np) { 382 + for_each_child_of_node_scoped(dev->of_node, np) { 382 383 struct rcar_gen2_channel *channel = drv->channels + i; 383 384 u32 channel_num; 384 385 int error, n; ··· 390 391 error = of_property_read_u32(np, "reg", &channel_num); 391 392 if (error || channel_num >= data->num_channels) { 392 393 dev_err(dev, "Invalid \"reg\" property\n"); 393 - of_node_put(np); 394 394 return error; 395 395 } 396 396 channel->select_mask = select_mask[channel_num];
+212 -49
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 17 17 #include <linux/io.h> 18 18 #include <linux/module.h> 19 19 #include <linux/mutex.h> 20 + #include <linux/mux/consumer.h> 20 21 #include <linux/of.h> 21 22 #include <linux/phy/phy.h> 22 23 #include <linux/platform_device.h> 23 24 #include <linux/pm_runtime.h> 24 25 #include <linux/regulator/consumer.h> 26 + #include <linux/regulator/driver.h> 25 27 #include <linux/reset.h> 26 28 #include <linux/string.h> 27 29 #include <linux/usb/of.h> ··· 143 141 bool extcon_host; 144 142 bool is_otg_channel; 145 143 bool uses_otg_pins; 144 + bool otg_internal_reg; 146 145 }; 147 146 148 147 struct rcar_gen3_phy_drv_data { ··· 207 204 writel(val, usb2_base + USB2_LINECTRL1); 208 205 } 209 206 210 - static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) 207 + static void rcar_gen3_phy_usb2_set_vbus(struct rcar_gen3_chan *ch, 208 + u32 vbus_ctrl_reg, 209 + u32 vbus_ctrl_val, 210 + bool enable) 211 211 { 212 212 void __iomem *usb2_base = ch->base; 213 - u32 vbus_ctrl_reg = USB2_ADPCTRL; 214 - u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; 215 213 u32 val; 214 + 215 + val = readl(usb2_base + vbus_ctrl_reg); 216 + if (enable) 217 + val |= vbus_ctrl_val; 218 + else 219 + val &= ~vbus_ctrl_val; 220 + writel(val, usb2_base + vbus_ctrl_reg); 221 + 222 + dev_vdbg(ch->dev, "%s: reg=0x%08x, val=%08x, enable=%d\n", 223 + __func__, vbus_ctrl_reg, val, enable); 224 + } 225 + 226 + static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) 227 + { 228 + if (ch->otg_internal_reg) { 229 + regulator_hardware_enable(ch->vbus, vbus); 230 + return; 231 + } 216 232 217 233 if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { 218 234 if (ch->vbus) 219 235 regulator_hardware_enable(ch->vbus, vbus); 220 236 221 - vbus_ctrl_reg = USB2_VBCTRL; 222 - vbus_ctrl_val = USB2_VBCTRL_VBOUT; 237 + rcar_gen3_phy_usb2_set_vbus(ch, USB2_VBCTRL, 238 + USB2_VBCTRL_VBOUT, vbus); 239 + return; 223 240 } 224 241 225 - val = readl(usb2_base + vbus_ctrl_reg); 226 - if (vbus) 227 - val |= vbus_ctrl_val; 228 - else 229 - val &= ~vbus_ctrl_val; 230 - dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); 231 - writel(val, usb2_base + vbus_ctrl_reg); 242 + rcar_gen3_phy_usb2_set_vbus(ch, USB2_ADPCTRL, 243 + USB2_ADPCTRL_DRVVBUS, vbus); 232 244 } 233 245 234 246 static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) ··· 601 583 u32 val; 602 584 int ret = 0; 603 585 604 - if (channel->vbus) { 586 + if (channel->vbus && !channel->otg_internal_reg) { 605 587 ret = regulator_enable(channel->vbus); 606 588 if (ret) 607 589 return ret; ··· 642 624 } 643 625 } 644 626 645 - if (channel->vbus) 627 + if (channel->vbus && !channel->otg_internal_reg) 646 628 ret = regulator_disable(channel->vbus); 647 629 648 630 return ret; ··· 817 799 return 0; 818 800 } 819 801 802 + static int rcar_gen3_phy_usb2_regulator_endisable(struct regulator_dev *rdev, 803 + bool enable) 804 + { 805 + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); 806 + struct device *dev = channel->dev; 807 + int ret; 808 + 809 + ret = pm_runtime_resume_and_get(dev); 810 + if (ret < 0) { 811 + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); 812 + return ret; 813 + } 814 + 815 + rcar_gen3_phy_usb2_set_vbus(channel, USB2_VBCTRL, 816 + USB2_VBCTRL_VBOUT, enable); 817 + pm_runtime_put_noidle(dev); 818 + 819 + return ret; 820 + } 821 + 822 + static int rcar_gen3_phy_usb2_regulator_enable(struct regulator_dev *rdev) 823 + { 824 + return rcar_gen3_phy_usb2_regulator_endisable(rdev, true); 825 + } 826 + 827 + static int rcar_gen3_phy_usb2_regulator_disable(struct regulator_dev *rdev) 828 + { 829 + return rcar_gen3_phy_usb2_regulator_endisable(rdev, false); 830 + } 831 + 832 + static int rcar_gen3_phy_usb2_regulator_is_enabled(struct regulator_dev *rdev) 833 + { 834 + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); 835 + void __iomem *usb2_base = channel->base; 836 + struct device *dev = channel->dev; 837 + u32 vbus_ctrl_reg = USB2_VBCTRL; 838 + u32 val; 839 + int ret; 840 + 841 + ret = pm_runtime_resume_and_get(dev); 842 + if (ret < 0) { 843 + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); 844 + return ret; 845 + } 846 + 847 + val = readl(usb2_base + vbus_ctrl_reg); 848 + 849 + pm_runtime_put_noidle(dev); 850 + dev_dbg(channel->dev, "%s: %08x\n", __func__, val); 851 + 852 + return (val & USB2_VBCTRL_VBOUT) ? 1 : 0; 853 + } 854 + 855 + static const struct regulator_ops rcar_gen3_phy_usb2_regulator_ops = { 856 + .enable = rcar_gen3_phy_usb2_regulator_enable, 857 + .disable = rcar_gen3_phy_usb2_regulator_disable, 858 + .is_enabled = rcar_gen3_phy_usb2_regulator_is_enabled, 859 + }; 860 + 861 + static const struct regulator_desc rcar_gen3_phy_usb2_regulator = { 862 + .name = "otg-vbus-regulator", 863 + .of_match = of_match_ptr("vbus-regulator"), 864 + .ops = &rcar_gen3_phy_usb2_regulator_ops, 865 + .type = REGULATOR_VOLTAGE, 866 + .owner = THIS_MODULE, 867 + .fixed_uV = 5000000, 868 + .n_voltages = 1, 869 + }; 870 + 871 + static void rcar_gen3_phy_usb2_vbus_disable_action(void *data) 872 + { 873 + struct regulator *vbus = data; 874 + 875 + regulator_disable(vbus); 876 + } 877 + 878 + static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_gen3_chan *channel, 879 + bool enable) 880 + { 881 + struct device *dev = channel->dev; 882 + int ret; 883 + 884 + channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); 885 + if (IS_ERR(channel->vbus)) 886 + return PTR_ERR(channel->vbus); 887 + 888 + if (!enable) 889 + return 0; 890 + 891 + ret = regulator_enable(channel->vbus); 892 + if (ret) 893 + return ret; 894 + 895 + return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action, 896 + channel->vbus); 897 + } 898 + 899 + static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel) 900 + { 901 + struct device *dev = channel->dev; 902 + struct regulator_config rcfg = { .dev = dev, }; 903 + struct regulator_dev *rdev; 904 + bool enable = false; 905 + 906 + rcfg.of_node = of_get_available_child_by_name(dev->of_node, 907 + "vbus-regulator"); 908 + if (rcfg.of_node) { 909 + rcfg.driver_data = channel; 910 + rdev = devm_regulator_register(dev, &rcar_gen3_phy_usb2_regulator, 911 + &rcfg); 912 + of_node_put(rcfg.of_node); 913 + if (IS_ERR(rdev)) 914 + return dev_err_probe(dev, PTR_ERR(rdev), 915 + "Failed to create vbus-regulator\n"); 916 + 917 + channel->otg_internal_reg = true; 918 + enable = true; 919 + } 920 + 921 + return rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(channel, enable); 922 + } 923 + 924 + /* Temporary wrapper until the multiplexer subsystem supports optional muxes */ 925 + static inline struct mux_state * 926 + devm_mux_state_get_optional(struct device *dev, const char *mux_name) 927 + { 928 + if (!of_property_present(dev->of_node, "mux-states")) 929 + return NULL; 930 + 931 + return devm_mux_state_get(dev, mux_name); 932 + } 933 + 934 + static void rcar_gen3_phy_mux_state_deselect(void *data) 935 + { 936 + mux_state_deselect(data); 937 + } 938 + 820 939 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) 821 940 { 822 941 struct device *dev = &pdev->dev; 823 942 struct rcar_gen3_chan *channel; 824 943 struct phy_provider *provider; 944 + struct mux_state *mux_state; 825 945 int ret = 0, i, irq; 826 946 827 947 if (!dev->of_node) { ··· 1008 852 * devm_phy_create() will call pm_runtime_enable(&phy->dev); 1009 853 * And then, phy-core will manage runtime pm for this device. 1010 854 */ 1011 - pm_runtime_enable(dev); 855 + ret = devm_pm_runtime_enable(dev); 856 + if (ret) 857 + return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n"); 1012 858 1013 859 channel->phy_data = of_device_get_match_data(dev); 1014 - if (!channel->phy_data) { 1015 - ret = -EINVAL; 1016 - goto error; 1017 - } 860 + if (!channel->phy_data) 861 + return -EINVAL; 1018 862 1019 863 platform_set_drvdata(pdev, channel); 1020 864 channel->dev = dev; 1021 865 1022 866 ret = rcar_gen3_phy_usb2_init_bus(channel); 1023 867 if (ret) 1024 - goto error; 868 + return ret; 1025 869 1026 870 spin_lock_init(&channel->lock); 1027 871 for (i = 0; i < NUM_OF_PHYS; i++) { 1028 872 channel->rphys[i].phy = devm_phy_create(dev, NULL, 1029 873 channel->phy_data->phy_usb2_ops); 1030 - if (IS_ERR(channel->rphys[i].phy)) { 1031 - dev_err(dev, "Failed to create USB2 PHY\n"); 1032 - ret = PTR_ERR(channel->rphys[i].phy); 1033 - goto error; 1034 - } 874 + if (IS_ERR(channel->rphys[i].phy)) 875 + return dev_err_probe(dev, PTR_ERR(channel->rphys[i].phy), 876 + "Failed to create USB2 PHY\n"); 877 + 1035 878 channel->rphys[i].ch = channel; 1036 879 channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i]; 1037 880 phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); 1038 881 } 1039 882 1040 - if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) 1041 - channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); 1042 - else 883 + mux_state = devm_mux_state_get_optional(dev, NULL); 884 + if (IS_ERR(mux_state)) 885 + return PTR_ERR(mux_state); 886 + if (mux_state) { 887 + ret = mux_state_select(mux_state); 888 + if (ret) 889 + return dev_err_probe(dev, ret, "Failed to select USB mux\n"); 890 + 891 + ret = devm_add_action_or_reset(dev, rcar_gen3_phy_mux_state_deselect, 892 + mux_state); 893 + if (ret) 894 + return dev_err_probe(dev, ret, 895 + "Failed to register USB mux state deselect\n"); 896 + } 897 + 898 + if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) { 899 + ret = rcar_gen3_phy_usb2_vbus_regulator_register(channel); 900 + if (ret) 901 + return ret; 902 + } else { 1043 903 channel->vbus = devm_regulator_get_optional(dev, "vbus"); 904 + } 1044 905 if (IS_ERR(channel->vbus)) { 1045 - if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) { 1046 - ret = PTR_ERR(channel->vbus); 1047 - goto error; 1048 - } 906 + if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) 907 + return PTR_ERR(channel->vbus); 908 + 1049 909 channel->vbus = NULL; 1050 910 } 1051 911 1052 912 irq = platform_get_irq_optional(pdev, 0); 1053 913 if (irq < 0 && irq != -ENXIO) { 1054 - ret = irq; 1055 - goto error; 914 + return irq; 1056 915 } else if (irq > 0) { 1057 916 INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); 1058 917 ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, 1059 918 IRQF_SHARED, dev_name(dev), channel); 1060 - if (ret < 0) { 1061 - dev_err(dev, "Failed to request irq (%d)\n", irq); 1062 - goto error; 1063 - } 919 + if (ret < 0) 920 + return dev_err_probe(dev, ret, 921 + "Failed to request irq (%d)\n", 922 + irq); 1064 923 } 1065 924 1066 925 provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate); 1067 926 if (IS_ERR(provider)) { 1068 - dev_err(dev, "Failed to register PHY provider\n"); 1069 - ret = PTR_ERR(provider); 1070 - goto error; 927 + return dev_err_probe(dev, PTR_ERR(provider), 928 + "Failed to register PHY provider\n"); 1071 929 } else if (channel->is_otg_channel) { 1072 930 ret = device_create_file(dev, &dev_attr_role); 1073 931 if (ret < 0) 1074 - goto error; 932 + return ret; 1075 933 } 1076 934 1077 935 return 0; 1078 - 1079 - error: 1080 - pm_runtime_disable(dev); 1081 - 1082 - return ret; 1083 936 } 1084 937 1085 938 static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) ··· 1097 932 1098 933 if (channel->is_otg_channel) 1099 934 device_remove_file(&pdev->dev, &dev_attr_role); 1100 - 1101 - pm_runtime_disable(&pdev->dev); 1102 935 } 1103 936 1104 937 static int rcar_gen3_phy_usb2_suspend(struct device *dev)
+16 -14
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
··· 749 749 return vco; 750 750 } 751 751 752 - static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw, 753 - unsigned long rate, 754 - unsigned long *parent_rate) 752 + static int inno_hdmi_phy_rk3228_clk_determine_rate(struct clk_hw *hw, 753 + struct clk_rate_request *req) 755 754 { 756 755 const struct pre_pll_config *cfg = pre_pll_cfg_table; 757 756 758 - rate = (rate / 1000) * 1000; 757 + req->rate = (req->rate / 1000) * 1000; 759 758 760 759 for (; cfg->pixclock != 0; cfg++) 761 - if (cfg->pixclock == rate && !cfg->fracdiv) 760 + if (cfg->pixclock == req->rate && !cfg->fracdiv) 762 761 break; 763 762 764 763 if (cfg->pixclock == 0) 765 764 return -EINVAL; 766 765 767 - return cfg->pixclock; 766 + req->rate = cfg->pixclock; 767 + 768 + return 0; 768 769 } 769 770 770 771 static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, ··· 836 835 .unprepare = inno_hdmi_phy_rk3228_clk_unprepare, 837 836 .is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared, 838 837 .recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate, 839 - .round_rate = inno_hdmi_phy_rk3228_clk_round_rate, 838 + .determine_rate = inno_hdmi_phy_rk3228_clk_determine_rate, 840 839 .set_rate = inno_hdmi_phy_rk3228_clk_set_rate, 841 840 }; 842 841 ··· 907 906 return inno->pixclock; 908 907 } 909 908 910 - static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, 911 - unsigned long rate, 912 - unsigned long *parent_rate) 909 + static int inno_hdmi_phy_rk3328_clk_determine_rate(struct clk_hw *hw, 910 + struct clk_rate_request *req) 913 911 { 914 912 const struct pre_pll_config *cfg = pre_pll_cfg_table; 915 913 916 - rate = (rate / 1000) * 1000; 914 + req->rate = (req->rate / 1000) * 1000; 917 915 918 916 for (; cfg->pixclock != 0; cfg++) 919 - if (cfg->pixclock == rate) 917 + if (cfg->pixclock == req->rate) 920 918 break; 921 919 922 920 if (cfg->pixclock == 0) 923 921 return -EINVAL; 924 922 925 - return cfg->pixclock; 923 + req->rate = cfg->pixclock; 924 + 925 + return 0; 926 926 } 927 927 928 928 static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, ··· 991 989 .unprepare = inno_hdmi_phy_rk3328_clk_unprepare, 992 990 .is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared, 993 991 .recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate, 994 - .round_rate = inno_hdmi_phy_rk3328_clk_round_rate, 992 + .determine_rate = inno_hdmi_phy_rk3328_clk_determine_rate, 995 993 .set_rate = inno_hdmi_phy_rk3328_clk_set_rate, 996 994 }; 997 995
+5 -7
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
··· 529 529 return -EINVAL; 530 530 } 531 531 532 - if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) { 532 + if (priv->ext_refclk) { 533 533 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); 534 534 535 535 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { ··· 554 554 } 555 555 } 556 556 557 - if (priv->type == PHY_TYPE_PCIE) { 558 - if (device_property_read_bool(priv->dev, "rockchip,enable-ssc")) 559 - rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, 560 - RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); 561 - } 557 + if (priv->type == PHY_TYPE_PCIE && priv->enable_ssc) 558 + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, 559 + RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); 562 560 563 561 return 0; 564 562 } ··· 580 582 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x101 }, 581 583 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 582 584 /* pipe-grf */ 583 - .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, 585 + .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, 584 586 }; 585 587 586 588 static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = {
+3 -1
drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
··· 1508 1508 { 1509 1509 struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); 1510 1510 1511 - return pm_runtime_put(samsung->dev); 1511 + pm_runtime_put(samsung->dev); 1512 + 1513 + return 0; 1512 1514 } 1513 1515 1514 1516 static const struct phy_ops samsung_mipi_dcphy_ops = {
+599 -159
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
··· 22 22 #include <linux/reset.h> 23 23 24 24 #define GRF_HDPTX_CON0 0x00 25 + #define LC_REF_CLK_SEL BIT(11) 25 26 #define HDPTX_I_PLL_EN BIT(7) 26 27 #define HDPTX_I_BIAS_EN BIT(6) 27 28 #define HDPTX_I_BGR_EN BIT(5) ··· 33 32 #define HDPTX_O_PHY_RDY BIT(1) 34 33 #define HDPTX_O_SB_RDY BIT(0) 35 34 36 - #define HDTPX_REG(_n, _min, _max) \ 35 + #define HDPTX_REG(_n, _min, _max) \ 37 36 ( \ 38 37 BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) + \ 39 38 BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) + \ 40 39 ((0x##_n) * 4) \ 41 40 ) 42 41 43 - #define CMN_REG(n) HDTPX_REG(n, 0000, 00a7) 44 - #define SB_REG(n) HDTPX_REG(n, 0100, 0129) 45 - #define LNTOP_REG(n) HDTPX_REG(n, 0200, 0229) 46 - #define LANE_REG(n) HDTPX_REG(n, 0300, 062d) 42 + #define CMN_REG(n) HDPTX_REG(n, 0000, 00a7) 43 + #define SB_REG(n) HDPTX_REG(n, 0100, 0129) 44 + #define LNTOP_REG(n) HDPTX_REG(n, 0200, 0229) 45 + #define LANE_REG(n) HDPTX_REG(n, 0300, 062d) 47 46 48 47 /* CMN_REG(0008) */ 49 48 #define OVRD_LCPLL_EN_MASK BIT(7) ··· 323 322 324 323 #define HDMI14_MAX_RATE 340000000 325 324 #define HDMI20_MAX_RATE 600000000 325 + #define FRL_3G3L_RATE 900000000 326 + #define FRL_6G3L_RATE 1800000000 327 + #define FRL_8G4L_RATE 3200000000 326 328 327 329 enum dp_link_rate { 328 330 DP_BW_RBR, 329 331 DP_BW_HBR, 330 332 DP_BW_HBR2, 333 + }; 334 + 335 + struct lcpll_config { 336 + unsigned long long rate; 337 + u8 lcvco_mode_en; 338 + u8 pi_en; 339 + u8 clk_en_100m; 340 + u8 pms_mdiv; 341 + u8 pms_mdiv_afc; 342 + u8 pms_pdiv; 343 + u8 pms_refdiv; 344 + u8 pms_sdiv; 345 + u8 sdm_deno; 346 + u8 sdm_num_sign; 347 + u8 sdm_num; 348 + u8 sdc_n; 331 349 }; 332 350 333 351 struct ropll_config { ··· 356 336 u8 pms_pdiv; 357 337 u8 pms_refdiv; 358 338 u8 pms_sdiv; 359 - u8 pms_iqdiv_rstn; 360 - u8 ref_clk_sel; 361 339 u8 sdm_en; 362 - u8 sdm_rstn; 363 - u8 sdc_frac_en; 364 - u8 sdc_rstn; 365 - u8 sdm_clk_div; 366 340 u8 sdm_deno; 367 341 u8 sdm_num_sign; 368 342 u8 sdm_num; 369 343 u8 sdc_n; 370 344 u8 sdc_num; 371 345 u8 sdc_deno; 372 - u8 sdc_ndiv_rstn; 373 - u8 ssc_en; 374 - u8 ssc_fm_dev; 375 - u8 ssc_fm_freq; 376 - u8 ssc_clk_div_sel; 377 - u8 ana_cpp_ctrl; 378 - u8 ana_lpf_c_sel; 379 - u8 cd_tx_ser_rate_sel; 380 346 }; 381 347 382 348 struct tx_drv_ctrl { ··· 393 387 unsigned int phy_ids[MAX_HDPTX_PHY_NUM]; 394 388 }; 395 389 390 + struct rk_hdptx_hdmi_cfg { 391 + enum phy_hdmi_mode mode; 392 + unsigned long long rate; 393 + unsigned int bpc; 394 + }; 395 + 396 396 struct rk_hdptx_phy { 397 397 struct device *dev; 398 398 struct regmap *regmap; ··· 406 394 407 395 int phy_id; 408 396 struct phy *phy; 409 - struct phy_configure_opts_hdmi hdmi_cfg; 397 + struct rk_hdptx_hdmi_cfg hdmi_cfg; 410 398 struct clk_bulk_data *clks; 411 399 int nr_clks; 412 400 struct reset_control_bulk_data rsts[RST_MAX]; 413 401 414 402 /* clk provider */ 415 403 struct clk_hw hw; 416 - unsigned long hw_rate; 417 404 bool restrict_rate_change; 418 405 419 406 atomic_t usage_count; ··· 422 411 unsigned int lanes; 423 412 }; 424 413 425 - static const struct ropll_config ropll_tmds_cfg[] = { 426 - { 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 427 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 428 - { 371250000ULL, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 429 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 430 - { 297000000ULL, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 431 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 432 - { 162000000ULL, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10, 433 - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 434 - { 185625000ULL, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 435 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 436 - { 154000000ULL, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1, 437 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 438 - { 148500000ULL, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5, 439 - 0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 440 - { 146250000ULL, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1, 441 - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 442 - { 119000000ULL, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1, 443 - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 444 - { 106500000ULL, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1, 445 - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 446 - { 108000000ULL, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 447 - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 448 - { 85500000ULL, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1, 449 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 450 - { 83500000ULL, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0, 451 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 452 - { 92812500ULL, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 453 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 454 - { 74250000ULL, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 455 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 456 - { 65000000ULL, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1, 457 - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 458 - { 50250000ULL, 84, 84, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 11, 1, 4, 5, 459 - 4, 11, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 460 - { 33750000ULL, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5, 461 - 1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 462 - { 40000000ULL, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 463 - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 464 - { 27000000ULL, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 465 - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 466 - { 25175000ULL, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1, 467 - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 414 + static const struct lcpll_config rk_hdptx_frl_lcpll_cfg[] = { 415 + /* | pms | sdm | */ 416 + /* rate, lcen, pien, cken, mdiv, mdafc, pdiv, rdiv, sdiv, deno, nsig, num, sdcn, */ 417 + { 4800000000ULL, 1, 0, 0, 125, 125, 1, 1, 0, 1, 0, 0, 2, }, 418 + { 4000000000ULL, 1, 1, 0, 104, 104, 1, 1, 0, 9, 0, 1, 1, }, 419 + { 2400000000ULL, 1, 0, 0, 125, 125, 1, 1, 1, 1, 0, 0, 2, }, 420 + { 1800000000ULL, 1, 0, 0, 125, 125, 1, 1, 1, 1, 0, 0, 2, }, 421 + { 900000000ULL, 1, 0, 0, 125, 125, 1, 1, 3, 1, 0, 0, 2, }, 468 422 }; 469 423 470 - static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { 424 + static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = { 425 + /* | pms | sdm | sdc | */ 426 + /* rate, mdiv, mdafc, pdiv, rdiv, sdiv, en, deno, nsig, num, n, num, deno, */ 427 + { 594000000ULL, 124, 124, 1, 1, 0, 1, 62, 1, 16, 5, 0, 1, }, 428 + { 461101250ULL, 97, 97, 1, 1, 0, 1, 71, 1, 53, 2, 6, 35, }, 429 + { 371250000ULL, 155, 155, 1, 1, 1, 1, 62, 1, 16, 5, 0, 1, }, 430 + { 297000000ULL, 124, 124, 1, 1, 1, 1, 62, 1, 16, 5, 0, 1, }, 431 + { 185625000ULL, 155, 155, 1, 1, 3, 1, 62, 1, 16, 5, 0, 1, }, 432 + { 162000000ULL, 135, 135, 1, 1, 3, 0, 4, 0, 3, 5, 5, 16, }, 433 + { 154000000ULL, 193, 193, 1, 1, 5, 1, 193, 1, 32, 2, 1, 1, }, 434 + { 148500000ULL, 123, 123, 1, 1, 3, 1, 4, 0, 3, 5, 5, 16, }, 435 + { 146250000ULL, 122, 122, 1, 1, 3, 1, 244, 1, 16, 2, 1, 1, }, 436 + { 119000000ULL, 149, 149, 1, 1, 5, 1, 149, 1, 16, 2, 1, 1, }, 437 + { 108000000ULL, 135, 135, 1, 1, 5, 0, 9, 0, 5, 0, 20, 24, }, 438 + { 106500000ULL, 89, 89, 1, 1, 3, 1, 89, 1, 16, 1, 0, 1, }, 439 + { 92812500ULL, 155, 155, 1, 1, 7, 1, 62, 1, 16, 5, 0, 1, }, 440 + { 85500000ULL, 214, 214, 1, 1, 11, 1, 214, 1, 16, 2, 1, 1, }, 441 + { 83500000ULL, 105, 105, 1, 1, 5, 1, 42, 1, 16, 1, 0, 1, }, 442 + { 74250000ULL, 124, 124, 1, 1, 7, 1, 62, 1, 16, 5, 0, 1, }, 443 + { 65000000ULL, 162, 162, 1, 1, 11, 1, 54, 0, 16, 4, 1, 1, }, 444 + { 50250000ULL, 84, 84, 1, 1, 7, 1, 11, 1, 4, 5, 4, 11, }, 445 + { 40000000ULL, 100, 100, 1, 1, 11, 0, 9, 0, 5, 0, 20, 24, }, 446 + { 33750000ULL, 112, 112, 1, 1, 15, 1, 2, 0, 1, 5, 1, 1, }, 447 + { 27000000ULL, 90, 90, 1, 1, 15, 0, 9, 0, 5, 0, 20, 24, }, 448 + { 25175000ULL, 84, 84, 1, 1, 15, 1, 168, 1, 16, 4, 1, 1, }, 449 + }; 450 + 451 + static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = { 471 452 REG_SEQ0(CMN_REG(0009), 0x0c), 472 453 REG_SEQ0(CMN_REG(000a), 0x83), 473 454 REG_SEQ0(CMN_REG(000b), 0x06), ··· 468 465 REG_SEQ0(CMN_REG(000e), 0x0f), 469 466 REG_SEQ0(CMN_REG(000f), 0x0f), 470 467 REG_SEQ0(CMN_REG(0010), 0x04), 471 - REG_SEQ0(CMN_REG(0011), 0x00), 472 468 REG_SEQ0(CMN_REG(0012), 0x26), 473 469 REG_SEQ0(CMN_REG(0013), 0x22), 474 470 REG_SEQ0(CMN_REG(0014), 0x24), 475 471 REG_SEQ0(CMN_REG(0015), 0x77), 476 472 REG_SEQ0(CMN_REG(0016), 0x08), 477 - REG_SEQ0(CMN_REG(0017), 0x00), 478 473 REG_SEQ0(CMN_REG(0018), 0x04), 479 474 REG_SEQ0(CMN_REG(0019), 0x48), 480 475 REG_SEQ0(CMN_REG(001a), 0x01), ··· 480 479 REG_SEQ0(CMN_REG(001c), 0x01), 481 480 REG_SEQ0(CMN_REG(001d), 0x64), 482 481 REG_SEQ0(CMN_REG(001f), 0x00), 483 - REG_SEQ0(CMN_REG(0026), 0x53), 484 482 REG_SEQ0(CMN_REG(0029), 0x01), 485 - REG_SEQ0(CMN_REG(0030), 0x00), 486 - REG_SEQ0(CMN_REG(0031), 0x20), 487 - REG_SEQ0(CMN_REG(0032), 0x30), 488 - REG_SEQ0(CMN_REG(0033), 0x0b), 489 - REG_SEQ0(CMN_REG(0034), 0x23), 490 483 REG_SEQ0(CMN_REG(0035), 0x00), 491 484 REG_SEQ0(CMN_REG(0038), 0x00), 492 485 REG_SEQ0(CMN_REG(0039), 0x00), ··· 491 496 REG_SEQ0(CMN_REG(003f), 0x83), 492 497 REG_SEQ0(CMN_REG(0040), 0x06), 493 498 REG_SEQ0(CMN_REG(0041), 0x20), 494 - REG_SEQ0(CMN_REG(0042), 0xb8), 495 499 REG_SEQ0(CMN_REG(0043), 0x00), 496 500 REG_SEQ0(CMN_REG(0044), 0x46), 497 501 REG_SEQ0(CMN_REG(0045), 0x24), ··· 500 506 REG_SEQ0(CMN_REG(004b), 0x00), 501 507 REG_SEQ0(CMN_REG(004c), 0x01), 502 508 REG_SEQ0(CMN_REG(004d), 0x64), 503 - REG_SEQ0(CMN_REG(004e), 0x14), 504 509 REG_SEQ0(CMN_REG(004f), 0x00), 505 510 REG_SEQ0(CMN_REG(0050), 0x00), 506 - REG_SEQ0(CMN_REG(005d), 0x0c), 507 511 REG_SEQ0(CMN_REG(005f), 0x01), 508 - REG_SEQ0(CMN_REG(006b), 0x04), 509 - REG_SEQ0(CMN_REG(0073), 0x30), 510 - REG_SEQ0(CMN_REG(0074), 0x00), 511 512 REG_SEQ0(CMN_REG(0075), 0x20), 512 513 REG_SEQ0(CMN_REG(0076), 0x30), 513 514 REG_SEQ0(CMN_REG(0077), 0x08), ··· 514 525 REG_SEQ0(CMN_REG(007e), 0x00), 515 526 REG_SEQ0(CMN_REG(007f), 0x00), 516 527 REG_SEQ0(CMN_REG(0080), 0x00), 517 - REG_SEQ0(CMN_REG(0081), 0x09), 518 528 REG_SEQ0(CMN_REG(0082), 0x04), 519 529 REG_SEQ0(CMN_REG(0083), 0x24), 520 530 REG_SEQ0(CMN_REG(0084), 0x20), 521 531 REG_SEQ0(CMN_REG(0085), 0x03), 522 - REG_SEQ0(CMN_REG(0086), 0x01), 523 - REG_SEQ0(CMN_REG(0087), 0x0c), 524 532 REG_SEQ0(CMN_REG(008a), 0x55), 525 533 REG_SEQ0(CMN_REG(008b), 0x25), 526 534 REG_SEQ0(CMN_REG(008c), 0x2c), ··· 529 543 REG_SEQ0(CMN_REG(0092), 0x00), 530 544 REG_SEQ0(CMN_REG(0093), 0x00), 531 545 REG_SEQ0(CMN_REG(009a), 0x11), 546 + }; 547 + 548 + static const struct reg_sequence rk_hdptx_frl_lcpll_cmn_init_seq[] = { 549 + REG_SEQ0(CMN_REG(0011), 0x00), 550 + REG_SEQ0(CMN_REG(0017), 0x00), 551 + REG_SEQ0(CMN_REG(0025), 0x10), 552 + REG_SEQ0(CMN_REG(0026), 0x53), 553 + REG_SEQ0(CMN_REG(0027), 0x01), 554 + REG_SEQ0(CMN_REG(0028), 0x0d), 555 + REG_SEQ0(CMN_REG(002e), 0x02), 556 + REG_SEQ0(CMN_REG(002f), 0x0d), 557 + REG_SEQ0(CMN_REG(0030), 0x00), 558 + REG_SEQ0(CMN_REG(0031), 0x20), 559 + REG_SEQ0(CMN_REG(0032), 0x30), 560 + REG_SEQ0(CMN_REG(0033), 0x0b), 561 + REG_SEQ0(CMN_REG(0034), 0x23), 562 + REG_SEQ0(CMN_REG(003d), 0x00), 563 + REG_SEQ0(CMN_REG(0042), 0xb8), 564 + REG_SEQ0(CMN_REG(0046), 0xff), 565 + REG_SEQ0(CMN_REG(0048), 0x44), 566 + REG_SEQ0(CMN_REG(004e), 0x14), 567 + REG_SEQ0(CMN_REG(0051), 0x00), 568 + REG_SEQ0(CMN_REG(0055), 0x00), 569 + REG_SEQ0(CMN_REG(0059), 0x11), 570 + REG_SEQ0(CMN_REG(005a), 0x03), 571 + REG_SEQ0(CMN_REG(005c), 0x05), 572 + REG_SEQ0(CMN_REG(005d), 0x0c), 573 + REG_SEQ0(CMN_REG(005e), 0x07), 574 + REG_SEQ0(CMN_REG(0060), 0x01), 575 + REG_SEQ0(CMN_REG(0064), 0x07), 576 + REG_SEQ0(CMN_REG(0065), 0x00), 577 + REG_SEQ0(CMN_REG(0069), 0x00), 578 + REG_SEQ0(CMN_REG(006b), 0x04), 579 + REG_SEQ0(CMN_REG(006c), 0x00), 580 + REG_SEQ0(CMN_REG(0070), 0x01), 581 + REG_SEQ0(CMN_REG(0073), 0x30), 582 + REG_SEQ0(CMN_REG(0074), 0x00), 583 + REG_SEQ0(CMN_REG(0081), 0x09), 584 + REG_SEQ0(CMN_REG(0086), 0x01), 585 + REG_SEQ0(CMN_REG(0087), 0x0c), 586 + REG_SEQ0(CMN_REG(0089), 0x02), 587 + REG_SEQ0(CMN_REG(0095), 0x00), 588 + REG_SEQ0(CMN_REG(0097), 0x00), 589 + REG_SEQ0(CMN_REG(0099), 0x00), 532 590 REG_SEQ0(CMN_REG(009b), 0x10), 533 591 }; 534 592 535 - static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { 593 + static const struct reg_sequence rk_hdptx_frl_lcpll_ropll_cmn_init_seq[] = { 594 + REG_SEQ0(CMN_REG(0008), 0xd0), 595 + REG_SEQ0(CMN_REG(0011), 0x00), 596 + REG_SEQ0(CMN_REG(0017), 0x00), 597 + REG_SEQ0(CMN_REG(001e), 0x35), 598 + REG_SEQ0(CMN_REG(0020), 0x6b), 599 + REG_SEQ0(CMN_REG(0021), 0x6b), 600 + REG_SEQ0(CMN_REG(0022), 0x11), 601 + REG_SEQ0(CMN_REG(0024), 0x00), 602 + REG_SEQ0(CMN_REG(0025), 0x10), 603 + REG_SEQ0(CMN_REG(0026), 0x53), 604 + REG_SEQ0(CMN_REG(0027), 0x15), 605 + REG_SEQ0(CMN_REG(0028), 0x0d), 606 + REG_SEQ0(CMN_REG(002a), 0x09), 607 + REG_SEQ0(CMN_REG(002b), 0x01), 608 + REG_SEQ0(CMN_REG(002c), 0x02), 609 + REG_SEQ0(CMN_REG(002d), 0x02), 610 + REG_SEQ0(CMN_REG(002e), 0x0d), 611 + REG_SEQ0(CMN_REG(002f), 0x61), 612 + REG_SEQ0(CMN_REG(0030), 0x00), 613 + REG_SEQ0(CMN_REG(0031), 0x20), 614 + REG_SEQ0(CMN_REG(0032), 0x30), 615 + REG_SEQ0(CMN_REG(0033), 0x0b), 616 + REG_SEQ0(CMN_REG(0034), 0x23), 617 + REG_SEQ0(CMN_REG(0037), 0x00), 618 + REG_SEQ0(CMN_REG(003d), 0xc0), 619 + REG_SEQ0(CMN_REG(0042), 0xb8), 620 + REG_SEQ0(CMN_REG(0046), 0xff), 621 + REG_SEQ0(CMN_REG(0048), 0x44), 622 + REG_SEQ0(CMN_REG(004e), 0x14), 623 + REG_SEQ0(CMN_REG(0054), 0x19), 624 + REG_SEQ0(CMN_REG(0058), 0x19), 625 + REG_SEQ0(CMN_REG(0059), 0x11), 626 + REG_SEQ0(CMN_REG(005b), 0x30), 627 + REG_SEQ0(CMN_REG(005c), 0x25), 628 + REG_SEQ0(CMN_REG(005d), 0x14), 629 + REG_SEQ0(CMN_REG(005e), 0x0e), 630 + REG_SEQ0(CMN_REG(0063), 0x01), 631 + REG_SEQ0(CMN_REG(0064), 0x0e), 632 + REG_SEQ0(CMN_REG(0068), 0x00), 633 + REG_SEQ0(CMN_REG(0069), 0x02), 634 + REG_SEQ0(CMN_REG(006b), 0x00), 635 + REG_SEQ0(CMN_REG(006f), 0x00), 636 + REG_SEQ0(CMN_REG(0073), 0x02), 637 + REG_SEQ0(CMN_REG(0074), 0x00), 638 + REG_SEQ0(CMN_REG(007a), 0x00), 639 + REG_SEQ0(CMN_REG(0081), 0x09), 640 + REG_SEQ0(CMN_REG(0086), 0x11), 641 + REG_SEQ0(CMN_REG(0087), 0x0c), 642 + REG_SEQ0(CMN_REG(0089), 0x00), 643 + REG_SEQ0(CMN_REG(0095), 0x03), 644 + REG_SEQ0(CMN_REG(0097), 0x00), 645 + REG_SEQ0(CMN_REG(0099), 0x00), 646 + REG_SEQ0(CMN_REG(009b), 0x10), 647 + REG_SEQ0(CMN_REG(009e), 0x03), 648 + REG_SEQ0(CMN_REG(009f), 0xff), 649 + REG_SEQ0(CMN_REG(00a0), 0x60), 650 + }; 651 + 652 + static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = { 536 653 REG_SEQ0(CMN_REG(0008), 0x00), 537 654 REG_SEQ0(CMN_REG(0011), 0x01), 538 655 REG_SEQ0(CMN_REG(0017), 0x20), ··· 666 577 REG_SEQ0(CMN_REG(0048), 0x11), 667 578 REG_SEQ0(CMN_REG(004e), 0x34), 668 579 REG_SEQ0(CMN_REG(005c), 0x25), 580 + REG_SEQ0(CMN_REG(005d), 0x0c), 669 581 REG_SEQ0(CMN_REG(005e), 0x4f), 582 + REG_SEQ0(CMN_REG(006b), 0x04), 583 + REG_SEQ0(CMN_REG(0073), 0x30), 670 584 REG_SEQ0(CMN_REG(0074), 0x04), 671 585 REG_SEQ0(CMN_REG(0081), 0x01), 586 + REG_SEQ0(CMN_REG(0086), 0x01), 672 587 REG_SEQ0(CMN_REG(0087), 0x04), 673 588 REG_SEQ0(CMN_REG(0089), 0x00), 674 589 REG_SEQ0(CMN_REG(0095), 0x00), ··· 681 588 REG_SEQ0(CMN_REG(009b), 0x00), 682 589 }; 683 590 684 - static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = { 591 + static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = { 685 592 REG_SEQ0(SB_REG(0114), 0x00), 686 593 REG_SEQ0(SB_REG(0115), 0x00), 687 594 REG_SEQ0(SB_REG(0116), 0x00), 688 595 REG_SEQ0(SB_REG(0117), 0x00), 689 596 }; 690 597 691 - static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = { 598 + static const struct reg_sequence rk_hdptx_frl_lntop_init_seq[] = { 599 + REG_SEQ0(LNTOP_REG(0200), 0x04), 600 + REG_SEQ0(LNTOP_REG(0201), 0x00), 601 + REG_SEQ0(LNTOP_REG(0202), 0x00), 602 + REG_SEQ0(LNTOP_REG(0203), 0xf0), 603 + REG_SEQ0(LNTOP_REG(0204), 0xff), 604 + REG_SEQ0(LNTOP_REG(0205), 0xff), 605 + REG_SEQ0(LNTOP_REG(0206), 0x05), 606 + }; 607 + 608 + static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = { 692 609 REG_SEQ0(LNTOP_REG(0201), 0x00), 693 610 REG_SEQ0(LNTOP_REG(0202), 0x00), 694 611 REG_SEQ0(LNTOP_REG(0203), 0x0f), ··· 706 603 REG_SEQ0(LNTOP_REG(0205), 0xff), 707 604 }; 708 605 709 - static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = { 606 + static const struct reg_sequence rk_hdptx_tmds_lntop_lowbr_seq[] = { 710 607 REG_SEQ0(LNTOP_REG(0201), 0x07), 711 608 REG_SEQ0(LNTOP_REG(0202), 0xc1), 712 609 REG_SEQ0(LNTOP_REG(0203), 0xf0), ··· 714 611 REG_SEQ0(LNTOP_REG(0205), 0x1f), 715 612 }; 716 613 717 - static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { 614 + static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = { 718 615 REG_SEQ0(LANE_REG(0303), 0x0c), 719 616 REG_SEQ0(LANE_REG(0307), 0x20), 720 617 REG_SEQ0(LANE_REG(030a), 0x17), ··· 769 666 REG_SEQ0(LANE_REG(0620), 0xa0), 770 667 }; 771 668 772 - static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { 669 + static const struct reg_sequence rk_hdptx_frl_lane_init_seq[] = { 670 + REG_SEQ0(LANE_REG(0312), 0x3c), 671 + REG_SEQ0(LANE_REG(0412), 0x3c), 672 + REG_SEQ0(LANE_REG(0512), 0x3c), 673 + REG_SEQ0(LANE_REG(0612), 0x3c), 674 + REG_SEQ0(LANE_REG(0303), 0x2f), 675 + REG_SEQ0(LANE_REG(0403), 0x2f), 676 + REG_SEQ0(LANE_REG(0503), 0x2f), 677 + REG_SEQ0(LANE_REG(0603), 0x2f), 678 + REG_SEQ0(LANE_REG(0305), 0x03), 679 + REG_SEQ0(LANE_REG(0405), 0x03), 680 + REG_SEQ0(LANE_REG(0505), 0x03), 681 + REG_SEQ0(LANE_REG(0605), 0x03), 682 + REG_SEQ0(LANE_REG(0306), 0xfc), 683 + REG_SEQ0(LANE_REG(0406), 0xfc), 684 + REG_SEQ0(LANE_REG(0506), 0xfc), 685 + REG_SEQ0(LANE_REG(0606), 0xfc), 686 + REG_SEQ0(LANE_REG(0305), 0x4f), 687 + REG_SEQ0(LANE_REG(0405), 0x4f), 688 + REG_SEQ0(LANE_REG(0505), 0x4f), 689 + REG_SEQ0(LANE_REG(0605), 0x4f), 690 + REG_SEQ0(LANE_REG(0304), 0x14), 691 + REG_SEQ0(LANE_REG(0404), 0x14), 692 + REG_SEQ0(LANE_REG(0504), 0x14), 693 + REG_SEQ0(LANE_REG(0604), 0x14), 694 + /* Keep Inter-Pair Skew in the limits */ 695 + REG_SEQ0(LANE_REG(031e), 0x02), 696 + REG_SEQ0(LANE_REG(041e), 0x02), 697 + REG_SEQ0(LANE_REG(051e), 0x02), 698 + REG_SEQ0(LANE_REG(061e), 0x02), 699 + }; 700 + 701 + static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = { 773 702 REG_SEQ0(LANE_REG(0312), 0x00), 774 703 REG_SEQ0(LANE_REG(0412), 0x00), 775 704 REG_SEQ0(LANE_REG(0512), 0x00), ··· 964 829 HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN; 965 830 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); 966 831 832 + /* 3 lanes FRL mode */ 833 + if (hdptx->hdmi_cfg.rate == FRL_6G3L_RATE || 834 + hdptx->hdmi_cfg.rate == FRL_3G3L_RATE) 835 + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x07); 836 + else 837 + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f); 838 + 967 839 ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, 968 840 (val & HDPTX_O_PHY_RDY) && 969 841 (val & HDPTX_O_PLL_LOCK_DONE), ··· 1024 882 usleep_range(20, 30); 1025 883 reset_control_deassert(hdptx->rsts[RST_APB].rstc); 1026 884 885 + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0); 1027 886 regmap_write(hdptx->regmap, LANE_REG(0300), 0x82); 1028 887 regmap_write(hdptx->regmap, SB_REG(010f), 0xc1); 1029 888 regmap_write(hdptx->regmap, SB_REG(0110), 0x1); ··· 1113 970 return true; 1114 971 } 1115 972 1116 - static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) 973 + static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx) 974 + { 975 + const struct lcpll_config *cfg = NULL; 976 + int i; 977 + 978 + dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate); 979 + 980 + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) { 981 + if (hdptx->hdmi_cfg.rate == rk_hdptx_frl_lcpll_cfg[i].rate) { 982 + cfg = &rk_hdptx_frl_lcpll_cfg[i]; 983 + break; 984 + } 985 + } 986 + 987 + if (!cfg) { 988 + dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n", 989 + __func__, hdptx->hdmi_cfg.rate); 990 + return -EINVAL; 991 + } 992 + 993 + rk_hdptx_pre_power_up(hdptx); 994 + 995 + regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16); 996 + 997 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); 998 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_cmn_init_seq); 999 + 1000 + regmap_update_bits(hdptx->regmap, CMN_REG(0008), 1001 + LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK, 1002 + FIELD_PREP(LCPLL_EN_MASK, 1) | 1003 + FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en)); 1004 + 1005 + regmap_update_bits(hdptx->regmap, CMN_REG(001e), 1006 + LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK, 1007 + FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) | 1008 + FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m)); 1009 + 1010 + regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv); 1011 + regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc); 1012 + regmap_write(hdptx->regmap, CMN_REG(0022), 1013 + (cfg->pms_pdiv << 4) | cfg->pms_refdiv); 1014 + regmap_write(hdptx->regmap, CMN_REG(0023), 1015 + (cfg->pms_sdiv << 4) | cfg->pms_sdiv); 1016 + regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno); 1017 + regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign); 1018 + regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num); 1019 + 1020 + regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK, 1021 + FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n)); 1022 + 1023 + regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, 1024 + FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); 1025 + regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, 1026 + FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->hdmi_cfg.bpc - 8) >> 1)); 1027 + 1028 + return rk_hdptx_post_enable_pll(hdptx); 1029 + } 1030 + 1031 + static int rk_hdptx_frl_lcpll_ropll_cmn_config(struct rk_hdptx_phy *hdptx) 1032 + { 1033 + dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate); 1034 + 1035 + rk_hdptx_pre_power_up(hdptx); 1036 + 1037 + /* ROPLL input reference clock from LCPLL (cascade mode) */ 1038 + regmap_write(hdptx->grf, GRF_HDPTX_CON0, 1039 + (LC_REF_CLK_SEL << 16) | LC_REF_CLK_SEL); 1040 + 1041 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); 1042 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_ropll_cmn_init_seq); 1043 + 1044 + return rk_hdptx_post_enable_pll(hdptx); 1045 + } 1046 + 1047 + static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx) 1117 1048 { 1118 1049 const struct ropll_config *cfg = NULL; 1119 1050 struct ropll_config rc = {0}; 1120 - int ret, i; 1051 + int i; 1121 1052 1122 - if (!hdptx->hdmi_cfg.tmds_char_rate) 1053 + if (!hdptx->hdmi_cfg.rate) 1123 1054 return 0; 1124 1055 1125 - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) 1126 - if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) { 1127 - cfg = &ropll_tmds_cfg[i]; 1056 + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++) 1057 + if (hdptx->hdmi_cfg.rate == rk_hdptx_tmds_ropll_cfg[i].rate) { 1058 + cfg = &rk_hdptx_tmds_ropll_cfg[i]; 1128 1059 break; 1129 1060 } 1130 1061 1131 1062 if (!cfg) { 1132 - if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.tmds_char_rate, &rc)) { 1063 + if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.rate, &rc)) { 1133 1064 dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n", 1134 - __func__, hdptx->hdmi_cfg.tmds_char_rate); 1065 + __func__, hdptx->hdmi_cfg.rate); 1135 1066 return -EINVAL; 1136 1067 } 1137 1068 ··· 1213 996 } 1214 997 1215 998 dev_dbg(hdptx->dev, "%s rate=%llu mdiv=%u sdiv=%u sdm_en=%u k_sign=%u k=%u lc=%u\n", 1216 - __func__, hdptx->hdmi_cfg.tmds_char_rate, cfg->pms_mdiv, cfg->pms_sdiv + 1, 999 + __func__, hdptx->hdmi_cfg.rate, cfg->pms_mdiv, cfg->pms_sdiv + 1, 1217 1000 cfg->sdm_en, cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno); 1218 1001 1219 1002 rk_hdptx_pre_power_up(hdptx); 1220 1003 1221 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq); 1222 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq); 1004 + regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16); 1005 + 1006 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); 1007 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq); 1223 1008 1224 1009 regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv); 1225 1010 regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc); ··· 1255 1036 regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK, 1256 1037 FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1)); 1257 1038 1258 - ret = rk_hdptx_post_enable_pll(hdptx); 1259 - if (!ret) 1260 - hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, 1261 - hdptx->hdmi_cfg.bpc); 1262 - 1263 - return ret; 1039 + return rk_hdptx_post_enable_pll(hdptx); 1264 1040 } 1265 1041 1266 - static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx) 1042 + static int rk_hdptx_pll_cmn_config(struct rk_hdptx_phy *hdptx) 1267 1043 { 1268 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); 1044 + if (hdptx->hdmi_cfg.rate <= HDMI20_MAX_RATE) 1045 + return rk_hdptx_tmds_ropll_cmn_config(hdptx); 1046 + 1047 + if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE) 1048 + return rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx); 1049 + 1050 + return rk_hdptx_frl_lcpll_cmn_config(hdptx); 1051 + } 1052 + 1053 + static int rk_hdptx_frl_lcpll_mode_config(struct rk_hdptx_phy *hdptx) 1054 + { 1055 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq); 1056 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lntop_init_seq); 1057 + 1058 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq); 1059 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lane_init_seq); 1060 + 1061 + return rk_hdptx_post_enable_lane(hdptx); 1062 + } 1063 + 1064 + static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx) 1065 + { 1066 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq); 1269 1067 1270 1068 regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06); 1271 1069 1272 - if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) { 1070 + if (hdptx->hdmi_cfg.rate > HDMI14_MAX_RATE) { 1273 1071 /* For 1/40 bitrate clk */ 1274 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq); 1072 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq); 1275 1073 } else { 1276 1074 /* For 1/10 bitrate clk */ 1277 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq); 1075 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_lowbr_seq); 1278 1076 } 1279 1077 1280 1078 regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07); 1281 - regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f); 1282 1079 1283 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); 1284 - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq); 1080 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq); 1081 + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq); 1285 1082 1286 1083 return rk_hdptx_post_enable_lane(hdptx); 1287 1084 } ··· 1309 1074 reset_control_assert(hdptx->rsts[RST_INIT].rstc); 1310 1075 1311 1076 reset_control_assert(hdptx->rsts[RST_APB].rstc); 1312 - udelay(10); 1077 + usleep_range(10, 15); 1313 1078 reset_control_deassert(hdptx->rsts[RST_APB].rstc); 1314 1079 1315 1080 regmap_update_bits(hdptx->regmap, LANE_REG(0301), ··· 1356 1121 if (mode == PHY_MODE_DP) { 1357 1122 rk_hdptx_dp_reset(hdptx); 1358 1123 } else { 1359 - ret = rk_hdptx_ropll_tmds_cmn_config(hdptx); 1124 + ret = rk_hdptx_pll_cmn_config(hdptx); 1360 1125 if (ret) 1361 1126 goto dec_usage; 1362 1127 } ··· 1657 1422 int ret, lane; 1658 1423 1659 1424 if (mode != PHY_MODE_DP) { 1660 - if (!hdptx->hdmi_cfg.tmds_char_rate) { 1425 + if (!hdptx->hdmi_cfg.rate && hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) { 1661 1426 /* 1662 1427 * FIXME: Temporary workaround to setup TMDS char rate 1663 1428 * from the RK DW HDMI QP bridge driver. 1664 1429 * Will be removed as soon the switch to the HDMI PHY 1665 1430 * configuration API has been completed on both ends. 1666 1431 */ 1667 - hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff; 1668 - hdptx->hdmi_cfg.tmds_char_rate *= 100; 1432 + hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff; 1433 + hdptx->hdmi_cfg.rate *= 100; 1669 1434 } 1670 1435 1671 1436 dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, 1672 - hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); 1437 + hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc); 1673 1438 } 1674 1439 1675 1440 ret = rk_hdptx_phy_consumer_get(hdptx); ··· 1703 1468 regmap_write(hdptx->grf, GRF_HDPTX_CON0, 1704 1469 HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0)); 1705 1470 1706 - ret = rk_hdptx_ropll_tmds_mode_config(hdptx); 1471 + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) 1472 + ret = rk_hdptx_frl_lcpll_mode_config(hdptx); 1473 + else 1474 + ret = rk_hdptx_tmds_ropll_mode_config(hdptx); 1475 + 1707 1476 if (ret) 1708 1477 rk_hdptx_phy_consumer_put(hdptx, true); 1709 1478 } ··· 1723 1484 } 1724 1485 1725 1486 static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx, 1726 - struct phy_configure_opts_hdmi *hdmi) 1487 + struct phy_configure_opts_hdmi *hdmi_in, 1488 + struct rk_hdptx_hdmi_cfg *hdmi_out) 1727 1489 { 1728 1490 int i; 1729 1491 1730 - if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE) 1731 - return -EINVAL; 1492 + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) { 1493 + unsigned long long frl_rate = 100000000ULL * hdmi_in->frl.lanes * 1494 + hdmi_in->frl.rate_per_lane; 1732 1495 1733 - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) 1734 - if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate) 1496 + switch (hdmi_in->frl.rate_per_lane) { 1497 + case 3: 1498 + case 6: 1499 + case 8: 1500 + case 10: 1501 + case 12: 1735 1502 break; 1503 + default: 1504 + return -EINVAL; 1505 + } 1736 1506 1737 - if (i == ARRAY_SIZE(ropll_tmds_cfg) && 1738 - !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL)) 1739 - return -EINVAL; 1507 + if (!hdmi_in->frl.lanes || hdmi_in->frl.lanes > 4) 1508 + return -EINVAL; 1740 1509 1741 - if (!hdmi->bpc) 1742 - hdmi->bpc = 8; 1510 + if (frl_rate != FRL_8G4L_RATE) { 1511 + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) 1512 + if (frl_rate == rk_hdptx_frl_lcpll_cfg[i].rate) 1513 + break; 1514 + if (i == ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg)) 1515 + return -EINVAL; 1516 + } 1743 1517 1744 - switch (hdmi->bpc) { 1518 + if (hdmi_out) 1519 + hdmi_out->rate = frl_rate; 1520 + } else { 1521 + if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE) 1522 + return -EINVAL; 1523 + 1524 + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++) 1525 + if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) 1526 + break; 1527 + 1528 + if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) && 1529 + !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL)) 1530 + return -EINVAL; 1531 + 1532 + if (hdmi_out) 1533 + hdmi_out->rate = hdmi_in->tmds_char_rate; 1534 + } 1535 + 1536 + switch (hdmi_in->bpc) { 1537 + case 0: 1745 1538 case 8: 1746 1539 case 10: 1747 1540 case 12: ··· 1782 1511 default: 1783 1512 return -EINVAL; 1784 1513 } 1514 + 1515 + if (hdmi_out) 1516 + hdmi_out->bpc = hdmi_in->bpc ?: 8; 1785 1517 1786 1518 return 0; 1787 1519 } ··· 1930 1656 regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset, 1931 1657 LN_TX_JEQ_EVEN_CTRL_RBR_MASK, 1932 1658 FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK, 1933 - ctrl->tx_jeq_even_ctrl)); 1659 + ctrl->tx_jeq_even_ctrl)); 1934 1660 regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset, 1935 1661 LN_TX_JEQ_ODD_CTRL_RBR_MASK, 1936 1662 FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK, 1937 - ctrl->tx_jeq_odd_ctrl)); 1663 + ctrl->tx_jeq_odd_ctrl)); 1938 1664 regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, 1939 1665 LN_TX_SER_40BIT_EN_RBR_MASK, 1940 1666 FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1)); ··· 1944 1670 regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset, 1945 1671 LN_TX_JEQ_EVEN_CTRL_HBR_MASK, 1946 1672 FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK, 1947 - ctrl->tx_jeq_even_ctrl)); 1673 + ctrl->tx_jeq_even_ctrl)); 1948 1674 regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset, 1949 1675 LN_TX_JEQ_ODD_CTRL_HBR_MASK, 1950 1676 FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK, 1951 - ctrl->tx_jeq_odd_ctrl)); 1677 + ctrl->tx_jeq_odd_ctrl)); 1952 1678 regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, 1953 1679 LN_TX_SER_40BIT_EN_HBR_MASK, 1954 1680 FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1)); ··· 1959 1685 regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset, 1960 1686 LN_TX_JEQ_EVEN_CTRL_HBR2_MASK, 1961 1687 FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK, 1962 - ctrl->tx_jeq_even_ctrl)); 1688 + ctrl->tx_jeq_even_ctrl)); 1963 1689 regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset, 1964 1690 LN_TX_JEQ_ODD_CTRL_HBR2_MASK, 1965 1691 FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK, 1966 - ctrl->tx_jeq_odd_ctrl)); 1692 + ctrl->tx_jeq_odd_ctrl)); 1967 1693 regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, 1968 1694 LN_TX_SER_40BIT_EN_HBR2_MASK, 1969 1695 FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1)); ··· 2044 1770 return 0; 2045 1771 } 2046 1772 1773 + static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 1774 + { 1775 + struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); 1776 + 1777 + if (mode == PHY_MODE_DP) 1778 + return 0; 1779 + 1780 + if (mode != PHY_MODE_HDMI) { 1781 + dev_err(&phy->dev, "invalid PHY mode: %d\n", mode); 1782 + return -EINVAL; 1783 + } 1784 + 1785 + switch (submode) { 1786 + case PHY_HDMI_MODE_TMDS: 1787 + case PHY_HDMI_MODE_FRL: 1788 + hdptx->hdmi_cfg.mode = submode; 1789 + break; 1790 + default: 1791 + dev_err(&phy->dev, "invalid HDMI mode: %d\n", submode); 1792 + return -EINVAL; 1793 + } 1794 + 1795 + return 0; 1796 + } 1797 + 2047 1798 static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts) 2048 1799 { 2049 1800 struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); ··· 2076 1777 int ret; 2077 1778 2078 1779 if (mode != PHY_MODE_DP) { 2079 - ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); 1780 + ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, &hdptx->hdmi_cfg); 2080 1781 if (ret) { 2081 1782 dev_err(hdptx->dev, "invalid hdmi params for phy configure\n"); 2082 1783 } else { 2083 - hdptx->hdmi_cfg = opts->hdmi; 2084 1784 hdptx->restrict_rate_change = true; 1785 + dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, 1786 + hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc); 2085 1787 } 2086 1788 2087 - dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, 2088 - hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); 2089 1789 return ret; 2090 1790 } 2091 1791 ··· 2128 1830 struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); 2129 1831 2130 1832 if (mode != PHY_MODE_DP) 2131 - return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); 1833 + return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, NULL); 2132 1834 2133 1835 return rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp); 2134 1836 } ··· 2136 1838 static const struct phy_ops rk_hdptx_phy_ops = { 2137 1839 .power_on = rk_hdptx_phy_power_on, 2138 1840 .power_off = rk_hdptx_phy_power_off, 1841 + .set_mode = rk_hdptx_phy_set_mode, 2139 1842 .configure = rk_hdptx_phy_configure, 2140 1843 .validate = rk_hdptx_phy_validate, 2141 1844 .owner = THIS_MODULE, ··· 2161 1862 rk_hdptx_phy_consumer_put(hdptx, true); 2162 1863 } 2163 1864 1865 + #define PLL_REF_CLK 24000000ULL 1866 + 1867 + static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx) 1868 + { 1869 + struct lcpll_config lcpll_hw; 1870 + struct ropll_config ropll_hw; 1871 + u64 fout, sdm; 1872 + u32 mode, val; 1873 + int ret, i; 1874 + 1875 + ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode); 1876 + if (ret) 1877 + return 0; 1878 + 1879 + if (mode & LCPLL_LCVCO_MODE_EN_MASK) { 1880 + ret = regmap_read(hdptx->regmap, CMN_REG(0020), &val); 1881 + if (ret) 1882 + return 0; 1883 + lcpll_hw.pms_mdiv = val; 1884 + 1885 + ret = regmap_read(hdptx->regmap, CMN_REG(0023), &val); 1886 + if (ret) 1887 + return 0; 1888 + lcpll_hw.pms_sdiv = val & 0xf; 1889 + 1890 + ret = regmap_read(hdptx->regmap, CMN_REG(002B), &val); 1891 + if (ret) 1892 + return 0; 1893 + lcpll_hw.sdm_num_sign = val; 1894 + 1895 + ret = regmap_read(hdptx->regmap, CMN_REG(002C), &val); 1896 + if (ret) 1897 + return 0; 1898 + lcpll_hw.sdm_num = val; 1899 + 1900 + ret = regmap_read(hdptx->regmap, CMN_REG(002A), &val); 1901 + if (ret) 1902 + return 0; 1903 + lcpll_hw.sdm_deno = val; 1904 + 1905 + ret = regmap_read(hdptx->regmap, CMN_REG(002D), &val); 1906 + if (ret) 1907 + return 0; 1908 + lcpll_hw.sdc_n = (val & LCPLL_SDC_N_MASK) >> 1; 1909 + 1910 + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) { 1911 + const struct lcpll_config *cfg = &rk_hdptx_frl_lcpll_cfg[i]; 1912 + 1913 + if (cfg->pms_mdiv == lcpll_hw.pms_mdiv && 1914 + cfg->pms_sdiv == lcpll_hw.pms_sdiv && 1915 + cfg->sdm_num_sign == lcpll_hw.sdm_num_sign && 1916 + cfg->sdm_num == lcpll_hw.sdm_num && 1917 + cfg->sdm_deno == lcpll_hw.sdm_deno && 1918 + cfg->sdc_n == lcpll_hw.sdc_n) 1919 + return cfg->rate; 1920 + } 1921 + 1922 + dev_dbg(hdptx->dev, "%s no FRL match found\n", __func__); 1923 + return 0; 1924 + } 1925 + 1926 + ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val); 1927 + if (ret) 1928 + return 0; 1929 + ropll_hw.pms_mdiv = val; 1930 + 1931 + ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val); 1932 + if (ret) 1933 + return 0; 1934 + ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK; 1935 + 1936 + ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val); 1937 + if (ret) 1938 + return 0; 1939 + ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK; 1940 + 1941 + ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val); 1942 + if (ret) 1943 + return 0; 1944 + ropll_hw.sdm_num = val; 1945 + 1946 + ret = regmap_read(hdptx->regmap, CMN_REG(0060), &val); 1947 + if (ret) 1948 + return 0; 1949 + ropll_hw.sdm_deno = val; 1950 + 1951 + ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val); 1952 + if (ret) 1953 + return 0; 1954 + ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3; 1955 + 1956 + ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val); 1957 + if (ret) 1958 + return 0; 1959 + ropll_hw.sdc_num = val; 1960 + 1961 + ret = regmap_read(hdptx->regmap, CMN_REG(0070), &val); 1962 + if (ret) 1963 + return 0; 1964 + ropll_hw.sdc_deno = val; 1965 + 1966 + ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val); 1967 + if (ret) 1968 + return 0; 1969 + ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1; 1970 + 1971 + fout = PLL_REF_CLK * ropll_hw.pms_mdiv; 1972 + if (ropll_hw.sdm_en) { 1973 + sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno * 1974 + ropll_hw.pms_mdiv * ropll_hw.sdm_num, 1975 + 16 * ropll_hw.sdm_deno * 1976 + (ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num)); 1977 + 1978 + if (ropll_hw.sdm_num_sign) 1979 + fout = fout - sdm; 1980 + else 1981 + fout = fout + sdm; 1982 + } 1983 + 1984 + return div_u64(fout * 2, ropll_hw.pms_sdiv * 10); 1985 + } 1986 + 2164 1987 static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw, 2165 1988 unsigned long parent_rate) 2166 1989 { 2167 1990 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1991 + u32 status; 1992 + u64 rate; 1993 + int ret; 2168 1994 2169 - return hdptx->hw_rate; 1995 + ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status); 1996 + if (ret || !(status & HDPTX_I_PLL_EN)) 1997 + return 0; 1998 + 1999 + rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx); 2000 + 2001 + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) 2002 + return rate; 2003 + 2004 + return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc); 2170 2005 } 2171 2006 2172 - static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, 2173 - unsigned long *parent_rate) 2007 + static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw, 2008 + struct clk_rate_request *req) 2174 2009 { 2175 2010 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 2011 + 2012 + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) 2013 + return hdptx->hdmi_cfg.rate; 2176 2014 2177 2015 /* 2178 2016 * FIXME: Temporarily allow altering TMDS char rate via CCF. 2179 2017 * To be dropped as soon as the RK DW HDMI QP bridge driver 2180 2018 * switches to make use of phy_configure(). 2181 2019 */ 2182 - if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) { 2020 + if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.rate) { 2183 2021 struct phy_configure_opts_hdmi hdmi = { 2184 - .tmds_char_rate = rate, 2022 + .tmds_char_rate = req->rate, 2185 2023 }; 2186 - int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi); 2024 + 2025 + int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi, &hdptx->hdmi_cfg); 2187 2026 2188 2027 if (ret) 2189 2028 return ret; 2190 - 2191 - hdptx->hdmi_cfg = hdmi; 2192 2029 } 2193 2030 2194 2031 /* ··· 2332 1897 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with 2333 1898 * a different rate argument. 2334 1899 */ 2335 - return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc); 1900 + req->rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8, hdptx->hdmi_cfg.bpc); 1901 + 1902 + return 0; 2336 1903 } 2337 1904 2338 1905 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, 2339 1906 unsigned long parent_rate) 2340 1907 { 2341 1908 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 2342 - unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); 1909 + unsigned long long link_rate = rate; 2343 1910 2344 - /* Revert any unlikely TMDS char rate change since round_rate() */ 2345 - if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { 1911 + if (hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) 1912 + link_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); 1913 + 1914 + /* Revert any unlikely link rate change since determine_rate() */ 1915 + if (hdptx->hdmi_cfg.rate != link_rate) { 2346 1916 dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n", 2347 - tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); 2348 - hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; 1917 + link_rate, hdptx->hdmi_cfg.rate); 1918 + hdptx->hdmi_cfg.rate = link_rate; 2349 1919 } 2350 1920 2351 1921 /* 2352 - * The TMDS char rate would be normally programmed in HW during 1922 + * The link rate would be normally programmed in HW during 2353 1923 * phy_ops.power_on() or clk_ops.prepare() callbacks, but it might 2354 1924 * happen that the former gets fired too late, i.e. after this call, 2355 1925 * while the latter being executed only once, i.e. when clock remains 2356 1926 * in the prepared state during rate changes. 2357 1927 */ 2358 - return rk_hdptx_ropll_tmds_cmn_config(hdptx); 1928 + return rk_hdptx_pll_cmn_config(hdptx); 2359 1929 } 2360 1930 2361 1931 static const struct clk_ops hdptx_phy_clk_ops = { 2362 1932 .prepare = rk_hdptx_phy_clk_prepare, 2363 1933 .unprepare = rk_hdptx_phy_clk_unprepare, 2364 1934 .recalc_rate = rk_hdptx_phy_clk_recalc_rate, 2365 - .round_rate = rk_hdptx_phy_clk_round_rate, 1935 + .determine_rate = rk_hdptx_phy_clk_determine_rate, 2366 1936 .set_rate = rk_hdptx_phy_clk_set_rate, 2367 1937 }; 2368 1938
+2 -5
drivers/phy/rockchip/phy-rockchip-usb.c
··· 446 446 struct device *dev = &pdev->dev; 447 447 struct rockchip_usb_phy_base *phy_base; 448 448 struct phy_provider *phy_provider; 449 - struct device_node *child; 450 449 int err; 451 450 452 451 phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL); ··· 471 472 return PTR_ERR(phy_base->reg_base); 472 473 } 473 474 474 - for_each_available_child_of_node(dev->of_node, child) { 475 + for_each_available_child_of_node_scoped(dev->of_node, child) { 475 476 err = rockchip_usb_phy_init(phy_base, child); 476 - if (err) { 477 - of_node_put(child); 477 + if (err) 478 478 return err; 479 - } 480 479 } 481 480 482 481 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+651
drivers/phy/samsung/phy-exynos5-usbdrd.c
··· 41 41 #define EXYNOS2200_CLKRST_LINK_PCLK_SEL BIT(1) 42 42 43 43 #define EXYNOS2200_DRD_UTMI 0x10 44 + 45 + /* ExynosAutov920 bits */ 46 + #define UTMICTL_FORCE_UTMI_SUSPEND BIT(13) 47 + #define UTMICTL_FORCE_UTMI_SLEEP BIT(12) 48 + #define UTMICTL_FORCE_DPPULLDOWN BIT(9) 49 + #define UTMICTL_FORCE_DMPULLDOWN BIT(8) 50 + 44 51 #define EXYNOS2200_UTMI_FORCE_VBUSVALID BIT(1) 45 52 #define EXYNOS2200_UTMI_FORCE_BVALID BIT(0) 46 53 ··· 256 249 257 250 #define EXYNOS850_DRD_HSP_TEST 0x5c 258 251 #define HSP_TEST_SIDDQ BIT(24) 252 + 253 + #define EXYNOSAUTOV920_DRD_HSP_CLKRST 0x100 254 + #define HSPCLKRST_PHY20_SW_PORTRESET BIT(3) 255 + #define HSPCLKRST_PHY20_SW_POR BIT(1) 256 + #define HSPCLKRST_PHY20_SW_POR_SEL BIT(0) 257 + 258 + #define EXYNOSAUTOV920_DRD_HSPCTL 0x104 259 + #define HSPCTRL_VBUSVLDEXTSEL BIT(13) 260 + #define HSPCTRL_VBUSVLDEXT BIT(12) 261 + #define HSPCTRL_EN_UTMISUSPEND BIT(9) 262 + #define HSPCTRL_COMMONONN BIT(8) 263 + 264 + #define EXYNOSAUTOV920_DRD_HSP_TEST 0x10c 265 + 266 + #define EXYNOSAUTOV920_DRD_HSPPLLTUNE 0x110 267 + #define HSPPLLTUNE_FSEL GENMASK(18, 16) 268 + 269 + /* ExynosAutov920 phy usb31drd port reg */ 270 + #define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL 0x000 271 + #define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN BIT(5) 272 + #define PHY_RST_CTRL_PIPE_LANE0_RESET_N BIT(4) 273 + #define PHY_RST_CTRL_PHY_RESET_OVRD_EN BIT(1) 274 + #define PHY_RST_CTRL_PHY_RESET BIT(0) 275 + 276 + #define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0 0x0004 277 + #define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR GENMASK(31, 16) 278 + #define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK BIT(8) 279 + #define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK BIT(4) 280 + #define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL BIT(0) 281 + 282 + #define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1 0x0008 283 + 284 + #define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2 0x000c 285 + #define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN BIT(0) 286 + #define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA GENMASK(31, 16) 287 + 288 + #define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0 0x100 289 + #define PHY_CONFIG0_PHY0_PMA_PWR_STABLE BIT(14) 290 + #define PHY_CONFIG0_PHY0_PCS_PWR_STABLE BIT(13) 291 + #define PHY_CONFIG0_PHY0_ANA_PWR_EN BIT(1) 292 + 293 + #define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7 0x11c 294 + #define PHY_CONFIG7_PHY_TEST_POWERDOWN BIT(24) 295 + 296 + #define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4 0x110 297 + #define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN BIT(2) 259 298 260 299 /* Exynos9 - GS101 */ 261 300 #define EXYNOS850_DRD_SECPMACTL 0x48 ··· 2107 2054 .n_regulators = ARRAY_SIZE(exynos5_regulator_names), 2108 2055 }; 2109 2056 2057 + static void 2058 + exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high) 2059 + { 2060 + void __iomem *reg_phy = phy_drd->reg_phy; 2061 + u32 reg; 2062 + 2063 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2064 + if (high) 2065 + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; 2066 + else 2067 + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; 2068 + 2069 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2070 + fsleep(1); 2071 + } 2072 + 2073 + static void 2074 + exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd) 2075 + { 2076 + struct device *dev = phy_drd->dev; 2077 + void __iomem *reg_phy = phy_drd->reg_phy; 2078 + static const unsigned int timeout_us = 20000; 2079 + static const unsigned int sleep_us = 40; 2080 + u32 reg; 2081 + int err; 2082 + 2083 + /* Clear cr_para_con */ 2084 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2085 + reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK | 2086 + PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR); 2087 + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; 2088 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2089 + writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1); 2090 + writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); 2091 + 2092 + exynosautov920_usb31drd_cr_clk(phy_drd, true); 2093 + exynosautov920_usb31drd_cr_clk(phy_drd, false); 2094 + 2095 + /* 2096 + * The maximum time from phy reset de-assertion to de-assertion of 2097 + * tx/rx_ack can be as high as 5ms in fast simulation mode. 2098 + * Time to phy ready is < 20ms 2099 + */ 2100 + err = readl_poll_timeout(reg_phy + 2101 + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0, 2102 + reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK), 2103 + sleep_us, timeout_us); 2104 + if (err) 2105 + dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg); 2106 + 2107 + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; 2108 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2109 + } 2110 + 2111 + static void 2112 + exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd, 2113 + u16 addr, u16 data) 2114 + { 2115 + void __iomem *reg_phy = phy_drd->reg_phy; 2116 + u32 cnt = 0; 2117 + u32 reg; 2118 + 2119 + /* Pre Clocking */ 2120 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2121 + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; 2122 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2123 + 2124 + /* 2125 + * tx clks must be available prior to assertion of tx req. 2126 + * tx pstate p2 to p0 transition directly is not permitted. 2127 + * tx clk ready must be asserted synchronously on tx clk prior 2128 + * to internal transmit clk alignment sequence in the phy 2129 + * when entering from p2 to p1 to p0. 2130 + */ 2131 + do { 2132 + exynosautov920_usb31drd_cr_clk(phy_drd, true); 2133 + exynosautov920_usb31drd_cr_clk(phy_drd, false); 2134 + cnt++; 2135 + } while (cnt < 15); 2136 + 2137 + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; 2138 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2139 + 2140 + /* 2141 + * tx data path is active when tx lane is in p0 state 2142 + * and tx data en asserted. enable cr_para_wr_en. 2143 + */ 2144 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); 2145 + reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA; 2146 + reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) | 2147 + PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN; 2148 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); 2149 + 2150 + /* write addr */ 2151 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2152 + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR; 2153 + reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) | 2154 + PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK | 2155 + PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; 2156 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2157 + 2158 + /* check cr_para_ack*/ 2159 + cnt = 0; 2160 + do { 2161 + /* 2162 + * data symbols are captured by phy on rising edge of the 2163 + * tx_clk when tx data enabled. 2164 + * completion of the write cycle is acknowledged by assertion 2165 + * of the cr_para_ack. 2166 + */ 2167 + exynosautov920_usb31drd_cr_clk(phy_drd, true); 2168 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); 2169 + if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK)) 2170 + break; 2171 + 2172 + exynosautov920_usb31drd_cr_clk(phy_drd, false); 2173 + 2174 + /* 2175 + * wait for minimum of 10 cr_para_clk cycles after phy reset 2176 + * is negated, before accessing control regs to allow for 2177 + * internal resets. 2178 + */ 2179 + cnt++; 2180 + } while (cnt < 10); 2181 + 2182 + if (cnt < 10) 2183 + exynosautov920_usb31drd_cr_clk(phy_drd, false); 2184 + } 2185 + 2186 + static void 2187 + exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val) 2188 + { 2189 + void __iomem *reg_phy = phy_drd->reg_phy; 2190 + u32 reg; 2191 + 2192 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2193 + reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN; 2194 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2195 + 2196 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2197 + if (val) 2198 + reg |= PHY_RST_CTRL_PHY_RESET; 2199 + else 2200 + reg &= ~PHY_RST_CTRL_PHY_RESET; 2201 + 2202 + reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN; 2203 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2204 + } 2205 + 2206 + static void 2207 + exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val) 2208 + { 2209 + void __iomem *reg_phy = phy_drd->reg_phy; 2210 + u32 reg; 2211 + 2212 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2213 + reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN; 2214 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2215 + 2216 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2217 + if (val) 2218 + reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N; 2219 + else 2220 + reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N; 2221 + 2222 + reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN; 2223 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); 2224 + } 2225 + 2226 + static void 2227 + exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) 2228 + { 2229 + void __iomem *reg_phy = phy_drd->reg_phy; 2230 + u32 reg; 2231 + 2232 + /* 2233 + * Phy and Pipe Lane reset assert. 2234 + * assert reset (phy_reset = 1). 2235 + * The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1) 2236 + */ 2237 + exynosautov920_usb31drd_phy_reset(phy_drd, 1); 2238 + exynosautov920_usb31drd_lane0_reset(phy_drd, 1); 2239 + 2240 + /* 2241 + * ANA Power En, PCS & PMA PWR Stable Set 2242 + * ramp-up power suppiles 2243 + */ 2244 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0); 2245 + reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE | 2246 + PHY_CONFIG0_PHY0_PMA_PWR_STABLE; 2247 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0); 2248 + 2249 + fsleep(10); 2250 + 2251 + /* 2252 + * phy is not functional in test_powerdown mode, test_powerdown to be 2253 + * de-asserted for normal operation 2254 + */ 2255 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); 2256 + reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN; 2257 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); 2258 + 2259 + /* 2260 + * phy reset signal be asserted for minimum 10us after power 2261 + * supplies are ramped-up 2262 + */ 2263 + fsleep(10); 2264 + 2265 + /* 2266 + * Phy and Pipe Lane reset assert de-assert 2267 + */ 2268 + exynosautov920_usb31drd_phy_reset(phy_drd, 0); 2269 + exynosautov920_usb31drd_lane0_reset(phy_drd, 0); 2270 + 2271 + /* Pipe_rx0_sris_mode_en = 1 */ 2272 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4); 2273 + reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN; 2274 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4); 2275 + 2276 + /* 2277 + * wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0) 2278 + * Exit from the reset state is indicated by de-assertion of *_ack 2279 + */ 2280 + exynosautov920_usb31drd_port_phy_ready(phy_drd); 2281 + 2282 + /* override values for level settings */ 2283 + exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5); 2284 + } 2285 + 2286 + static void 2287 + exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd) 2288 + { 2289 + void __iomem *reg_phy = phy_drd->reg_phy; 2290 + u32 reg; 2291 + 2292 + /* 1. Assert reset (phy_reset = 1) */ 2293 + exynosautov920_usb31drd_lane0_reset(phy_drd, 1); 2294 + exynosautov920_usb31drd_phy_reset(phy_drd, 1); 2295 + 2296 + /* phy test power down */ 2297 + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); 2298 + reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN; 2299 + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); 2300 + } 2301 + 2302 + static void 2303 + exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) 2304 + { 2305 + void __iomem *reg_phy = phy_drd->reg_phy; 2306 + u32 reg; 2307 + 2308 + /* 2309 + * Disable HWACG (hardware auto clock gating control). This 2310 + * forces QACTIVE signal in Q-Channel interface to HIGH level, 2311 + * to make sure the PHY clock is not gated by the hardware. 2312 + */ 2313 + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); 2314 + reg |= LINKCTRL_FORCE_QACT; 2315 + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); 2316 + 2317 + /* De-assert link reset */ 2318 + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); 2319 + reg &= ~CLKRST_LINK_SW_RST; 2320 + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); 2321 + 2322 + /* Set PHY POR High */ 2323 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); 2324 + reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL; 2325 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); 2326 + 2327 + /* Enable UTMI+ */ 2328 + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); 2329 + reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP | 2330 + UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN); 2331 + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); 2332 + 2333 + /* set phy clock & control HS phy */ 2334 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); 2335 + reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN; 2336 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); 2337 + 2338 + fsleep(100); 2339 + 2340 + /* Set VBUS Valid and DP-Pull up control by VBUS pad usage */ 2341 + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); 2342 + reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf); 2343 + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); 2344 + 2345 + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); 2346 + reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID; 2347 + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); 2348 + 2349 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); 2350 + reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT; 2351 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); 2352 + 2353 + /* Setting FSEL for refference clock */ 2354 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE); 2355 + reg &= ~HSPPLLTUNE_FSEL; 2356 + 2357 + switch (phy_drd->extrefclk) { 2358 + case EXYNOS5_FSEL_50MHZ: 2359 + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7); 2360 + break; 2361 + case EXYNOS5_FSEL_26MHZ: 2362 + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6); 2363 + break; 2364 + case EXYNOS5_FSEL_24MHZ: 2365 + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2); 2366 + break; 2367 + case EXYNOS5_FSEL_20MHZ: 2368 + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1); 2369 + break; 2370 + case EXYNOS5_FSEL_19MHZ2: 2371 + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0); 2372 + break; 2373 + default: 2374 + dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n", 2375 + phy_drd->extrefclk); 2376 + break; 2377 + } 2378 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE); 2379 + 2380 + /* Enable PHY Power Mode */ 2381 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); 2382 + reg &= ~HSP_TEST_SIDDQ; 2383 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); 2384 + 2385 + /* before POR low, 10us delay is needed to Finish PHY reset */ 2386 + fsleep(10); 2387 + 2388 + /* Set PHY POR Low */ 2389 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); 2390 + reg |= HSPCLKRST_PHY20_SW_POR_SEL; 2391 + reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET); 2392 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); 2393 + 2394 + /* after POR low and delay 75us, PHYCLOCK is guaranteed. */ 2395 + fsleep(75); 2396 + 2397 + /* Disable forcing pipe interface */ 2398 + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); 2399 + reg &= ~LINKCTRL_FORCE_PIPE_EN; 2400 + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); 2401 + 2402 + /* Pclk to pipe_clk */ 2403 + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); 2404 + reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL; 2405 + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); 2406 + } 2407 + 2408 + static void 2409 + exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd) 2410 + { 2411 + u32 reg; 2412 + void __iomem *reg_phy = phy_drd->reg_phy; 2413 + 2414 + /* set phy clock & control HS phy */ 2415 + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); 2416 + reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP; 2417 + reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN); 2418 + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); 2419 + 2420 + /* Disable PHY Power Mode */ 2421 + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); 2422 + reg |= HSP_TEST_SIDDQ; 2423 + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); 2424 + 2425 + /* clear force q-channel */ 2426 + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); 2427 + reg &= ~LINKCTRL_FORCE_QACT; 2428 + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); 2429 + 2430 + /* link sw reset is need for USB_DP/DM high-z in host mode */ 2431 + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); 2432 + reg |= CLKRST_LINK_SW_RST; 2433 + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); 2434 + fsleep(10); 2435 + reg &= ~CLKRST_LINK_SW_RST; 2436 + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); 2437 + } 2438 + 2439 + static int exynosautov920_usbdrd_phy_init(struct phy *phy) 2440 + { 2441 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 2442 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 2443 + int ret; 2444 + 2445 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 2446 + if (ret) 2447 + return ret; 2448 + 2449 + /* Bypass PHY isol */ 2450 + inst->phy_cfg->phy_isol(inst, false); 2451 + 2452 + /* UTMI or PIPE3 specific init */ 2453 + inst->phy_cfg->phy_init(phy_drd); 2454 + 2455 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 2456 + 2457 + return 0; 2458 + } 2459 + 2460 + static int exynosautov920_usbdrd_phy_exit(struct phy *phy) 2461 + { 2462 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 2463 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 2464 + int ret; 2465 + 2466 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 2467 + if (ret) 2468 + return ret; 2469 + 2470 + exynos850_usbdrd_phy_exit(phy); 2471 + 2472 + /* enable PHY isol */ 2473 + inst->phy_cfg->phy_isol(inst, true); 2474 + 2475 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 2476 + 2477 + return 0; 2478 + } 2479 + 2480 + static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy) 2481 + { 2482 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 2483 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 2484 + int ret = 0; 2485 + 2486 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 2487 + if (ret) 2488 + return ret; 2489 + 2490 + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) 2491 + exynosautov920_usbdrd_hsphy_disable(phy_drd); 2492 + else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3) 2493 + exynosautov920_usb31drd_ssphy_disable(phy_drd); 2494 + 2495 + /* enable PHY isol */ 2496 + inst->phy_cfg->phy_isol(inst, true); 2497 + 2498 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 2499 + 2500 + return 0; 2501 + } 2502 + 2503 + static int exynosautov920_usbdrd_phy_power_on(struct phy *phy) 2504 + { 2505 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 2506 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 2507 + int ret; 2508 + 2509 + dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); 2510 + 2511 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks, 2512 + phy_drd->core_clks); 2513 + if (ret) 2514 + return ret; 2515 + 2516 + /* Enable supply */ 2517 + ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators, 2518 + phy_drd->regulators); 2519 + if (ret) { 2520 + dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n"); 2521 + goto fail_supply; 2522 + } 2523 + 2524 + return 0; 2525 + 2526 + fail_supply: 2527 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, 2528 + phy_drd->core_clks); 2529 + 2530 + return ret; 2531 + } 2532 + 2533 + static int exynosautov920_usbdrd_phy_power_off(struct phy *phy) 2534 + { 2535 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 2536 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 2537 + 2538 + dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n"); 2539 + 2540 + /* Disable supply */ 2541 + regulator_bulk_disable(phy_drd->drv_data->n_regulators, 2542 + phy_drd->regulators); 2543 + 2544 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, 2545 + phy_drd->core_clks); 2546 + 2547 + return 0; 2548 + } 2549 + 2550 + static const char * const exynosautov920_usb30_regulators[] = { 2551 + "dvdd", "vdd18", 2552 + }; 2553 + 2554 + static const char * const exynosautov920_usb20_regulators[] = { 2555 + "dvdd", "vdd18", "vdd33", 2556 + }; 2557 + 2558 + static const struct 2559 + exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = { 2560 + { 2561 + .id = EXYNOS5_DRDPHY_PIPE3, 2562 + .phy_isol = exynos5_usbdrd_phy_isol, 2563 + .phy_init = exynosautov920_usb31drd_pipe3_init, 2564 + }, 2565 + }; 2566 + 2567 + static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = { 2568 + .init = exynosautov920_usbdrd_phy_init, 2569 + .exit = exynosautov920_usbdrd_combo_phy_exit, 2570 + .power_on = exynosautov920_usbdrd_phy_power_on, 2571 + .power_off = exynosautov920_usbdrd_phy_power_off, 2572 + .owner = THIS_MODULE, 2573 + }; 2574 + 2575 + static const 2576 + struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = { 2577 + .phy_cfg = usb31drd_phy_cfg_exynosautov920, 2578 + .phy_ops = &exynosautov920_usb31drd_combo_ssphy_ops, 2579 + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB31, 2580 + .clk_names = exynos5_clk_names, 2581 + .n_clks = ARRAY_SIZE(exynos5_clk_names), 2582 + .core_clk_names = exynos5_core_clk_names, 2583 + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), 2584 + .regulator_names = exynosautov920_usb30_regulators, 2585 + .n_regulators = ARRAY_SIZE(exynosautov920_usb30_regulators), 2586 + }; 2587 + 2588 + static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = { 2589 + .init = exynosautov920_usbdrd_phy_init, 2590 + .exit = exynosautov920_usbdrd_combo_phy_exit, 2591 + .power_on = exynosautov920_usbdrd_phy_power_on, 2592 + .power_off = exynosautov920_usbdrd_phy_power_off, 2593 + .owner = THIS_MODULE, 2594 + }; 2595 + 2596 + static const struct 2597 + exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = { 2598 + { 2599 + .id = EXYNOS5_DRDPHY_UTMI, 2600 + .phy_isol = exynos5_usbdrd_phy_isol, 2601 + .phy_init = exynosautov920_usbdrd_utmi_init, 2602 + }, 2603 + }; 2604 + 2605 + static const 2606 + struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = { 2607 + .phy_cfg = usbdrd_hsphy_cfg_exynosautov920, 2608 + .phy_ops = &exynosautov920_usbdrd_combo_hsphy_ops, 2609 + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20, 2610 + .clk_names = exynos5_clk_names, 2611 + .n_clks = ARRAY_SIZE(exynos5_clk_names), 2612 + .core_clk_names = exynos5_core_clk_names, 2613 + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), 2614 + .regulator_names = exynosautov920_usb20_regulators, 2615 + .n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators), 2616 + }; 2617 + 2618 + static const struct phy_ops exynosautov920_usbdrd_phy_ops = { 2619 + .init = exynosautov920_usbdrd_phy_init, 2620 + .exit = exynosautov920_usbdrd_phy_exit, 2621 + .power_on = exynosautov920_usbdrd_phy_power_on, 2622 + .power_off = exynosautov920_usbdrd_phy_power_off, 2623 + .owner = THIS_MODULE, 2624 + }; 2625 + 2626 + static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = { 2627 + { 2628 + .id = EXYNOS5_DRDPHY_UTMI, 2629 + .phy_isol = exynos5_usbdrd_phy_isol, 2630 + .phy_init = exynos850_usbdrd_utmi_init, 2631 + }, 2632 + }; 2633 + 2634 + static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = { 2635 + .phy_cfg = phy_cfg_exynosautov920, 2636 + .phy_ops = &exynosautov920_usbdrd_phy_ops, 2637 + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20, 2638 + .clk_names = exynos5_clk_names, 2639 + .n_clks = ARRAY_SIZE(exynos5_clk_names), 2640 + .core_clk_names = exynos5_core_clk_names, 2641 + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), 2642 + .regulator_names = exynosautov920_usb20_regulators, 2643 + .n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators), 2644 + }; 2645 + 2110 2646 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = { 2111 2647 { 2112 2648 .id = EXYNOS5_DRDPHY_UTMI, ··· 2902 2260 }, { 2903 2261 .compatible = "samsung,exynos990-usbdrd-phy", 2904 2262 .data = &exynos990_usbdrd_phy 2263 + }, { 2264 + .compatible = "samsung,exynosautov920-usb31drd-combo-ssphy", 2265 + .data = &exynosautov920_usb31drd_combo_ssphy 2266 + }, { 2267 + .compatible = "samsung,exynosautov920-usbdrd-combo-hsphy", 2268 + .data = &exynosautov920_usbdrd_combo_hsphy 2269 + }, { 2270 + .compatible = "samsung,exynosautov920-usbdrd-phy", 2271 + .data = &exynosautov920_usbdrd_phy 2905 2272 }, 2906 2273 { }, 2907 2274 };
+10 -18
drivers/phy/socionext/phy-uniphier-usb2.c
··· 106 106 static int uniphier_u2phy_probe(struct platform_device *pdev) 107 107 { 108 108 struct device *dev = &pdev->dev; 109 - struct device_node *parent, *child; 109 + struct device_node *parent; 110 110 struct uniphier_u2phy_priv *priv = NULL, *next = NULL; 111 111 struct phy_provider *phy_provider; 112 112 struct regmap *regmap; ··· 129 129 return PTR_ERR(regmap); 130 130 } 131 131 132 - for_each_child_of_node(dev->of_node, child) { 132 + for_each_child_of_node_scoped(dev->of_node, child) { 133 133 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 134 - if (!priv) { 135 - ret = -ENOMEM; 136 - goto out_put_child; 137 - } 134 + if (!priv) 135 + return -ENOMEM; 136 + 138 137 priv->regmap = regmap; 139 138 140 139 priv->vbus = devm_regulator_get_optional(dev, "vbus"); 141 140 if (IS_ERR(priv->vbus)) { 142 - if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) { 143 - ret = PTR_ERR(priv->vbus); 144 - goto out_put_child; 145 - } 141 + if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) 142 + return PTR_ERR(priv->vbus); 143 + 146 144 priv->vbus = NULL; 147 145 } 148 146 149 147 priv->phy = devm_phy_create(dev, child, &uniphier_u2phy_ops); 150 148 if (IS_ERR(priv->phy)) { 151 149 dev_err(dev, "Failed to create phy\n"); 152 - ret = PTR_ERR(priv->phy); 153 - goto out_put_child; 150 + return PTR_ERR(priv->phy); 154 151 } 155 152 156 153 ret = of_property_read_u32(child, "reg", &data_idx); 157 154 if (ret) { 158 155 dev_err(dev, "Failed to get reg property\n"); 159 - goto out_put_child; 156 + return ret; 160 157 } 161 158 162 159 if (data_idx < ndatas) ··· 171 174 phy_provider = devm_of_phy_provider_register(dev, 172 175 uniphier_u2phy_xlate); 173 176 return PTR_ERR_OR_ZERO(phy_provider); 174 - 175 - out_put_child: 176 - of_node_put(child); 177 - 178 - return ret; 179 177 } 180 178 181 179 static const struct uniphier_u2phy_soc_data uniphier_pro4_data[] = {
+13
drivers/phy/spacemit/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # Phy drivers for SpacemiT platforms 4 + # 5 + config PHY_SPACEMIT_K1_USB2 6 + tristate "SpacemiT K1 USB 2.0 PHY support" 7 + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF 8 + depends on COMMON_CLK 9 + depends on USB_COMMON 10 + select GENERIC_PHY 11 + help 12 + Enable this to support K1 USB 2.0 PHY driver. This driver takes care of 13 + enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
+2
drivers/phy/spacemit/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
+200
drivers/phy/spacemit/phy-k1-usb2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * SpacemiT K1 USB 2.0 PHY driver 4 + * 5 + * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd 6 + * Copyright (C) 2025 Ze Huang <huang.ze@linux.dev> 7 + */ 8 + 9 + #include <linux/bitfield.h> 10 + #include <linux/clk.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/regmap.h> 14 + #include <linux/usb/of.h> 15 + 16 + #define PHY_RST_MODE_CTRL 0x04 17 + #define PHY_PLL_RDY BIT(0) 18 + #define PHY_CLK_CDR_EN BIT(1) 19 + #define PHY_CLK_PLL_EN BIT(2) 20 + #define PHY_CLK_MAC_EN BIT(3) 21 + #define PHY_MAC_RSTN BIT(5) 22 + #define PHY_CDR_RSTN BIT(6) 23 + #define PHY_PLL_RSTN BIT(7) 24 + /* 25 + * hs line state sel (Bit 13): 26 + * - 1 (Default): Internal HS line state is set to 01 when usb_hs_tx_en is valid. 27 + * - 0: Internal HS line state is always driven by usb_hs_lstate. 28 + * 29 + * fs line state sel (Bit 14): 30 + * - 1 (Default): FS line state is determined by the output data 31 + * (usb_fs_datain/b). 32 + * - 0: FS line state is always determined by the input data (dmo/dpo). 33 + */ 34 + #define PHY_HS_LINE_TX_MODE BIT(13) 35 + #define PHY_FS_LINE_TX_MODE BIT(14) 36 + 37 + #define PHY_INIT_MODE_BITS (PHY_FS_LINE_TX_MODE | PHY_HS_LINE_TX_MODE) 38 + #define PHY_CLK_ENABLE_BITS (PHY_CLK_PLL_EN | PHY_CLK_CDR_EN | \ 39 + PHY_CLK_MAC_EN) 40 + #define PHY_DEASSERT_RST_BITS (PHY_PLL_RSTN | PHY_CDR_RSTN | \ 41 + PHY_MAC_RSTN) 42 + 43 + #define PHY_TX_HOST_CTRL 0x10 44 + #define PHY_HST_DISC_AUTO_CLR BIT(2) /* autoclear hs host disc when re-connect */ 45 + 46 + #define PHY_HSTXP_HW_CTRL 0x34 47 + #define PHY_HSTXP_RSTN BIT(2) /* generate reset for clock hstxp */ 48 + #define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */ 49 + #define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */ 50 + 51 + #define PHY_PLL_DIV_CFG 0x98 52 + #define PHY_FDIV_FRACT_8_15 GENMASK(7, 0) 53 + #define PHY_FDIV_FRACT_16_19 GENMASK(11, 8) 54 + #define PHY_FDIV_FRACT_20_21 BIT(12) /* fdiv_reg<21>, <20>, bit21 == bit20 */ 55 + /* 56 + * freq_sel<1:0> 57 + * if ref clk freq=24.0MHz-->freq_sel<2:0> == 3b'001, then internal divider value == 80 58 + */ 59 + #define PHY_FDIV_FRACT_0_1 GENMASK(14, 13) 60 + /* 61 + * pll divider value selection 62 + * 1: divider value will choose internal default value ,dependent on freq_sel<1:0> 63 + * 0: divider value will be over ride by fdiv_reg<21:0> 64 + */ 65 + #define PHY_DIV_LOCAL_EN BIT(15) 66 + 67 + #define PHY_SEL_FREQ_24MHZ 0x01 68 + #define FDIV_REG_MASK (PHY_FDIV_FRACT_20_21 | PHY_FDIV_FRACT_16_19 | \ 69 + PHY_FDIV_FRACT_8_15) 70 + #define FDIV_REG_VAL 0x1ec4 /* 0x100 selects 24MHz, rest are default */ 71 + 72 + #define K1_USB2PHY_RESET_TIME_MS 50 73 + 74 + struct spacemit_usb2phy { 75 + struct phy *phy; 76 + struct clk *clk; 77 + struct regmap *regmap_base; 78 + }; 79 + 80 + static const struct regmap_config phy_regmap_config = { 81 + .reg_bits = 32, 82 + .val_bits = 32, 83 + .reg_stride = 4, 84 + .max_register = 0x200, 85 + }; 86 + 87 + static int spacemit_usb2phy_init(struct phy *phy) 88 + { 89 + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); 90 + struct regmap *map = sphy->regmap_base; 91 + u32 val; 92 + int ret; 93 + 94 + ret = clk_enable(sphy->clk); 95 + if (ret) { 96 + dev_err(&phy->dev, "failed to enable clock\n"); 97 + clk_disable(sphy->clk); 98 + return ret; 99 + } 100 + 101 + /* 102 + * make sure the usb controller is not under reset process before 103 + * any configuration 104 + */ 105 + usleep_range(150, 200); 106 + 107 + /* 24M ref clk */ 108 + val = FIELD_PREP(FDIV_REG_MASK, FDIV_REG_VAL) | 109 + FIELD_PREP(PHY_FDIV_FRACT_0_1, PHY_SEL_FREQ_24MHZ) | 110 + PHY_DIV_LOCAL_EN; 111 + regmap_write(map, PHY_PLL_DIV_CFG, val); 112 + 113 + ret = regmap_read_poll_timeout(map, PHY_RST_MODE_CTRL, val, 114 + (val & PHY_PLL_RDY), 115 + 500, K1_USB2PHY_RESET_TIME_MS * 1000); 116 + if (ret) { 117 + dev_err(&phy->dev, "wait PLLREADY timeout\n"); 118 + clk_disable(sphy->clk); 119 + return ret; 120 + } 121 + 122 + /* release usb2 phy internal reset and enable clock gating */ 123 + val = (PHY_INIT_MODE_BITS | PHY_CLK_ENABLE_BITS | PHY_DEASSERT_RST_BITS); 124 + regmap_write(map, PHY_RST_MODE_CTRL, val); 125 + 126 + val = (PHY_HSTXP_RSTN | PHY_CLK_HSTXP_EN | PHY_HSTXP_MODE); 127 + regmap_write(map, PHY_HSTXP_HW_CTRL, val); 128 + 129 + /* auto clear host disc */ 130 + regmap_update_bits(map, PHY_TX_HOST_CTRL, PHY_HST_DISC_AUTO_CLR, 131 + PHY_HST_DISC_AUTO_CLR); 132 + 133 + return 0; 134 + } 135 + 136 + static int spacemit_usb2phy_exit(struct phy *phy) 137 + { 138 + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); 139 + 140 + clk_disable(sphy->clk); 141 + 142 + return 0; 143 + } 144 + 145 + static const struct phy_ops spacemit_usb2phy_ops = { 146 + .init = spacemit_usb2phy_init, 147 + .exit = spacemit_usb2phy_exit, 148 + .owner = THIS_MODULE, 149 + }; 150 + 151 + static int spacemit_usb2phy_probe(struct platform_device *pdev) 152 + { 153 + struct phy_provider *phy_provider; 154 + struct device *dev = &pdev->dev; 155 + struct spacemit_usb2phy *sphy; 156 + void __iomem *base; 157 + 158 + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); 159 + if (!sphy) 160 + return -ENOMEM; 161 + 162 + sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL); 163 + if (IS_ERR(sphy->clk)) 164 + return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n"); 165 + 166 + base = devm_platform_ioremap_resource(pdev, 0); 167 + if (IS_ERR(base)) 168 + return PTR_ERR(base); 169 + 170 + sphy->regmap_base = devm_regmap_init_mmio(dev, base, &phy_regmap_config); 171 + if (IS_ERR(sphy->regmap_base)) 172 + return dev_err_probe(dev, PTR_ERR(sphy->regmap_base), "Failed to init regmap\n"); 173 + 174 + sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops); 175 + if (IS_ERR(sphy->phy)) 176 + return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n"); 177 + 178 + phy_set_drvdata(sphy->phy, sphy); 179 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 180 + 181 + return PTR_ERR_OR_ZERO(phy_provider); 182 + } 183 + 184 + static const struct of_device_id spacemit_usb2phy_dt_match[] = { 185 + { .compatible = "spacemit,k1-usb2-phy", }, 186 + { /* sentinel */ } 187 + }; 188 + MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match); 189 + 190 + static struct platform_driver spacemit_usb2_phy_driver = { 191 + .probe = spacemit_usb2phy_probe, 192 + .driver = { 193 + .name = "spacemit-usb2-phy", 194 + .of_match_table = spacemit_usb2phy_dt_match, 195 + }, 196 + }; 197 + module_platform_driver(spacemit_usb2_phy_driver); 198 + 199 + MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver"); 200 + MODULE_LICENSE("GPL");
-1
drivers/phy/tegra/xusb.h
··· 69 69 struct tegra_xusb_lane base; 70 70 71 71 u32 hs_curr_level_offset; 72 - bool powered_on; 73 72 }; 74 73 75 74 static inline struct tegra_xusb_usb2_lane *
+21 -6
drivers/phy/ti/phy-j721e-wiz.c
··· 393 393 struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS]; 394 394 struct clk_onecell_data clk_data; 395 395 const struct wiz_data *data; 396 + int mux_sel_status[WIZ_MUX_NUM_CLOCKS]; 396 397 }; 397 398 398 399 static int wiz_reset(struct wiz *wiz) ··· 935 934 return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2); 936 935 } 937 936 938 - static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, 939 - unsigned long *prate) 937 + static int wiz_clk_div_determine_rate(struct clk_hw *hw, 938 + struct clk_rate_request *req) 940 939 { 941 940 struct wiz_clk_divider *div = to_wiz_clk_div(hw); 942 941 943 - return divider_round_rate(hw, rate, prate, div->table, 2, 0x0); 942 + return divider_determine_rate(hw, req, div->table, 2, 0x0); 944 943 } 945 944 946 945 static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, ··· 959 958 960 959 static const struct clk_ops wiz_clk_div_ops = { 961 960 .recalc_rate = wiz_clk_div_recalc_rate, 962 - .round_rate = wiz_clk_div_round_rate, 961 + .determine_rate = wiz_clk_div_determine_rate, 963 962 .set_rate = wiz_clk_div_set_rate, 964 963 }; 965 964 ··· 1655 1654 pm_runtime_disable(dev); 1656 1655 } 1657 1656 1657 + static int wiz_suspend_noirq(struct device *dev) 1658 + { 1659 + struct wiz *wiz = dev_get_drvdata(dev); 1660 + int i; 1661 + 1662 + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) 1663 + regmap_field_read(wiz->mux_sel_field[i], &wiz->mux_sel_status[i]); 1664 + 1665 + return 0; 1666 + } 1667 + 1658 1668 static int wiz_resume_noirq(struct device *dev) 1659 1669 { 1660 1670 struct device_node *node = dev->of_node; 1661 1671 struct wiz *wiz = dev_get_drvdata(dev); 1662 - int ret; 1672 + int ret, i; 1673 + 1674 + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) 1675 + regmap_field_write(wiz->mux_sel_field[i], wiz->mux_sel_status[i]); 1663 1676 1664 1677 /* Enable supplemental Control override if available */ 1665 1678 if (wiz->sup_legacy_clk_override) ··· 1695 1680 return ret; 1696 1681 } 1697 1682 1698 - static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq); 1683 + static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, wiz_suspend_noirq, wiz_resume_noirq); 1699 1684 1700 1685 static struct platform_driver wiz_driver = { 1701 1686 .probe = wiz_probe,
+4
drivers/soc/apple/Kconfig
··· 38 38 39 39 Say 'y' here if you have an Apple SoC. 40 40 41 + config APPLE_TUNABLE 42 + tristate 43 + depends on ARCH_APPLE || COMPILE_TEST 44 + 41 45 endmenu 42 46 43 47 endif
+3
drivers/soc/apple/Makefile
··· 8 8 9 9 obj-$(CONFIG_APPLE_SART) += apple-sart.o 10 10 apple-sart-y = sart.o 11 + 12 + obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o 13 + apple-tunable-y = tunable.o
+80
drivers/soc/apple/tunable.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* 3 + * Apple Silicon hardware tunable support 4 + * 5 + * Each tunable is a list with each entry containing a offset into the MMIO 6 + * region, a mask of bits to be cleared and a set of bits to be set. These 7 + * tunables are passed along by the previous boot stages and vary from device 8 + * to device such that they cannot be hardcoded in the individual drivers. 9 + * 10 + * Copyright (C) The Asahi Linux Contributors 11 + */ 12 + 13 + #include <linux/io.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 16 + #include <linux/overflow.h> 17 + #include <linux/soc/apple/tunable.h> 18 + 19 + struct apple_tunable *devm_apple_tunable_parse(struct device *dev, 20 + struct device_node *np, 21 + const char *name, 22 + struct resource *res) 23 + { 24 + struct apple_tunable *tunable; 25 + struct property *prop; 26 + const __be32 *p; 27 + size_t sz; 28 + int i; 29 + 30 + if (resource_size(res) < 4) 31 + return ERR_PTR(-EINVAL); 32 + 33 + prop = of_find_property(np, name, NULL); 34 + if (!prop) 35 + return ERR_PTR(-ENOENT); 36 + 37 + if (prop->length % (3 * sizeof(u32))) 38 + return ERR_PTR(-EINVAL); 39 + sz = prop->length / (3 * sizeof(u32)); 40 + 41 + tunable = devm_kzalloc(dev, struct_size(tunable, values, sz), GFP_KERNEL); 42 + if (!tunable) 43 + return ERR_PTR(-ENOMEM); 44 + tunable->sz = sz; 45 + 46 + for (i = 0, p = NULL; i < tunable->sz; ++i) { 47 + p = of_prop_next_u32(prop, p, &tunable->values[i].offset); 48 + p = of_prop_next_u32(prop, p, &tunable->values[i].mask); 49 + p = of_prop_next_u32(prop, p, &tunable->values[i].value); 50 + 51 + /* Sanity checks to catch bugs in our bootloader */ 52 + if (tunable->values[i].offset % 4) 53 + return ERR_PTR(-EINVAL); 54 + if (tunable->values[i].offset > (resource_size(res) - 4)) 55 + return ERR_PTR(-EINVAL); 56 + } 57 + 58 + return tunable; 59 + } 60 + EXPORT_SYMBOL(devm_apple_tunable_parse); 61 + 62 + void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable) 63 + { 64 + size_t i; 65 + 66 + for (i = 0; i < tunable->sz; ++i) { 67 + u32 val, old_val; 68 + 69 + old_val = readl(regs + tunable->values[i].offset); 70 + val = old_val & ~tunable->values[i].mask; 71 + val |= tunable->values[i].value; 72 + if (val != old_val) 73 + writel(val, regs + tunable->values[i].offset); 74 + } 75 + } 76 + EXPORT_SYMBOL(apple_tunable_apply); 77 + 78 + MODULE_LICENSE("Dual MIT/GPL"); 79 + MODULE_AUTHOR("Sven Peter <sven@kernel.org>"); 80 + MODULE_DESCRIPTION("Apple Silicon hardware tunable support");
+1
include/dt-bindings/phy/phy.h
··· 23 23 #define PHY_TYPE_DPHY 10 24 24 #define PHY_TYPE_CPHY 11 25 25 #define PHY_TYPE_USXGMII 12 26 + #define PHY_TYPE_XAUI 13 26 27 27 28 #define PHY_POL_NORMAL 0 28 29 #define PHY_POL_INVERT 1
+17 -2
include/linux/phy/phy-hdmi.h
··· 6 6 #ifndef __PHY_HDMI_H_ 7 7 #define __PHY_HDMI_H_ 8 8 9 + #include <linux/types.h> 10 + 11 + enum phy_hdmi_mode { 12 + PHY_HDMI_MODE_TMDS, 13 + PHY_HDMI_MODE_FRL, 14 + }; 15 + 9 16 /** 10 17 * struct phy_configure_opts_hdmi - HDMI configuration set 11 - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. 12 18 * @bpc: Bits per color channel. 19 + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. 20 + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps. 21 + * @frl.lanes: HDMI FRL lanes count. 13 22 * 14 23 * This structure is used to represent the configuration state of a HDMI phy. 15 24 */ 16 25 struct phy_configure_opts_hdmi { 17 - unsigned long long tmds_char_rate; 18 26 unsigned int bpc; 27 + union { 28 + unsigned long long tmds_char_rate; 29 + struct { 30 + u8 rate_per_lane; 31 + u8 lanes; 32 + } frl; 33 + }; 19 34 }; 20 35 21 36 #endif /* __PHY_HDMI_H_ */
+2 -5
include/linux/phy/phy.h
··· 243 243 #if IS_ENABLED(CONFIG_GENERIC_PHY) 244 244 int phy_pm_runtime_get(struct phy *phy); 245 245 int phy_pm_runtime_get_sync(struct phy *phy); 246 - int phy_pm_runtime_put(struct phy *phy); 246 + void phy_pm_runtime_put(struct phy *phy); 247 247 int phy_pm_runtime_put_sync(struct phy *phy); 248 248 int phy_init(struct phy *phy); 249 249 int phy_exit(struct phy *phy); ··· 324 324 return -ENOSYS; 325 325 } 326 326 327 - static inline int phy_pm_runtime_put(struct phy *phy) 327 + static inline void phy_pm_runtime_put(struct phy *phy) 328 328 { 329 - if (!phy) 330 - return 0; 331 - return -ENOSYS; 332 329 } 333 330 334 331 static inline int phy_pm_runtime_put_sync(struct phy *phy)
+62
include/linux/soc/apple/tunable.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 + /* 3 + * Apple Silicon hardware tunable support 4 + * 5 + * Each tunable is a list with each entry containing a offset into the MMIO 6 + * region, a mask of bits to be cleared and a set of bits to be set. These 7 + * tunables are passed along by the previous boot stages and vary from device 8 + * to device such that they cannot be hardcoded in the individual drivers. 9 + * 10 + * Copyright (C) The Asahi Linux Contributors 11 + */ 12 + 13 + #ifndef _LINUX_SOC_APPLE_TUNABLE_H_ 14 + #define _LINUX_SOC_APPLE_TUNABLE_H_ 15 + 16 + #include <linux/device.h> 17 + #include <linux/types.h> 18 + 19 + /** 20 + * Struct to store an Apple Silicon hardware tunable. 21 + * 22 + * Each tunable is a list with each entry containing a offset into the MMIO 23 + * region, a mask of bits to be cleared and a set of bits to be set. These 24 + * tunables are passed along by the previous boot stages and vary from device 25 + * to device such that they cannot be hardcoded in the individual drivers. 26 + * 27 + * @param sz Number of [offset, mask, value] tuples stored in values. 28 + * @param values [offset, mask, value] array. 29 + */ 30 + struct apple_tunable { 31 + size_t sz; 32 + struct { 33 + u32 offset; 34 + u32 mask; 35 + u32 value; 36 + } values[] __counted_by(sz); 37 + }; 38 + 39 + /** 40 + * Parse an array of hardware tunables from the device tree. 41 + * 42 + * @dev: Device node used for devm_kzalloc internally. 43 + * @np: Device node which contains the tunable array. 44 + * @name: Name of the device tree property which contains the tunables. 45 + * @res: Resource to which the tunables will be applied, used for bound checking 46 + * 47 + * @return: devres allocated struct on success or PTR_ERR on failure. 48 + */ 49 + struct apple_tunable *devm_apple_tunable_parse(struct device *dev, 50 + struct device_node *np, 51 + const char *name, 52 + struct resource *res); 53 + 54 + /** 55 + * Apply a previously loaded hardware tunable. 56 + * 57 + * @param regs: MMIO to which the tunable will be applied. 58 + * @param tunable: Pointer to the tunable. 59 + */ 60 + void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable); 61 + 62 + #endif
+3
include/linux/soc/samsung/exynos-regs-pmu.h
··· 1015 1015 #define GS101_GRP2_INTR_BID_UPEND (0x0208) 1016 1016 #define GS101_GRP2_INTR_BID_CLEAR (0x020c) 1017 1017 1018 + /* exynosautov920 */ 1019 + #define EXYNOSAUTOV920_PHY_CTRL_USB20 (0x0710) 1020 + #define EXYNOSAUTOV920_PHY_CTRL_USB31 (0x0714) 1018 1021 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */