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

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

Pull phy updates from Vinod Koul:
"As usual featuring couple of new driver and bunch of new device
support and some driver changes to Freescale, rockchip driver along
with couple of yaml binding conversions.

New Support:
- Qualcomm IPQ5424 qusb2 support, IPQ5018 uniphy-pcie driver
- Rockchip usb2 support for RK3562, RK3036 usb2 phy support
- Samsung exynos2200 eusb2 phy support and driver refactoring for
this support, exynos7870 USBDRD support
- Mediatek MT7988 xs-phy support
- Broadcom BCM74110 usb phy support
- Renesas RZ/V2H(P) usb2 phy support

Updates:
- Freescale phy rate claculation updates, i.MX95 tuning support
- Better error handling for amlogic pcie phy
- Rockchip color depth configuration and management support
- Yaml binding conversion for RK3399 Type-C and PCIe Phy"

* tag 'phy-for-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (77 commits)
phy: tegra: p2u: Broaden architecture dependency
phy: rockchip: inno-usb2: Add usb2 phy support for rk3562
dt-bindings: phy: rockchip,inno-usb2phy: add rk3562
phy: rockchip: inno-usb2: add phy definition for rk3036
dt-bindings: phy: rockchip,inno-usb2phy: add rk3036 compatible
phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock
phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings
phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate
phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY support for RZ/V2H(P)
phy: renesas: phy-rcar-gen3-usb2: Sort compatible entries by SoC part number
dt-bindings: phy: renesas,usb2-phy: Document RZ/V2H(P) SoC
dt-bindings: phy: renesas,usb2-phy: Add clock constraint for RZ/G2L family
phy: exynos5-usbdrd: support Exynos USBDRD 3.2 4nm controller
phy: phy-snps-eusb2: add support for exynos2200
phy: phy-snps-eusb2: refactor reference clock init
phy: phy-snps-eusb2: make reset control optional
phy: phy-snps-eusb2: make repeater optional
phy: phy-snps-eusb2: split phy init code
phy: phy-snps-eusb2: refactor constructs names
phy: move phy-qcom-snps-eusb2 out of its vendor sub-directory
...

+2387 -1034
+4 -1
Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
··· 18 18 - brcm,bcm4908-usb-phy 19 19 - brcm,bcm7211-usb-phy 20 20 - brcm,bcm7216-usb-phy 21 + - brcm,bcm74110-usb-phy 21 22 - brcm,brcmstb-usb-phy 22 23 23 24 reg: ··· 140 139 properties: 141 140 compatible: 142 141 contains: 143 - const: brcm,bcm7216-usb-phy 142 + enum: 143 + - brcm,bcm7216-usb-phy 144 + - brcm,bcm74110-usb-phy 144 145 then: 145 146 properties: 146 147 reg:
+32 -5
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
··· 43 43 fsl,phy-tx-vref-tune-percent: 44 44 description: 45 45 Tunes the HS DC level relative to the nominal level 46 - minimum: 94 46 + minimum: 90 47 47 maximum: 124 48 48 49 49 fsl,phy-tx-rise-tune-percent: 50 50 description: 51 51 Adjusts the rise/fall time duration of the HS waveform relative to 52 52 its nominal value 53 - minimum: 97 54 - maximum: 103 53 + minimum: 90 54 + maximum: 120 55 55 56 56 fsl,phy-tx-preemp-amp-tune-microamp: 57 57 description: ··· 63 63 fsl,phy-tx-vboost-level-microvolt: 64 64 description: 65 65 Adjust the boosted transmit launch pk-pk differential amplitude 66 - minimum: 880 67 - maximum: 1120 66 + enum: [844, 1008, 1156] 68 67 69 68 fsl,phy-comp-dis-tune-percent: 70 69 description: ··· 110 111 properties: 111 112 reg: 112 113 maxItems: 1 114 + 115 + - if: 116 + properties: 117 + compatible: 118 + enum: 119 + - fsl,imx8mq-usb-phy 120 + - fsl,imx8mp-usb-phy 121 + then: 122 + properties: 123 + fsl,phy-tx-vref-tune-percent: 124 + minimum: 94 125 + fsl,phy-tx-rise-tune-percent: 126 + minimum: 97 127 + maximum: 103 128 + 129 + - if: 130 + properties: 131 + compatible: 132 + contains: 133 + enum: 134 + - fsl,imx95-usb-phy 135 + then: 136 + properties: 137 + fsl,phy-tx-vref-tune-percent: 138 + maximum: 108 139 + fsl,phy-comp-dis-tune-percent: 140 + minimum: 94 141 + maximum: 104 113 142 114 143 - if: 115 144 required:
+1
Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
··· 30 30 - const: mediatek,mt8173-mipi-tx 31 31 - items: 32 32 - enum: 33 + - mediatek,mt6893-mipi-tx 33 34 - mediatek,mt8188-mipi-tx 34 35 - mediatek,mt8195-mipi-tx 35 36 - mediatek,mt8365-mipi-tx
+1
Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
··· 78 78 - items: 79 79 - enum: 80 80 - mediatek,mt2712-tphy 81 + - mediatek,mt6893-tphy 81 82 - mediatek,mt7629-tphy 82 83 - mediatek,mt7986-tphy 83 84 - mediatek,mt8183-tphy
+16
Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml
··· 49 49 - enum: 50 50 - mediatek,mt3611-xsphy 51 51 - mediatek,mt3612-xsphy 52 + - mediatek,mt7988-xsphy 52 53 - const: mediatek,xsphy 53 54 54 55 reg: ··· 150 149 $ref: /schemas/types.yaml#/definitions/uint32 151 150 minimum: 1 152 151 maximum: 31 152 + 153 + mediatek,syscon-type: 154 + $ref: /schemas/types.yaml#/definitions/phandle-array 155 + description: 156 + A phandle to syscon used to access the register of type switch, 157 + the field should always be 3 cells long. 158 + items: 159 + - items: 160 + - description: 161 + Phandle to phy type configuration system controller 162 + - description: 163 + Phy type configuration register offset 164 + - description: 165 + Index of config segment 166 + enum: [0, 1, 2, 3] 153 167 154 168 required: 155 169 - reg
+1 -2
Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
··· 99 99 Specifies the type of PHY for which the group of PHY lanes is used. 100 100 Refer include/dt-bindings/phy/phy.h. Constants from the header should be used. 101 101 $ref: /schemas/types.yaml#/definitions/uint32 102 - minimum: 1 103 - maximum: 9 102 + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 12] 104 103 105 104 cdns,num-lanes: 106 105 description:
+3
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
··· 42 42 - const: phy 43 43 - const: apb 44 44 45 + phy-supply: 46 + description: Single PHY regulator 47 + 45 48 rockchip,enable-ssc: 46 49 type: boolean 47 50 description:
-84
Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
··· 1 - * ROCKCHIP type-c PHY 2 - --------------------- 3 - 4 - Required properties: 5 - - compatible : must be "rockchip,rk3399-typec-phy" 6 - - reg: Address and length of the usb phy control register set 7 - - rockchip,grf : phandle to the syscon managing the "general 8 - register files" 9 - - clocks : phandle + clock specifier for the phy clocks 10 - - clock-names : string, clock name, must be "tcpdcore", "tcpdphy-ref"; 11 - - assigned-clocks: main clock, should be <&cru SCLK_UPHY0_TCPDCORE> or 12 - <&cru SCLK_UPHY1_TCPDCORE>; 13 - - assigned-clock-rates : the phy core clk frequency, shall be: 50000000 14 - - resets : a list of phandle + reset specifier pairs 15 - - reset-names : string reset name, must be: 16 - "uphy", "uphy-pipe", "uphy-tcphy" 17 - 18 - Optional properties: 19 - - extcon : extcon specifier for the Power Delivery 20 - 21 - Required nodes : a sub-node is required for each port the phy provides. 22 - The sub-node name is used to identify dp or usb3 port, 23 - and shall be the following entries: 24 - * "dp-port" : the name of DP port. 25 - * "usb3-port" : the name of USB3 port. 26 - 27 - Required properties (port (child) node): 28 - - #phy-cells : must be 0, See ./phy-bindings.txt for details. 29 - 30 - Deprecated properties, do not use in new device tree sources, these 31 - properties are determined by the compatible value: 32 - - rockchip,typec-conn-dir 33 - - rockchip,usb3tousb2-en 34 - - rockchip,external-psm 35 - - rockchip,pipe-status 36 - 37 - Example: 38 - tcphy0: phy@ff7c0000 { 39 - compatible = "rockchip,rk3399-typec-phy"; 40 - reg = <0x0 0xff7c0000 0x0 0x40000>; 41 - rockchip,grf = <&grf>; 42 - extcon = <&fusb0>; 43 - clocks = <&cru SCLK_UPHY0_TCPDCORE>, 44 - <&cru SCLK_UPHY0_TCPDPHY_REF>; 45 - clock-names = "tcpdcore", "tcpdphy-ref"; 46 - assigned-clocks = <&cru SCLK_UPHY0_TCPDCORE>; 47 - assigned-clock-rates = <50000000>; 48 - resets = <&cru SRST_UPHY0>, 49 - <&cru SRST_UPHY0_PIPE_L00>, 50 - <&cru SRST_P_UPHY0_TCPHY>; 51 - reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; 52 - 53 - tcphy0_dp: dp-port { 54 - #phy-cells = <0>; 55 - }; 56 - 57 - tcphy0_usb3: usb3-port { 58 - #phy-cells = <0>; 59 - }; 60 - }; 61 - 62 - tcphy1: phy@ff800000 { 63 - compatible = "rockchip,rk3399-typec-phy"; 64 - reg = <0x0 0xff800000 0x0 0x40000>; 65 - rockchip,grf = <&grf>; 66 - extcon = <&fusb1>; 67 - clocks = <&cru SCLK_UPHY1_TCPDCORE>, 68 - <&cru SCLK_UPHY1_TCPDPHY_REF>; 69 - clock-names = "tcpdcore", "tcpdphy-ref"; 70 - assigned-clocks = <&cru SCLK_UPHY1_TCPDCORE>; 71 - assigned-clock-rates = <50000000>; 72 - resets = <&cru SRST_UPHY1>, 73 - <&cru SRST_UPHY1_PIPE_L00>, 74 - <&cru SRST_P_UPHY1_TCPHY>; 75 - reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; 76 - 77 - tcphy1_dp: dp-port { 78 - #phy-cells = <0>; 79 - }; 80 - 81 - tcphy1_usb3: usb3-port { 82 - #phy-cells = <0>; 83 - }; 84 - };
+3
Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
··· 47 47 - const: pcs_apb 48 48 - const: pma_apb 49 49 50 + phy-supply: 51 + description: Single PHY regulator 52 + 50 53 rockchip,dp-lane-mux: 51 54 $ref: /schemas/types.yaml#/definitions/uint32-array 52 55 minItems: 2
+41 -8
Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
··· 11 11 - Varadarajan Narayanan <quic_varada@quicinc.com> 12 12 13 13 description: 14 - PCIe and USB combo PHY found in Qualcomm IPQ5332 SoC 14 + PCIe and USB combo PHY found in Qualcomm IPQ5018 & IPQ5332 SoCs 15 15 16 16 properties: 17 17 compatible: 18 18 enum: 19 + - qcom,ipq5018-uniphy-pcie-phy 19 20 - qcom,ipq5332-uniphy-pcie-phy 20 21 21 22 reg: 22 23 maxItems: 1 23 24 24 25 clocks: 25 - items: 26 - - description: pcie pipe clock 27 - - description: pcie ahb clock 26 + minItems: 1 27 + maxItems: 2 28 28 29 29 resets: 30 - items: 31 - - description: phy reset 32 - - description: ahb reset 33 - - description: cfg reset 30 + minItems: 2 31 + maxItems: 3 34 32 35 33 "#phy-cells": 36 34 const: 0 ··· 50 52 - num-lanes 51 53 52 54 additionalProperties: false 55 + 56 + allOf: 57 + - if: 58 + properties: 59 + compatible: 60 + contains: 61 + enum: 62 + - qcom,ipq5018-uniphy-pcie-phy 63 + then: 64 + properties: 65 + clocks: 66 + items: 67 + - description: pcie pipe clock 68 + resets: 69 + items: 70 + - description: phy reset 71 + - description: cfg reset 72 + 73 + - if: 74 + properties: 75 + compatible: 76 + contains: 77 + enum: 78 + - qcom,ipq5332-uniphy-pcie-phy 79 + then: 80 + properties: 81 + clocks: 82 + items: 83 + - description: pcie pipe clock 84 + - description: pcie ahb clock 85 + resets: 86 + items: 87 + - description: phy reset 88 + - description: ahb reset 89 + - description: cfg reset 53 90 54 91 examples: 55 92 - |
+7 -1
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
··· 16 16 - enum: 17 17 - renesas,usb2-phy-r8a77470 # RZ/G1C 18 18 - renesas,usb2-phy-r9a08g045 # RZ/G3S 19 + - renesas,usb2-phy-r9a09g057 # RZ/V2H(P) 19 20 20 21 - items: 21 22 - enum: ··· 106 105 properties: 107 106 compatible: 108 107 contains: 109 - const: renesas,rzg2l-usb2-phy 108 + enum: 109 + - renesas,usb2-phy-r9a09g057 110 + - renesas,rzg2l-usb2-phy 110 111 then: 112 + properties: 113 + clocks: 114 + minItems: 2 111 115 required: 112 116 - resets 113 117
+4
Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
··· 13 13 compatible: 14 14 enum: 15 15 - rockchip,px30-usb2phy 16 + - rockchip,rk3036-usb2phy 16 17 - rockchip,rk3128-usb2phy 17 18 - rockchip,rk3228-usb2phy 18 19 - rockchip,rk3308-usb2phy 19 20 - rockchip,rk3328-usb2phy 20 21 - rockchip,rk3366-usb2phy 21 22 - rockchip,rk3399-usb2phy 23 + - rockchip,rk3562-usb2phy 22 24 - rockchip,rk3568-usb2phy 23 25 - rockchip,rk3576-usb2phy 24 26 - rockchip,rk3588-usb2phy ··· 186 184 contains: 187 185 enum: 188 186 - rockchip,px30-usb2phy 187 + - rockchip,rk3036-usb2phy 189 188 - rockchip,rk3128-usb2phy 190 189 - rockchip,rk3228-usb2phy 191 190 - rockchip,rk3308-usb2phy 192 191 - rockchip,rk3328-usb2phy 193 192 - rockchip,rk3366-usb2phy 194 193 - rockchip,rk3399-usb2phy 194 + - rockchip,rk3562-usb2phy 195 195 - rockchip,rk3568-usb2phy 196 196 - rockchip,rk3588-usb2phy 197 197 - rockchip,rv1108-usb2phy
+3
Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
··· 46 46 reset-names: 47 47 const: phy 48 48 49 + phy-supply: 50 + description: Single PHY regulator 51 + 49 52 rockchip,phy-grf: 50 53 $ref: /schemas/types.yaml#/definitions/phandle 51 54 description: phandle to the syscon managing the phy "general register files"
+45
Documentation/devicetree/bindings/phy/rockchip,rk3399-pcie-phy.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/rockchip,rk3399-pcie-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rockchip RK3399 PCIE PHY 8 + 9 + maintainers: 10 + - Heiko Stuebner <heiko@sntech.de> 11 + 12 + properties: 13 + compatible: 14 + const: rockchip,rk3399-pcie-phy 15 + 16 + '#phy-cells': 17 + oneOf: 18 + - const: 0 19 + deprecated: true 20 + - const: 1 21 + description: One lane per phy mode 22 + 23 + clocks: 24 + maxItems: 1 25 + 26 + clock-names: 27 + const: refclk 28 + 29 + resets: 30 + maxItems: 1 31 + 32 + reset-names: 33 + const: phy 34 + 35 + required: 36 + - compatible 37 + - '#phy-cells' 38 + - clocks 39 + - clock-names 40 + - resets 41 + - reset-names 42 + 43 + additionalProperties: false 44 + 45 + ...
+116
Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/rockchip,rk3399-typec-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rockchip Type-C PHY 8 + 9 + maintainers: 10 + - Heiko Stuebner <heiko@sntech.de> 11 + 12 + properties: 13 + compatible: 14 + const: rockchip,rk3399-typec-phy 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + clocks: 20 + maxItems: 2 21 + 22 + clock-names: 23 + items: 24 + - const: tcpdcore 25 + - const: tcpdphy-ref 26 + 27 + extcon: true 28 + 29 + power-domains: 30 + maxItems: 1 31 + 32 + resets: 33 + maxItems: 3 34 + 35 + reset-names: 36 + items: 37 + - const: uphy 38 + - const: uphy-pipe 39 + - const: uphy-tcphy 40 + 41 + rockchip,grf: 42 + $ref: /schemas/types.yaml#/definitions/phandle 43 + description: 44 + Phandle to the syscon managing the "general register files" (GRF). 45 + 46 + dp-port: 47 + type: object 48 + additionalProperties: false 49 + 50 + properties: 51 + '#phy-cells': 52 + const: 0 53 + 54 + port: 55 + $ref: /schemas/graph.yaml#/properties/port 56 + description: Connection to USB Type-C connector 57 + 58 + required: 59 + - '#phy-cells' 60 + 61 + usb3-port: 62 + type: object 63 + additionalProperties: false 64 + 65 + properties: 66 + '#phy-cells': 67 + const: 0 68 + 69 + orientation-switch: true 70 + 71 + port: 72 + $ref: /schemas/graph.yaml#/properties/port 73 + description: Connection to USB Type-C connector SS port 74 + 75 + required: 76 + - '#phy-cells' 77 + 78 + required: 79 + - compatible 80 + - reg 81 + - clocks 82 + - clock-names 83 + - resets 84 + - reset-names 85 + - dp-port 86 + - usb3-port 87 + 88 + additionalProperties: false 89 + 90 + examples: 91 + - | 92 + #include <dt-bindings/clock/rk3399-cru.h> 93 + 94 + phy@ff7c0000 { 95 + compatible = "rockchip,rk3399-typec-phy"; 96 + reg = <0xff7c0000 0x40000>; 97 + rockchip,grf = <&grf>; 98 + extcon = <&fusb0>; 99 + clocks = <&cru SCLK_UPHY0_TCPDCORE>, 100 + <&cru SCLK_UPHY0_TCPDPHY_REF>; 101 + clock-names = "tcpdcore", "tcpdphy-ref"; 102 + resets = <&cru SRST_UPHY0>, 103 + <&cru SRST_UPHY0_PIPE_L00>, 104 + <&cru SRST_P_UPHY0_TCPHY>; 105 + reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; 106 + 107 + dp-port { 108 + #phy-cells = <0>; 109 + }; 110 + 111 + usb3-port { 112 + #phy-cells = <0>; 113 + }; 114 + }; 115 + 116 + ...
-36
Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt
··· 1 - Rockchip PCIE PHY 2 - ----------------------- 3 - 4 - Required properties: 5 - - compatible: rockchip,rk3399-pcie-phy 6 - - clocks: Must contain an entry in clock-names. 7 - See ../clocks/clock-bindings.txt for details. 8 - - clock-names: Must be "refclk" 9 - - resets: Must contain an entry in reset-names. 10 - See ../reset/reset.txt for details. 11 - - reset-names: Must be "phy" 12 - 13 - Required properties for legacy PHY mode (deprecated): 14 - - #phy-cells: must be 0 15 - 16 - Required properties for per-lane PHY mode (preferred): 17 - - #phy-cells: must be 1 18 - 19 - Example: 20 - 21 - grf: syscon@ff770000 { 22 - compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd"; 23 - #address-cells = <1>; 24 - #size-cells = <1>; 25 - 26 - ... 27 - 28 - pcie_phy: pcie-phy { 29 - compatible = "rockchip,rk3399-pcie-phy"; 30 - #phy-cells = <0>; 31 - clocks = <&cru SCLK_PCIEPHY_REF>; 32 - clock-names = "refclk"; 33 - resets = <&cru SRST_PCIEPHY>; 34 - reset-names = "phy"; 35 - }; 36 - };
+80
Documentation/devicetree/bindings/phy/samsung,exynos2200-eusb2-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/samsung,exynos2200-eusb2-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Samsung Exynos2200 eUSB2 phy controller 8 + 9 + maintainers: 10 + - Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com> 11 + 12 + description: 13 + Samsung Exynos2200 eUSB2 phy, based on Synopsys eUSB2 IP block, supports 14 + LS/FS/HS usb connectivity. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - samsung,exynos2200-eusb2-phy 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + "#phy-cells": 25 + const: 0 26 + 27 + clocks: 28 + items: 29 + - description: Reference clock 30 + - description: Bus (APB) clock 31 + - description: Control clock 32 + 33 + clock-names: 34 + items: 35 + - const: ref 36 + - const: bus 37 + - const: ctrl 38 + 39 + resets: 40 + maxItems: 1 41 + 42 + phys: 43 + maxItems: 1 44 + description: 45 + Phandle to eUSB2 to USB 2.0 repeater 46 + 47 + vdd-supply: 48 + description: 49 + Phandle to 0.88V regulator supply to PHY digital circuit. 50 + 51 + vdda12-supply: 52 + description: 53 + Phandle to 1.2V regulator supply to PHY refclk pll block. 54 + 55 + required: 56 + - compatible 57 + - reg 58 + - "#phy-cells" 59 + - clocks 60 + - clock-names 61 + - vdd-supply 62 + - vdda12-supply 63 + 64 + additionalProperties: false 65 + 66 + examples: 67 + - | 68 + usb_hsphy: phy@10ab0000 { 69 + compatible = "samsung,exynos2200-eusb2-phy"; 70 + reg = <0x10ab0000 0x10000>; 71 + #phy-cells = <0>; 72 + 73 + clocks = <&cmu_hsi0 7>, 74 + <&cmu_hsi0 5>, 75 + <&cmu_hsi0 8>; 76 + clock-names = "ref", "bus", "ctrl"; 77 + 78 + vdd-supply = <&vreg_0p88>; 79 + vdda12-supply = <&vreg_1p2>; 80 + };
+36 -4
Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
··· 26 26 compatible: 27 27 enum: 28 28 - google,gs101-usb31drd-phy 29 + - samsung,exynos2200-usb32drd-phy 29 30 - samsung,exynos5250-usbdrd-phy 30 31 - samsung,exynos5420-usbdrd-phy 31 32 - samsung,exynos5433-usbdrd-phy 32 33 - samsung,exynos7-usbdrd-phy 34 + - samsung,exynos7870-usbdrd-phy 33 35 - samsung,exynos850-usbdrd-phy 34 36 35 37 clocks: 36 - minItems: 2 38 + minItems: 1 37 39 maxItems: 5 38 40 39 41 clock-names: 40 - minItems: 2 42 + minItems: 1 41 43 maxItems: 5 42 44 description: | 43 - At least two clocks:: 45 + Typically two clocks: 44 46 - Main PHY clock (same as USB DRD controller i.e. DWC3 IP clock), used 45 47 for register access. 46 48 - PHY reference clock (usually crystal clock), used for PHY operations, 47 49 associated by phy name. It is used to determine bit values for clock 48 50 settings register. For Exynos5420 this is given as 'sclk_usbphy30' 49 - in the CMU. 51 + in the CMU. It's not needed for Exynos2200. 50 52 51 53 "#phy-cells": 52 54 const: 1 55 + 56 + phys: 57 + maxItems: 1 58 + description: 59 + USBDRD-underlying high-speed PHY 60 + 61 + phy-names: 62 + const: hs 53 63 54 64 port: 55 65 $ref: /schemas/graph.yaml#/properties/port ··· 165 155 compatible: 166 156 contains: 167 157 enum: 158 + - samsung,exynos2200-usb32drd-phy 159 + then: 160 + properties: 161 + clocks: 162 + maxItems: 1 163 + clock-names: 164 + items: 165 + - const: phy 166 + reg: 167 + maxItems: 1 168 + reg-names: 169 + maxItems: 1 170 + required: 171 + - phys 172 + - phy-names 173 + 174 + - if: 175 + properties: 176 + compatible: 177 + contains: 178 + enum: 168 179 - samsung,exynos5433-usbdrd-phy 169 180 - samsung,exynos7-usbdrd-phy 170 181 then: ··· 215 184 enum: 216 185 - samsung,exynos5250-usbdrd-phy 217 186 - samsung,exynos5420-usbdrd-phy 187 + - samsung,exynos7870-usbdrd-phy 218 188 - samsung,exynos850-usbdrd-phy 219 189 then: 220 190 properties:
+11 -2
Documentation/devicetree/bindings/soc/rockchip/grf.yaml
··· 208 208 209 209 pcie-phy: 210 210 type: object 211 - description: 212 - Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt 211 + $ref: /schemas/phy/rockchip,rk3399-pcie-phy.yaml# 212 + unevaluatedProperties: false 213 213 214 214 patternProperties: 215 215 "^phy@[0-9a-f]+$": ··· 331 331 clock-names = "dphy-ref", "dphy-cfg", "grf"; 332 332 power-domains = <&power RK3399_PD_VIO>; 333 333 #phy-cells = <0>; 334 + }; 335 + 336 + pcie-phy { 337 + compatible = "rockchip,rk3399-pcie-phy"; 338 + #phy-cells = <1>; 339 + clocks = <&cru SCLK_PCIEPHY_REF>; 340 + clock-names = "refclk"; 341 + resets = <&cru SRST_PCIEPHY>; 342 + reset-names = "phy"; 334 343 }; 335 344 336 345 phy@f780 {
+1 -1
Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml
··· 18 18 Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml 19 19 20 20 Type-C PHY 21 - Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 21 + Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml 22 22 23 23 select: 24 24 properties:
+8
drivers/phy/Kconfig
··· 43 43 help 44 44 Enable this to support the USB2.0 PHY on the IMG Pistachio SoC. 45 45 46 + config PHY_SNPS_EUSB2 47 + tristate "SNPS eUSB2 PHY Driver" 48 + depends on OF && (ARCH_EXYNOS || ARCH_QCOM || COMPILE_TEST) 49 + select GENERIC_PHY 50 + help 51 + Enable support for the USB high-speed SNPS eUSB2 phy on select 52 + SoCs. The PHY is usually paired with a Synopsys DWC3 USB controller. 53 + 46 54 config PHY_XGENE 47 55 tristate "APM X-Gene 15Gbps PHY support" 48 56 depends on HAS_IOMEM && OF && (ARCH_XGENE || COMPILE_TEST)
+1
drivers/phy/Makefile
··· 9 9 obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o 10 10 obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 11 11 obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 12 + obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snps-eusb2.o 12 13 obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o 13 14 obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o 14 15 obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
+3 -7
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
··· 377 377 return ret; 378 378 379 379 phy = devm_phy_create(dev, NULL, &phy_meson_axg_mipi_dphy_ops); 380 - if (IS_ERR(phy)) { 381 - ret = PTR_ERR(phy); 382 - if (ret != -EPROBE_DEFER) 383 - dev_err(dev, "failed to create PHY\n"); 384 - 385 - return ret; 386 - } 380 + if (IS_ERR(phy)) 381 + return dev_err_probe(dev, PTR_ERR(phy), 382 + "failed to create PHY\n"); 387 383 388 384 phy_set_drvdata(phy, priv); 389 385
+3 -7
drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
··· 200 200 struct phy_axg_mipi_pcie_analog_priv *priv; 201 201 struct device_node *np = dev->of_node, *parent_np; 202 202 struct regmap *map; 203 - int ret; 204 203 205 204 priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); 206 205 if (!priv) ··· 218 219 priv->regmap = map; 219 220 220 221 priv->phy = devm_phy_create(dev, np, &phy_axg_mipi_pcie_analog_ops); 221 - if (IS_ERR(priv->phy)) { 222 - ret = PTR_ERR(priv->phy); 223 - if (ret != -EPROBE_DEFER) 224 - dev_err(dev, "failed to create PHY\n"); 225 - return ret; 226 - } 222 + if (IS_ERR(priv->phy)) 223 + return dev_err_probe(dev, PTR_ERR(priv->phy), 224 + "failed to create PHY\n"); 227 225 228 226 phy_set_drvdata(priv->phy, priv); 229 227 dev_set_drvdata(dev, priv);
+5 -9
drivers/phy/amlogic/phy-meson-axg-pcie.c
··· 131 131 struct phy_axg_pcie_priv *priv; 132 132 struct device_node *np = dev->of_node; 133 133 void __iomem *base; 134 - int ret; 135 134 136 135 priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); 137 136 if (!priv) 138 137 return -ENOMEM; 139 - 140 - priv->phy = devm_phy_create(dev, np, &phy_axg_pcie_ops); 141 - if (IS_ERR(priv->phy)) { 142 - ret = PTR_ERR(priv->phy); 143 - if (ret != -EPROBE_DEFER) 144 - dev_err(dev, "failed to create PHY\n"); 145 - return ret; 146 - } 147 138 148 139 base = devm_platform_ioremap_resource(pdev, 0); 149 140 if (IS_ERR(base)) ··· 152 161 priv->analog = devm_phy_get(dev, "analog"); 153 162 if (IS_ERR(priv->analog)) 154 163 return PTR_ERR(priv->analog); 164 + 165 + priv->phy = devm_phy_create(dev, np, &phy_axg_pcie_ops); 166 + if (IS_ERR(priv->phy)) 167 + return dev_err_probe(dev, PTR_ERR(priv->phy), 168 + "failed to create PHY\n"); 155 169 156 170 phy_set_drvdata(priv->phy, priv); 157 171 dev_set_drvdata(dev, priv);
+3 -7
drivers/phy/amlogic/phy-meson-g12a-usb2.c
··· 339 339 return ret; 340 340 341 341 phy = devm_phy_create(dev, NULL, &phy_meson_g12a_usb2_ops); 342 - if (IS_ERR(phy)) { 343 - ret = PTR_ERR(phy); 344 - if (ret != -EPROBE_DEFER) 345 - dev_err(dev, "failed to create PHY\n"); 346 - 347 - return ret; 348 - } 342 + if (IS_ERR(phy)) 343 + return dev_err_probe(dev, PTR_ERR(phy), 344 + "failed to create PHY\n"); 349 345 350 346 phy_set_bus_width(phy, 8); 351 347 phy_set_drvdata(phy, priv);
+3 -8
drivers/phy/amlogic/phy-meson-gxl-usb2.c
··· 237 237 struct phy_meson_gxl_usb2_priv *priv; 238 238 struct phy *phy; 239 239 void __iomem *base; 240 - int ret; 241 240 242 241 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 243 242 if (!priv) ··· 265 266 return PTR_ERR(priv->reset); 266 267 267 268 phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops); 268 - if (IS_ERR(phy)) { 269 - ret = PTR_ERR(phy); 270 - if (ret != -EPROBE_DEFER) 271 - dev_err(dev, "failed to create PHY\n"); 272 - 273 - return ret; 274 - } 269 + if (IS_ERR(phy)) 270 + return dev_err_probe(dev, PTR_ERR(phy), 271 + "failed to create PHY\n"); 275 272 276 273 phy_set_drvdata(phy, priv); 277 274
+14 -21
drivers/phy/amlogic/phy-meson8b-usb2.c
··· 5 5 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com> 6 6 */ 7 7 8 + #include <linux/bitfield.h> 8 9 #include <linux/clk.h> 9 10 #include <linux/delay.h> 10 11 #include <linux/io.h> ··· 40 39 #define REG_CTRL_TX_BITSTUFF_ENN BIT(18) 41 40 #define REG_CTRL_COMMON_ON BIT(19) 42 41 #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) 43 - #define REG_CTRL_REF_CLK_SEL_SHIFT 20 44 42 #define REG_CTRL_FSEL_MASK GENMASK(24, 22) 45 - #define REG_CTRL_FSEL_SHIFT 22 46 43 #define REG_CTRL_PORT_RESET BIT(25) 47 44 #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) 48 45 ··· 165 166 return ret; 166 167 } 167 168 168 - regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, 169 - REG_CONFIG_CLK_32k_ALTSEL); 169 + regmap_set_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL); 170 170 171 171 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, 172 - 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); 172 + FIELD_PREP(REG_CTRL_REF_CLK_SEL_MASK, 0x2)); 173 173 174 174 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK, 175 - 0x5 << REG_CTRL_FSEL_SHIFT); 175 + FIELD_PREP(REG_CTRL_FSEL_MASK, 0x5)); 176 176 177 177 /* reset the PHY */ 178 - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 179 - REG_CTRL_POWER_ON_RESET); 178 + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); 180 179 udelay(RESET_COMPLETE_TIME); 181 - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); 180 + regmap_clear_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); 182 181 udelay(RESET_COMPLETE_TIME); 183 182 184 - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, 185 - REG_CTRL_SOF_TOGGLE_OUT); 183 + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT); 186 184 187 185 if (priv->dr_mode == USB_DR_MODE_HOST) { 188 - regmap_update_bits(priv->regmap, REG_DBG_UART, 189 - REG_DBG_UART_SET_IDDQ, 0); 186 + regmap_clear_bits(priv->regmap, REG_DBG_UART, 187 + REG_DBG_UART_SET_IDDQ); 190 188 191 189 if (priv->match->host_enable_aca) { 192 - regmap_update_bits(priv->regmap, REG_ADP_BC, 193 - REG_ADP_BC_ACA_ENABLE, 194 - REG_ADP_BC_ACA_ENABLE); 190 + regmap_set_bits(priv->regmap, REG_ADP_BC, 191 + REG_ADP_BC_ACA_ENABLE); 195 192 196 193 udelay(ACA_ENABLE_COMPLETE_TIME); 197 194 ··· 210 215 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); 211 216 212 217 if (priv->dr_mode == USB_DR_MODE_HOST) 213 - regmap_update_bits(priv->regmap, REG_DBG_UART, 214 - REG_DBG_UART_SET_IDDQ, 215 - REG_DBG_UART_SET_IDDQ); 218 + regmap_set_bits(priv->regmap, REG_DBG_UART, 219 + REG_DBG_UART_SET_IDDQ); 216 220 217 221 clk_disable_unprepare(priv->clk_usb); 218 222 clk_disable_unprepare(priv->clk_usb_general); 219 223 reset_control_rearm(priv->reset); 220 224 221 225 /* power off the PHY by putting it into reset mode */ 222 - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 223 - REG_CTRL_POWER_ON_RESET); 226 + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); 224 227 225 228 return 0; 226 229 }
+61
drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
··· 43 43 #define USB_CTRL_SETUP_tca_drv_sel_MASK BIT(24) 44 44 #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) 45 45 #define USB_CTRL_USB_PM 0x04 46 + #define USB_CTRL_USB_PM_REF_S2_CLK_SWITCH_EN_MASK BIT(1) 47 + #define USB_CTRL_USB_PM_UTMI_S2_CLK_SWITCH_EN_MASK BIT(2) 46 48 #define USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK BIT(3) 47 49 #define USB_CTRL_USB_PM_XHC_PME_EN_MASK BIT(4) 48 50 #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK BIT(22) ··· 63 61 #define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK BIT(18) 64 62 #define USB_CTRL_P0_U2PHY_CFG1 0x68 65 63 #define USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK BIT(10) 64 + #define USB_CTRL_P0_U2PHY_CFG2 0x6c 65 + #define USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK GENMASK(20, 17) 66 + #define USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT 17 67 + #define USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK GENMASK(24, 23) 68 + #define USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT 23 69 + #define USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK GENMASK(26, 25) 70 + #define USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT 25 66 71 67 72 /* Register definitions for the USB_PHY block in 7211b0 */ 68 73 #define USB_PHY_PLL_CTL 0x00 ··· 378 369 } 379 370 } 380 371 372 + static void usb_init_common_74110(struct brcm_usb_init_params *params) 373 + { 374 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 375 + u32 reg; 376 + 377 + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM)); 378 + reg &= ~(USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) | 379 + USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN)); 380 + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM)); 381 + 382 + usb_init_common_7216(params); 383 + 384 + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, P0_U2PHY_CFG2)); 385 + reg &= ~(USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK | 386 + USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK | 387 + USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK); 388 + reg |= (0x6 << USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT) | 389 + (0x3 << USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT) | 390 + (0x2 << USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT); 391 + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, P0_U2PHY_CFG2)); 392 + } 393 + 394 + static void usb_uninit_common_74110(struct brcm_usb_init_params *params) 395 + { 396 + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; 397 + u32 reg; 398 + 399 + if (params->wake_enabled) { 400 + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM)); 401 + reg |= (USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) | 402 + USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN)); 403 + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM)); 404 + } 405 + usb_uninit_common_7216(params); 406 + } 407 + 381 408 static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params) 382 409 { 383 410 void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; ··· 471 426 brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); 472 427 } 473 428 429 + static const struct brcm_usb_init_ops bcm74110_ops = { 430 + .init_ipp = usb_init_ipp, 431 + .init_common = usb_init_common_74110, 432 + .init_xhci = usb_init_xhci, 433 + .uninit_common = usb_uninit_common_74110, 434 + .uninit_xhci = usb_uninit_xhci, 435 + .get_dual_select = usb_get_dual_select, 436 + .set_dual_select = usb_set_dual_select, 437 + }; 438 + 474 439 static const struct brcm_usb_init_ops bcm7216_ops = { 475 440 .init_ipp = usb_init_ipp, 476 441 .init_common = usb_init_common_7216, ··· 500 445 .get_dual_select = usb_get_dual_select, 501 446 .set_dual_select = usb_set_dual_select, 502 447 }; 448 + 449 + void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params) 450 + { 451 + params->family_name = "74110"; 452 + params->ops = &bcm74110_ops; 453 + } 503 454 504 455 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params) 505 456 {
+1
drivers/phy/broadcom/phy-brcm-usb-init.h
··· 72 72 bool wake_enabled; 73 73 }; 74 74 75 + void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params); 75 76 void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params); 76 77 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params); 77 78 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
+14
drivers/phy/broadcom/phy-brcm-usb.c
··· 283 283 .attrs = brcm_usb_phy_attrs, 284 284 }; 285 285 286 + static const struct match_chip_info chip_info_74110 = { 287 + .init_func = &brcm_usb_dvr_init_74110, 288 + .required_regs = { 289 + BRCM_REGS_CTRL, 290 + BRCM_REGS_XHCI_EC, 291 + BRCM_REGS_XHCI_GBL, 292 + -1, 293 + }, 294 + }; 295 + 286 296 static const struct match_chip_info chip_info_4908 = { 287 297 .init_func = &brcm_usb_dvr_init_4908, 288 298 .required_regs = { ··· 335 325 }; 336 326 337 327 static const struct of_device_id brcm_usb_dt_ids[] = { 328 + { 329 + .compatible = "brcm,bcm74110-usb-phy", 330 + .data = &chip_info_74110, 331 + }, 338 332 { 339 333 .compatible = "brcm,bcm4908-usb-phy", 340 334 .data = &chip_info_4908,
+9 -12
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
··· 238 238 imx8_phy->clkreq_unused = false; 239 239 240 240 imx8_phy->clk = devm_clk_get(dev, "ref"); 241 - if (IS_ERR(imx8_phy->clk)) { 242 - dev_err(dev, "failed to get imx pcie phy clock\n"); 243 - return PTR_ERR(imx8_phy->clk); 244 - } 241 + if (IS_ERR(imx8_phy->clk)) 242 + return dev_err_probe(dev, PTR_ERR(imx8_phy->clk), 243 + "failed to get imx pcie phy clock\n"); 245 244 246 245 /* Grab GPR config register range */ 247 246 imx8_phy->iomuxc_gpr = 248 247 syscon_regmap_lookup_by_compatible(imx8_phy->drvdata->gpr); 249 - if (IS_ERR(imx8_phy->iomuxc_gpr)) { 250 - dev_err(dev, "unable to find iomuxc registers\n"); 251 - return PTR_ERR(imx8_phy->iomuxc_gpr); 252 - } 248 + if (IS_ERR(imx8_phy->iomuxc_gpr)) 249 + return dev_err_probe(dev, PTR_ERR(imx8_phy->iomuxc_gpr), 250 + "unable to find iomuxc registers\n"); 253 251 254 252 imx8_phy->reset = devm_reset_control_get_exclusive(dev, "pciephy"); 255 - if (IS_ERR(imx8_phy->reset)) { 256 - dev_err(dev, "Failed to get PCIEPHY reset control\n"); 257 - return PTR_ERR(imx8_phy->reset); 258 - } 253 + if (IS_ERR(imx8_phy->reset)) 254 + return dev_err_probe(dev, PTR_ERR(imx8_phy->reset), 255 + "Failed to get PCIEPHY reset control\n"); 259 256 260 257 if (imx8_phy->drvdata->variant == IMX8MP) { 261 258 imx8_phy->perst =
+79 -5
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
··· 293 293 return DIV_ROUND_CLOSEST(percent - 94U, 2); 294 294 } 295 295 296 + static u32 imx95_phy_tx_vref_tune_from_property(u32 percent) 297 + { 298 + percent = clamp(percent, 90U, 108U); 299 + 300 + switch (percent) { 301 + case 90 ... 91: 302 + percent = 0; 303 + break; 304 + case 92 ... 96: 305 + percent -= 91; 306 + break; 307 + case 97 ... 104: 308 + percent -= 92; 309 + break; 310 + case 105 ... 108: 311 + percent -= 93; 312 + break; 313 + } 314 + 315 + return percent; 316 + } 317 + 296 318 static u32 phy_tx_rise_tune_from_property(u32 percent) 297 319 { 298 320 switch (percent) { ··· 329 307 } 330 308 } 331 309 310 + static u32 imx95_phy_tx_rise_tune_from_property(u32 percent) 311 + { 312 + percent = clamp(percent, 90U, 120U); 313 + 314 + switch (percent) { 315 + case 90 ... 99: 316 + return 3; 317 + case 101 ... 115: 318 + return 1; 319 + case 116 ... 120: 320 + return 0; 321 + default: 322 + return 2; 323 + } 324 + } 325 + 332 326 static u32 phy_tx_preemp_amp_tune_from_property(u32 microamp) 333 327 { 334 328 microamp = min(microamp, 1800U); ··· 355 317 static u32 phy_tx_vboost_level_from_property(u32 microvolt) 356 318 { 357 319 switch (microvolt) { 358 - case 0 ... 960: 359 - return 0; 360 - case 961 ... 1160: 361 - return 2; 362 - default: 320 + case 1156: 321 + return 5; 322 + case 844: 363 323 return 3; 324 + default: 325 + return 4; 364 326 } 365 327 } 366 328 ··· 390 352 return 7; 391 353 } 392 354 } 355 + 356 + static u32 imx95_phy_comp_dis_tune_from_property(u32 percent) 357 + { 358 + percent = clamp(percent, 94, 104); 359 + 360 + switch (percent) { 361 + case 94 ... 95: 362 + percent = 0; 363 + break; 364 + case 96 ... 98: 365 + percent -= 95; 366 + break; 367 + case 99 ... 102: 368 + percent -= 96; 369 + break; 370 + case 103 ... 104: 371 + percent -= 97; 372 + break; 373 + } 374 + 375 + return percent; 376 + } 377 + 393 378 static u32 phy_pcs_tx_swing_full_from_property(u32 percent) 394 379 { 395 380 percent = min(percent, 100U); ··· 423 362 static void imx8m_get_phy_tuning_data(struct imx8mq_usb_phy *imx_phy) 424 363 { 425 364 struct device *dev = imx_phy->phy->dev.parent; 365 + bool is_imx95 = false; 366 + 367 + if (device_is_compatible(dev, "fsl,imx95-usb-phy")) 368 + is_imx95 = true; 426 369 427 370 if (device_property_read_u32(dev, "fsl,phy-tx-vref-tune-percent", 428 371 &imx_phy->tx_vref_tune)) 429 372 imx_phy->tx_vref_tune = PHY_TUNE_DEFAULT; 373 + else if (is_imx95) 374 + imx_phy->tx_vref_tune = 375 + imx95_phy_tx_vref_tune_from_property(imx_phy->tx_vref_tune); 430 376 else 431 377 imx_phy->tx_vref_tune = 432 378 phy_tx_vref_tune_from_property(imx_phy->tx_vref_tune); ··· 441 373 if (device_property_read_u32(dev, "fsl,phy-tx-rise-tune-percent", 442 374 &imx_phy->tx_rise_tune)) 443 375 imx_phy->tx_rise_tune = PHY_TUNE_DEFAULT; 376 + else if (is_imx95) 377 + imx_phy->tx_rise_tune = 378 + imx95_phy_tx_rise_tune_from_property(imx_phy->tx_rise_tune); 444 379 else 445 380 imx_phy->tx_rise_tune = 446 381 phy_tx_rise_tune_from_property(imx_phy->tx_rise_tune); ··· 465 394 if (device_property_read_u32(dev, "fsl,phy-comp-dis-tune-percent", 466 395 &imx_phy->comp_dis_tune)) 467 396 imx_phy->comp_dis_tune = PHY_TUNE_DEFAULT; 397 + else if (is_imx95) 398 + imx_phy->comp_dis_tune = 399 + imx95_phy_comp_dis_tune_from_property(imx_phy->comp_dis_tune); 468 400 else 469 401 imx_phy->comp_dis_tune = 470 402 phy_comp_dis_tune_from_property(imx_phy->comp_dis_tune);
+51 -68
drivers/phy/freescale/phy-fsl-samsung-hdmi.c
··· 456 456 int i, ret; 457 457 u8 val; 458 458 459 + phy->cur_cfg = cfg; 460 + 459 461 /* HDMI PHY init */ 460 462 writeb(REG33_FIX_DA, phy->regs + PHY_REG(33)); 461 463 ··· 510 508 if (phy_pll_cfg[i].pixclk <= rate) 511 509 break; 512 510 513 - return &phy_pll_cfg[i]; 511 + /* If there is an exact match, or the array has been searched, return the value*/ 512 + if (phy_pll_cfg[i].pixclk == rate || i + 1 > ARRAY_SIZE(phy_pll_cfg) - 1) 513 + return &phy_pll_cfg[i]; 514 + 515 + /* See if the next entry is closer to nominal than this one */ 516 + return (abs((long) rate - (long) phy_pll_cfg[i].pixclk) < 517 + abs((long) rate - (long) phy_pll_cfg[i+1].pixclk) ? 518 + &phy_pll_cfg[i] : &phy_pll_cfg[i+1]); 514 519 } 515 520 516 521 static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate, ··· 530 521 /* pll_div_regs 3-6 are fixed and pre-defined already */ 531 522 } 532 523 533 - static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate, 534 - u32 int_div_clk, u32 frac_div_clk) 535 - { 536 - /* Calculate the absolute value of the differences and return whichever is closest */ 537 - if (abs((long)rate - (long)int_div_clk) < abs((long)(rate - (long)frac_div_clk))) 538 - return int_div_clk; 539 - 540 - return frac_div_clk; 541 - } 542 - 543 - static long phy_clk_round_rate(struct clk_hw *hw, 544 - unsigned long rate, unsigned long *parent_rate) 524 + static 525 + const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_hdmi_phy *phy, 526 + unsigned long rate) 545 527 { 546 528 const struct phy_config *fract_div_phy; 547 529 u32 int_div_clk; ··· 541 541 542 542 /* If the clock is out of range return error instead of searching */ 543 543 if (rate > 297000000 || rate < 22250000) 544 - return -EINVAL; 544 + return NULL; 545 545 546 546 /* Search the fractional divider lookup table */ 547 547 fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate); 548 + if (fract_div_phy->pixclk == rate) { 549 + dev_dbg(phy->dev, "fractional divider match = %u\n", fract_div_phy->pixclk); 550 + return fract_div_phy; 551 + } 548 552 549 - /* If the rate is an exact match, return that value */ 550 - if (rate == fract_div_phy->pixclk) 551 - return fract_div_phy->pixclk; 552 - 553 - /* If the exact match isn't found, calculate the integer divider */ 553 + /* Calculate the integer divider */ 554 554 int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s); 555 + fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s); 556 + if (int_div_clk == rate) { 557 + dev_dbg(phy->dev, "integer divider match = %u\n", calculated_phy_pll_cfg.pixclk); 558 + return &calculated_phy_pll_cfg; 559 + } 555 560 556 - /* If the int_div_clk rate is an exact match, return that value */ 557 - if (int_div_clk == rate) 558 - return int_div_clk; 561 + /* Calculate the absolute value of the differences and return whichever is closest */ 562 + if (abs((long)rate - (long)int_div_clk) < 563 + abs((long)rate - (long)fract_div_phy->pixclk)) { 564 + dev_dbg(phy->dev, "integer divider = %u\n", calculated_phy_pll_cfg.pixclk); 565 + return &calculated_phy_pll_cfg; 566 + } 559 567 560 - /* If neither rate is an exact match, use the value from the LUT */ 561 - return fract_div_phy->pixclk; 568 + dev_dbg(phy->dev, "fractional divider = %u\n", phy->cur_cfg->pixclk); 569 + 570 + return fract_div_phy; 562 571 } 563 572 564 - static int phy_use_fract_div(struct fsl_samsung_hdmi_phy *phy, const struct phy_config *fract_div_phy) 573 + static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw, 574 + unsigned long rate, unsigned long *parent_rate) 565 575 { 566 - phy->cur_cfg = fract_div_phy; 567 - dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n", 568 - phy->cur_cfg->pixclk); 569 - return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg); 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); 578 + 579 + if (target_settings == NULL) 580 + return -EINVAL; 581 + 582 + dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk); 583 + return target_settings->pixclk; 570 584 } 571 585 572 - static int phy_use_integer_div(struct fsl_samsung_hdmi_phy *phy, 573 - const struct phy_config *int_div_clk) 574 - { 575 - phy->cur_cfg = &calculated_phy_pll_cfg; 576 - dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n", 577 - phy->cur_cfg->pixclk); 578 - return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg); 579 - } 580 - 581 - static int phy_clk_set_rate(struct clk_hw *hw, 586 + static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw, 582 587 unsigned long rate, unsigned long parent_rate) 583 588 { 584 589 struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw); 585 - const struct phy_config *fract_div_phy; 586 - u32 int_div_clk; 587 - u16 m; 588 - u8 p, s; 590 + const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate); 589 591 590 - /* Search the fractional divider lookup table */ 591 - fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate); 592 + if (target_settings == NULL) 593 + return -EINVAL; 592 594 593 - /* If the rate is an exact match, use that value */ 594 - if (fract_div_phy->pixclk == rate) 595 - return phy_use_fract_div(phy, fract_div_phy); 595 + dev_dbg(phy->dev, "set_rate, closest rate = %u\n", target_settings->pixclk); 596 596 597 - /* 598 - * If the rate from the fractional divider is not exact, check the integer divider, 599 - * and use it if that value is an exact match. 600 - */ 601 - int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s); 602 - fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s); 603 - if (int_div_clk == rate) 604 - return phy_use_integer_div(phy, &calculated_phy_pll_cfg); 605 - 606 - /* 607 - * Compare the difference between the integer clock and the fractional clock against 608 - * the desired clock and which whichever is closest. 609 - */ 610 - if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk, 611 - fract_div_phy->pixclk) == fract_div_phy->pixclk) 612 - return phy_use_fract_div(phy, fract_div_phy); 613 - else 614 - return phy_use_integer_div(phy, &calculated_phy_pll_cfg); 597 + return fsl_samsung_hdmi_phy_configure(phy, target_settings); 615 598 } 616 599 617 600 static const struct clk_ops phy_clk_ops = { 618 601 .recalc_rate = phy_clk_recalc_rate, 619 - .round_rate = phy_clk_round_rate, 620 - .set_rate = phy_clk_set_rate, 602 + .round_rate = fsl_samsung_hdmi_phy_clk_round_rate, 603 + .set_rate = fsl_samsung_hdmi_phy_clk_set_rate, 621 604 }; 622 605 623 606 static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
+2 -2
drivers/phy/marvell/Kconfig
··· 29 29 depends on ARCH_MVEBU || COMPILE_TEST 30 30 depends on OF 31 31 depends on HAVE_ARM_SMCCC 32 - default y 32 + default ARCH_MVEBU 33 33 select GENERIC_PHY 34 34 help 35 35 This driver allows to control the comphy, a hardware block providing ··· 40 40 tristate "Marvell A3700 UTMI driver" 41 41 depends on ARCH_MVEBU || COMPILE_TEST 42 42 depends on OF 43 - default y 43 + default ARCH_MVEBU 44 44 select GENERIC_PHY 45 45 help 46 46 Enable this to support Marvell A3700 UTMI PHY driver.
+84 -1
drivers/phy/mediatek/phy-mtk-xsphy.c
··· 11 11 #include <linux/clk.h> 12 12 #include <linux/delay.h> 13 13 #include <linux/iopoll.h> 14 + #include <linux/mfd/syscon.h> 14 15 #include <linux/module.h> 15 16 #include <linux/of_address.h> 16 17 #include <linux/phy/phy.h> 17 18 #include <linux/platform_device.h> 19 + #include <linux/regmap.h> 18 20 19 21 #include "phy-mtk-io.h" 20 22 ··· 83 81 #define XSP_SR_COEF_DIVISOR 1000 84 82 #define XSP_FM_DET_CYCLE_CNT 1024 85 83 84 + /* PHY switch between pcie/usb3/sgmii */ 85 + #define USB_PHY_SWITCH_CTRL 0x0 86 + #define RG_PHY_SW_TYPE GENMASK(3, 0) 87 + #define RG_PHY_SW_PCIE 0x0 88 + #define RG_PHY_SW_USB3 0x1 89 + #define RG_PHY_SW_SGMII 0x2 90 + 86 91 struct xsphy_instance { 87 92 struct phy *phy; 88 93 void __iomem *port_base; 89 94 struct clk *ref_clk; /* reference clock of anolog phy */ 90 95 u32 index; 91 96 u32 type; 97 + struct regmap *type_sw; 98 + u32 type_sw_reg; 99 + u32 type_sw_index; 92 100 /* only for HQA test */ 93 101 int efuse_intr; 94 102 int efuse_tx_imp; ··· 271 259 inst->efuse_intr, inst->efuse_tx_imp, 272 260 inst->efuse_rx_imp); 273 261 break; 262 + case PHY_TYPE_PCIE: 263 + case PHY_TYPE_SGMII: 264 + /* nothing to do */ 265 + break; 274 266 default: 275 267 dev_err(xsphy->dev, "incompatible phy type\n"); 276 268 return; ··· 321 305 RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp); 322 306 } 323 307 308 + /* type switch for usb3/pcie/sgmii */ 309 + static int phy_type_syscon_get(struct xsphy_instance *instance, 310 + struct device_node *dn) 311 + { 312 + struct of_phandle_args args; 313 + int ret; 314 + 315 + /* type switch function is optional */ 316 + if (!of_property_present(dn, "mediatek,syscon-type")) 317 + return 0; 318 + 319 + ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type", 320 + 2, 0, &args); 321 + if (ret) 322 + return ret; 323 + 324 + instance->type_sw_reg = args.args[0]; 325 + instance->type_sw_index = args.args[1] & 0x3; /* <=3 */ 326 + instance->type_sw = syscon_node_to_regmap(args.np); 327 + of_node_put(args.np); 328 + dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n", 329 + instance->type_sw_reg, instance->type_sw_index); 330 + 331 + return PTR_ERR_OR_ZERO(instance->type_sw); 332 + } 333 + 334 + static int phy_type_set(struct xsphy_instance *instance) 335 + { 336 + int type; 337 + u32 offset; 338 + 339 + if (!instance->type_sw) 340 + return 0; 341 + 342 + switch (instance->type) { 343 + case PHY_TYPE_USB3: 344 + type = RG_PHY_SW_USB3; 345 + break; 346 + case PHY_TYPE_PCIE: 347 + type = RG_PHY_SW_PCIE; 348 + break; 349 + case PHY_TYPE_SGMII: 350 + type = RG_PHY_SW_SGMII; 351 + break; 352 + case PHY_TYPE_USB2: 353 + default: 354 + return 0; 355 + } 356 + 357 + offset = instance->type_sw_index * BITS_PER_BYTE; 358 + regmap_update_bits(instance->type_sw, instance->type_sw_reg, 359 + RG_PHY_SW_TYPE << offset, type << offset); 360 + 361 + return 0; 362 + } 363 + 324 364 static int mtk_phy_init(struct phy *phy) 325 365 { 326 366 struct xsphy_instance *inst = phy_get_drvdata(phy); ··· 396 324 break; 397 325 case PHY_TYPE_USB3: 398 326 u3_phy_props_set(xsphy, inst); 327 + break; 328 + case PHY_TYPE_PCIE: 329 + case PHY_TYPE_SGMII: 330 + /* nothing to do, only used to set type */ 399 331 break; 400 332 default: 401 333 dev_err(xsphy->dev, "incompatible phy type\n"); ··· 479 403 480 404 inst->type = args->args[0]; 481 405 if (!(inst->type == PHY_TYPE_USB2 || 482 - inst->type == PHY_TYPE_USB3)) { 406 + inst->type == PHY_TYPE_USB3 || 407 + inst->type == PHY_TYPE_PCIE || 408 + inst->type == PHY_TYPE_SGMII)) { 483 409 dev_err(dev, "unsupported phy type: %d\n", inst->type); 484 410 return ERR_PTR(-EINVAL); 485 411 } 486 412 487 413 phy_parse_property(xsphy, inst); 414 + phy_type_set(inst); 488 415 489 416 return inst->phy; 490 417 } ··· 589 510 dev_err(dev, "failed to get ref_clk(id-%d)\n", port); 590 511 return PTR_ERR(inst->ref_clk); 591 512 } 513 + 514 + retval = phy_type_syscon_get(inst, child_np); 515 + if (retval) 516 + return retval; 592 517 } 593 518 594 519 provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
+627
drivers/phy/phy-snps-eusb2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2023, Linaro Limited 4 + */ 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <linux/delay.h> 9 + #include <linux/iopoll.h> 10 + #include <linux/mod_devicetable.h> 11 + #include <linux/phy/phy.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/regulator/consumer.h> 14 + #include <linux/reset.h> 15 + 16 + #define EXYNOS_USB_PHY_HS_PHY_CTRL_RST (0x0) 17 + #define USB_PHY_RST_MASK GENMASK(1, 0) 18 + #define UTMI_PORT_RST_MASK GENMASK(5, 4) 19 + 20 + #define EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON (0x4) 21 + #define RPTR_MODE BIT(10) 22 + #define FSEL_20_MHZ_VAL (0x1) 23 + #define FSEL_24_MHZ_VAL (0x2) 24 + #define FSEL_26_MHZ_VAL (0x3) 25 + #define FSEL_48_MHZ_VAL (0x2) 26 + 27 + #define EXYNOS_USB_PHY_CFG_PLLCFG0 (0x8) 28 + #define PHY_CFG_PLL_FB_DIV_19_8_MASK GENMASK(19, 8) 29 + #define DIV_19_8_19_2_MHZ_VAL (0x170) 30 + #define DIV_19_8_20_MHZ_VAL (0x160) 31 + #define DIV_19_8_24_MHZ_VAL (0x120) 32 + #define DIV_19_8_26_MHZ_VAL (0x107) 33 + #define DIV_19_8_48_MHZ_VAL (0x120) 34 + 35 + #define EXYNOS_USB_PHY_CFG_PLLCFG1 (0xc) 36 + #define EXYNOS_PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(11, 8) 37 + #define EXYNOS_DIV_11_8_19_2_MHZ_VAL (0x0) 38 + #define EXYNOS_DIV_11_8_20_MHZ_VAL (0x0) 39 + #define EXYNOS_DIV_11_8_24_MHZ_VAL (0x0) 40 + #define EXYNOS_DIV_11_8_26_MHZ_VAL (0x0) 41 + #define EXYNOS_DIV_11_8_48_MHZ_VAL (0x1) 42 + 43 + #define EXYNOS_PHY_CFG_TX (0x14) 44 + #define EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(2, 1) 45 + 46 + #define EXYNOS_USB_PHY_UTMI_TESTSE (0x20) 47 + #define TEST_IDDQ BIT(6) 48 + 49 + #define QCOM_USB_PHY_UTMI_CTRL0 (0x3c) 50 + #define SLEEPM BIT(0) 51 + #define OPMODE_MASK GENMASK(4, 3) 52 + #define OPMODE_NONDRIVING BIT(3) 53 + 54 + #define QCOM_USB_PHY_UTMI_CTRL5 (0x50) 55 + #define POR BIT(1) 56 + 57 + #define QCOM_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) 58 + #define PHY_ENABLE BIT(0) 59 + #define SIDDQ_SEL BIT(1) 60 + #define SIDDQ BIT(2) 61 + #define RETENABLEN BIT(3) 62 + #define FSEL_MASK GENMASK(6, 4) 63 + #define FSEL_19_2_MHZ_VAL (0x0) 64 + #define FSEL_38_4_MHZ_VAL (0x4) 65 + 66 + #define QCOM_USB_PHY_CFG_CTRL_1 (0x58) 67 + #define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1) 68 + 69 + #define QCOM_USB_PHY_CFG_CTRL_2 (0x5c) 70 + #define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0) 71 + #define DIV_7_0_19_2_MHZ_VAL (0x90) 72 + #define DIV_7_0_38_4_MHZ_VAL (0xc8) 73 + 74 + #define QCOM_USB_PHY_CFG_CTRL_3 (0x60) 75 + #define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0) 76 + #define DIV_11_8_19_2_MHZ_VAL (0x1) 77 + #define DIV_11_8_38_4_MHZ_VAL (0x0) 78 + 79 + #define PHY_CFG_PLL_REF_DIV GENMASK(7, 4) 80 + #define PLL_REF_DIV_VAL (0x0) 81 + 82 + #define QCOM_USB_PHY_HS_PHY_CTRL2 (0x64) 83 + #define VBUSVLDEXT0 BIT(0) 84 + #define USB2_SUSPEND_N BIT(2) 85 + #define USB2_SUSPEND_N_SEL BIT(3) 86 + #define VBUS_DET_EXT_SEL BIT(4) 87 + 88 + #define QCOM_USB_PHY_CFG_CTRL_4 (0x68) 89 + #define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0) 90 + #define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2) 91 + 92 + #define QCOM_USB_PHY_CFG_CTRL_5 (0x6c) 93 + #define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0) 94 + #define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6) 95 + 96 + #define QCOM_USB_PHY_CFG_CTRL_6 (0x70) 97 + #define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0) 98 + 99 + #define QCOM_USB_PHY_CFG_CTRL_7 (0x74) 100 + 101 + #define QCOM_USB_PHY_CFG_CTRL_8 (0x78) 102 + #define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0) 103 + #define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2) 104 + #define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3) 105 + #define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6) 106 + 107 + #define QCOM_USB_PHY_CFG_CTRL_9 (0x7c) 108 + #define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0) 109 + #define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3) 110 + #define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5) 111 + #define PHY_CFG_RCAL_BYPASS BIT(7) 112 + 113 + #define QCOM_USB_PHY_CFG_CTRL_10 (0x80) 114 + 115 + #define QCOM_USB_PHY_CFG0 (0x94) 116 + #define DATAPATH_CTRL_OVERRIDE_EN BIT(0) 117 + #define CMN_CTRL_OVERRIDE_EN BIT(1) 118 + 119 + #define QCOM_UTMI_PHY_CMN_CTRL0 (0x98) 120 + #define TESTBURNIN BIT(6) 121 + 122 + #define QCOM_USB_PHY_FSEL_SEL (0xb8) 123 + #define FSEL_SEL BIT(0) 124 + 125 + #define QCOM_USB_PHY_APB_ACCESS_CMD (0x130) 126 + #define RW_ACCESS BIT(0) 127 + #define APB_START_CMD BIT(1) 128 + #define APB_LOGIC_RESET BIT(2) 129 + 130 + #define QCOM_USB_PHY_APB_ACCESS_STATUS (0x134) 131 + #define ACCESS_DONE BIT(0) 132 + #define TIMED_OUT BIT(1) 133 + #define ACCESS_ERROR BIT(2) 134 + #define ACCESS_IN_PROGRESS BIT(3) 135 + 136 + #define QCOM_USB_PHY_APB_ADDRESS (0x138) 137 + #define APB_REG_ADDR_MASK GENMASK(7, 0) 138 + 139 + #define QCOM_USB_PHY_APB_WRDATA_LSB (0x13c) 140 + #define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0) 141 + 142 + #define QCOM_USB_PHY_APB_WRDATA_MSB (0x140) 143 + #define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4) 144 + 145 + #define QCOM_USB_PHY_APB_RDDATA_LSB (0x144) 146 + #define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0) 147 + 148 + #define QCOM_USB_PHY_APB_RDDATA_MSB (0x148) 149 + #define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4) 150 + 151 + static const char * const eusb2_hsphy_vreg_names[] = { 152 + "vdd", "vdda12", 153 + }; 154 + 155 + #define EUSB2_NUM_VREGS ARRAY_SIZE(eusb2_hsphy_vreg_names) 156 + 157 + struct snps_eusb2_phy_drvdata { 158 + int (*phy_init)(struct phy *p); 159 + const char * const *clk_names; 160 + int num_clks; 161 + }; 162 + 163 + struct snps_eusb2_hsphy { 164 + struct phy *phy; 165 + void __iomem *base; 166 + 167 + struct clk *ref_clk; 168 + struct clk_bulk_data *clks; 169 + struct reset_control *phy_reset; 170 + 171 + struct regulator_bulk_data vregs[EUSB2_NUM_VREGS]; 172 + 173 + enum phy_mode mode; 174 + 175 + struct phy *repeater; 176 + 177 + const struct snps_eusb2_phy_drvdata *data; 178 + }; 179 + 180 + static int snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode) 181 + { 182 + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); 183 + 184 + phy->mode = mode; 185 + 186 + return phy_set_mode_ext(phy->repeater, mode, submode); 187 + } 188 + 189 + static void snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset, 190 + u32 mask, u32 val) 191 + { 192 + u32 reg; 193 + 194 + reg = readl_relaxed(base + offset); 195 + reg &= ~mask; 196 + reg |= val & mask; 197 + writel_relaxed(reg, base + offset); 198 + 199 + /* Ensure above write is completed */ 200 + readl_relaxed(base + offset); 201 + } 202 + 203 + static void qcom_eusb2_default_parameters(struct snps_eusb2_hsphy *phy) 204 + { 205 + /* default parameters: tx pre-emphasis */ 206 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, 207 + PHY_CFG_TX_PREEMP_TUNE_MASK, 208 + FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0)); 209 + 210 + /* tx rise/fall time */ 211 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, 212 + PHY_CFG_TX_RISE_TUNE_MASK, 213 + FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2)); 214 + 215 + /* source impedance adjustment */ 216 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, 217 + PHY_CFG_TX_RES_TUNE_MASK, 218 + FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1)); 219 + 220 + /* dc voltage level adjustement */ 221 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8, 222 + PHY_CFG_TX_HS_VREF_TUNE_MASK, 223 + FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3)); 224 + 225 + /* transmitter HS crossover adjustement */ 226 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8, 227 + PHY_CFG_TX_HS_XV_TUNE_MASK, 228 + FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0)); 229 + } 230 + 231 + struct snps_eusb2_ref_clk { 232 + unsigned long freq; 233 + u32 fsel_val; 234 + u32 div_7_0_val; 235 + u32 div_11_8_val; 236 + }; 237 + 238 + static const struct snps_eusb2_ref_clk exynos_eusb2_ref_clk[] = { 239 + { 19200000, FSEL_19_2_MHZ_VAL, DIV_19_8_19_2_MHZ_VAL, EXYNOS_DIV_11_8_19_2_MHZ_VAL }, 240 + { 20000000, FSEL_20_MHZ_VAL, DIV_19_8_20_MHZ_VAL, EXYNOS_DIV_11_8_20_MHZ_VAL }, 241 + { 24000000, FSEL_24_MHZ_VAL, DIV_19_8_24_MHZ_VAL, EXYNOS_DIV_11_8_24_MHZ_VAL }, 242 + { 26000000, FSEL_26_MHZ_VAL, DIV_19_8_26_MHZ_VAL, EXYNOS_DIV_11_8_26_MHZ_VAL }, 243 + { 48000000, FSEL_48_MHZ_VAL, DIV_19_8_48_MHZ_VAL, EXYNOS_DIV_11_8_48_MHZ_VAL }, 244 + }; 245 + 246 + static int exynos_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy) 247 + { 248 + const struct snps_eusb2_ref_clk *config = NULL; 249 + unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk); 250 + 251 + for (int i = 0; i < ARRAY_SIZE(exynos_eusb2_ref_clk); i++) { 252 + if (exynos_eusb2_ref_clk[i].freq == ref_clk_freq) { 253 + config = &exynos_eusb2_ref_clk[i]; 254 + break; 255 + } 256 + } 257 + 258 + if (!config) { 259 + dev_err(&phy->phy->dev, "unsupported ref_clk_freq:%lu\n", ref_clk_freq); 260 + return -EINVAL; 261 + } 262 + 263 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON, 264 + FSEL_MASK, 265 + FIELD_PREP(FSEL_MASK, config->fsel_val)); 266 + 267 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_CFG_PLLCFG0, 268 + PHY_CFG_PLL_FB_DIV_19_8_MASK, 269 + FIELD_PREP(PHY_CFG_PLL_FB_DIV_19_8_MASK, 270 + config->div_7_0_val)); 271 + 272 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_CFG_PLLCFG1, 273 + EXYNOS_PHY_CFG_PLL_FB_DIV_11_8_MASK, 274 + config->div_11_8_val); 275 + return 0; 276 + } 277 + 278 + static const struct snps_eusb2_ref_clk qcom_eusb2_ref_clk[] = { 279 + { 19200000, FSEL_19_2_MHZ_VAL, DIV_7_0_19_2_MHZ_VAL, DIV_11_8_19_2_MHZ_VAL }, 280 + { 38400000, FSEL_38_4_MHZ_VAL, DIV_7_0_38_4_MHZ_VAL, DIV_11_8_38_4_MHZ_VAL }, 281 + }; 282 + 283 + static int qcom_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy) 284 + { 285 + const struct snps_eusb2_ref_clk *config = NULL; 286 + unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk); 287 + 288 + for (int i = 0; i < ARRAY_SIZE(qcom_eusb2_ref_clk); i++) { 289 + if (qcom_eusb2_ref_clk[i].freq == ref_clk_freq) { 290 + config = &qcom_eusb2_ref_clk[i]; 291 + break; 292 + } 293 + } 294 + 295 + if (!config) { 296 + dev_err(&phy->phy->dev, "unsupported ref_clk_freq:%lu\n", ref_clk_freq); 297 + return -EINVAL; 298 + } 299 + 300 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, 301 + FSEL_MASK, 302 + FIELD_PREP(FSEL_MASK, config->fsel_val)); 303 + 304 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2, 305 + PHY_CFG_PLL_FB_DIV_7_0_MASK, 306 + config->div_7_0_val); 307 + 308 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3, 309 + PHY_CFG_PLL_FB_DIV_11_8_MASK, 310 + config->div_11_8_val); 311 + 312 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3, 313 + PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL); 314 + 315 + return 0; 316 + } 317 + 318 + static int exynos_snps_eusb2_hsphy_init(struct phy *p) 319 + { 320 + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); 321 + int ret; 322 + 323 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST, 324 + USB_PHY_RST_MASK | UTMI_PORT_RST_MASK, 325 + USB_PHY_RST_MASK | UTMI_PORT_RST_MASK); 326 + fsleep(50); /* required after holding phy in reset */ 327 + 328 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON, 329 + RPTR_MODE, RPTR_MODE); 330 + 331 + /* update ref_clk related registers */ 332 + ret = exynos_eusb2_ref_clk_init(phy); 333 + if (ret) 334 + return ret; 335 + 336 + /* default parameter: tx fsls-vref */ 337 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_PHY_CFG_TX, 338 + EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK, 339 + FIELD_PREP(EXYNOS_PHY_CFG_TX_FSLS_VREF_TUNE_MASK, 0x0)); 340 + 341 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_UTMI_TESTSE, 342 + TEST_IDDQ, 0); 343 + fsleep(10); /* required after releasing test_iddq */ 344 + 345 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST, 346 + USB_PHY_RST_MASK, 0); 347 + 348 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_COMMON, 349 + PHY_ENABLE, PHY_ENABLE); 350 + 351 + snps_eusb2_hsphy_write_mask(phy->base, EXYNOS_USB_PHY_HS_PHY_CTRL_RST, 352 + UTMI_PORT_RST_MASK, 0); 353 + 354 + return 0; 355 + } 356 + 357 + static const char * const exynos_eusb2_hsphy_clock_names[] = { 358 + "ref", "bus", "ctrl", 359 + }; 360 + 361 + static const struct snps_eusb2_phy_drvdata exynos2200_snps_eusb2_phy = { 362 + .phy_init = exynos_snps_eusb2_hsphy_init, 363 + .clk_names = exynos_eusb2_hsphy_clock_names, 364 + .num_clks = ARRAY_SIZE(exynos_eusb2_hsphy_clock_names), 365 + }; 366 + 367 + static int qcom_snps_eusb2_hsphy_init(struct phy *p) 368 + { 369 + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); 370 + int ret; 371 + 372 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG0, 373 + CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN); 374 + 375 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, POR); 376 + 377 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, 378 + PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN); 379 + 380 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_APB_ACCESS_CMD, 381 + APB_LOGIC_RESET, APB_LOGIC_RESET); 382 + 383 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0); 384 + 385 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_FSEL_SEL, 386 + FSEL_SEL, FSEL_SEL); 387 + 388 + /* update ref_clk related registers */ 389 + ret = qcom_eusb2_ref_clk_init(phy); 390 + if (ret) 391 + return ret; 392 + 393 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_1, 394 + PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 395 + FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1)); 396 + 397 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4, 398 + PHY_CFG_PLL_INT_CNTRL_MASK, 399 + FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8)); 400 + 401 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4, 402 + PHY_CFG_PLL_GMP_CNTRL_MASK, 403 + FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1)); 404 + 405 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5, 406 + PHY_CFG_PLL_PROP_CNTRL_MASK, 407 + FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10)); 408 + 409 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_6, 410 + PHY_CFG_PLL_VCO_CNTRL_MASK, 411 + FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0)); 412 + 413 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5, 414 + PHY_CFG_PLL_VREF_TUNE_MASK, 415 + FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1)); 416 + 417 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, 418 + VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL); 419 + 420 + /* set default parameters */ 421 + qcom_eusb2_default_parameters(phy); 422 + 423 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, 424 + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, 425 + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); 426 + 427 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM); 428 + 429 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, 430 + SIDDQ_SEL, SIDDQ_SEL); 431 + 432 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, 433 + SIDDQ, 0); 434 + 435 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, 0); 436 + 437 + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, 438 + USB2_SUSPEND_N_SEL, 0); 439 + 440 + return 0; 441 + } 442 + 443 + static const char * const qcom_eusb2_hsphy_clock_names[] = { 444 + "ref", 445 + }; 446 + 447 + static const struct snps_eusb2_phy_drvdata sm8550_snps_eusb2_phy = { 448 + .phy_init = qcom_snps_eusb2_hsphy_init, 449 + .clk_names = qcom_eusb2_hsphy_clock_names, 450 + .num_clks = ARRAY_SIZE(qcom_eusb2_hsphy_clock_names), 451 + }; 452 + 453 + static int snps_eusb2_hsphy_init(struct phy *p) 454 + { 455 + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); 456 + int ret; 457 + 458 + ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs); 459 + if (ret) 460 + return ret; 461 + 462 + ret = phy_init(phy->repeater); 463 + if (ret) { 464 + dev_err(&p->dev, "repeater init failed. %d\n", ret); 465 + goto disable_vreg; 466 + } 467 + 468 + ret = clk_bulk_prepare_enable(phy->data->num_clks, phy->clks); 469 + if (ret) { 470 + dev_err(&p->dev, "failed to enable ref clock, %d\n", ret); 471 + goto disable_vreg; 472 + } 473 + 474 + ret = reset_control_assert(phy->phy_reset); 475 + if (ret) { 476 + dev_err(&p->dev, "failed to assert phy_reset, %d\n", ret); 477 + goto disable_ref_clk; 478 + } 479 + 480 + usleep_range(100, 150); 481 + 482 + ret = reset_control_deassert(phy->phy_reset); 483 + if (ret) { 484 + dev_err(&p->dev, "failed to de-assert phy_reset, %d\n", ret); 485 + goto disable_ref_clk; 486 + } 487 + 488 + ret = phy->data->phy_init(p); 489 + if (ret) 490 + goto disable_ref_clk; 491 + 492 + return 0; 493 + 494 + disable_ref_clk: 495 + clk_bulk_disable_unprepare(phy->data->num_clks, phy->clks); 496 + 497 + disable_vreg: 498 + regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs); 499 + 500 + return ret; 501 + } 502 + 503 + static int snps_eusb2_hsphy_exit(struct phy *p) 504 + { 505 + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); 506 + 507 + clk_disable_unprepare(phy->ref_clk); 508 + 509 + regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs); 510 + 511 + phy_exit(phy->repeater); 512 + 513 + return 0; 514 + } 515 + 516 + static const struct phy_ops snps_eusb2_hsphy_ops = { 517 + .init = snps_eusb2_hsphy_init, 518 + .exit = snps_eusb2_hsphy_exit, 519 + .set_mode = snps_eusb2_hsphy_set_mode, 520 + .owner = THIS_MODULE, 521 + }; 522 + 523 + static int snps_eusb2_hsphy_probe(struct platform_device *pdev) 524 + { 525 + struct device *dev = &pdev->dev; 526 + struct device_node *np = dev->of_node; 527 + struct snps_eusb2_hsphy *phy; 528 + struct phy_provider *phy_provider; 529 + struct phy *generic_phy; 530 + int ret, i; 531 + int num; 532 + 533 + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 534 + if (!phy) 535 + return -ENOMEM; 536 + 537 + phy->data = device_get_match_data(dev); 538 + if (!phy->data) 539 + return -EINVAL; 540 + 541 + phy->base = devm_platform_ioremap_resource(pdev, 0); 542 + if (IS_ERR(phy->base)) 543 + return PTR_ERR(phy->base); 544 + 545 + phy->phy_reset = devm_reset_control_get_optional_exclusive(dev, NULL); 546 + if (IS_ERR(phy->phy_reset)) 547 + return PTR_ERR(phy->phy_reset); 548 + 549 + phy->clks = devm_kcalloc(dev, phy->data->num_clks, sizeof(*phy->clks), 550 + GFP_KERNEL); 551 + if (!phy->clks) 552 + return -ENOMEM; 553 + 554 + for (int i = 0; i < phy->data->num_clks; ++i) 555 + phy->clks[i].id = phy->data->clk_names[i]; 556 + 557 + ret = devm_clk_bulk_get(dev, phy->data->num_clks, phy->clks); 558 + if (ret) 559 + return dev_err_probe(dev, ret, 560 + "failed to get phy clock(s)\n"); 561 + 562 + phy->ref_clk = NULL; 563 + for (int i = 0; i < phy->data->num_clks; ++i) { 564 + if (!strcmp(phy->clks[i].id, "ref")) { 565 + phy->ref_clk = phy->clks[i].clk; 566 + break; 567 + } 568 + } 569 + 570 + if (IS_ERR_OR_NULL(phy->ref_clk)) 571 + return dev_err_probe(dev, PTR_ERR(phy->ref_clk), 572 + "failed to get ref clk\n"); 573 + 574 + num = ARRAY_SIZE(phy->vregs); 575 + for (i = 0; i < num; i++) 576 + phy->vregs[i].supply = eusb2_hsphy_vreg_names[i]; 577 + 578 + ret = devm_regulator_bulk_get(dev, num, phy->vregs); 579 + if (ret) 580 + return dev_err_probe(dev, ret, 581 + "failed to get regulator supplies\n"); 582 + 583 + phy->repeater = devm_of_phy_optional_get(dev, np, 0); 584 + if (IS_ERR(phy->repeater)) 585 + return dev_err_probe(dev, PTR_ERR(phy->repeater), 586 + "failed to get repeater\n"); 587 + 588 + generic_phy = devm_phy_create(dev, NULL, &snps_eusb2_hsphy_ops); 589 + if (IS_ERR(generic_phy)) { 590 + dev_err(dev, "failed to create phy %d\n", ret); 591 + return PTR_ERR(generic_phy); 592 + } 593 + 594 + dev_set_drvdata(dev, phy); 595 + phy_set_drvdata(generic_phy, phy); 596 + 597 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 598 + if (IS_ERR(phy_provider)) 599 + return PTR_ERR(phy_provider); 600 + 601 + dev_info(dev, "Registered Snps-eUSB2 phy\n"); 602 + 603 + return 0; 604 + } 605 + 606 + static const struct of_device_id snps_eusb2_hsphy_of_match_table[] = { 607 + { 608 + .compatible = "qcom,sm8550-snps-eusb2-phy", 609 + .data = &sm8550_snps_eusb2_phy, 610 + }, { 611 + .compatible = "samsung,exynos2200-eusb2-phy", 612 + .data = &exynos2200_snps_eusb2_phy, 613 + }, { }, 614 + }; 615 + MODULE_DEVICE_TABLE(of, snps_eusb2_hsphy_of_match_table); 616 + 617 + static struct platform_driver snps_eusb2_hsphy_driver = { 618 + .probe = snps_eusb2_hsphy_probe, 619 + .driver = { 620 + .name = "snps-eusb2-hsphy", 621 + .of_match_table = snps_eusb2_hsphy_of_match_table, 622 + }, 623 + }; 624 + 625 + module_platform_driver(snps_eusb2_hsphy_driver); 626 + MODULE_DESCRIPTION("Synopsys eUSB2 HS PHY driver"); 627 + MODULE_LICENSE("GPL");
-9
drivers/phy/qualcomm/Kconfig
··· 125 125 PHY which is usually paired with either the ChipIdea or Synopsys DWC3 126 126 USB IPs on MSM SOCs. 127 127 128 - config PHY_QCOM_SNPS_EUSB2 129 - tristate "Qualcomm SNPS eUSB2 PHY Driver" 130 - depends on OF && (ARCH_QCOM || COMPILE_TEST) 131 - select GENERIC_PHY 132 - help 133 - Enable support for the USB high-speed SNPS eUSB2 phy on Qualcomm 134 - chipsets. The PHY is paired with a Synopsys DWC3 USB controller 135 - on Qualcomm SOCs. 136 - 137 128 config PHY_QCOM_EUSB2_REPEATER 138 129 tristate "Qualcomm SNPS eUSB2 Repeater Driver" 139 130 depends on OF && (ARCH_QCOM || COMPILE_TEST)
-1
drivers/phy/qualcomm/Makefile
··· 15 15 obj-$(CONFIG_PHY_QCOM_QMP_USB_LEGACY) += phy-qcom-qmp-usb-legacy.o 16 16 17 17 obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o 18 - obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o 19 18 obj-$(CONFIG_PHY_QCOM_EUSB2_REPEATER) += phy-qcom-eusb2-repeater.o 20 19 obj-$(CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP) += phy-qcom-uniphy-pcie-28lp.o 21 20 obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
+65 -25
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
··· 3021 3021 3022 3022 bool skip_start_delay; 3023 3023 3024 - bool has_nocsr_reset; 3025 - 3026 3024 /* QMP PHY pipe clock interface rate */ 3027 3025 unsigned long pipe_clock_rate; 3028 3026 ··· 3033 3035 3034 3036 const struct qmp_phy_cfg *cfg; 3035 3037 bool tcsr_4ln_config; 3038 + bool skip_init; 3036 3039 3037 3040 void __iomem *serdes; 3038 3041 void __iomem *pcs; ··· 4019 4020 4020 4021 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4021 4022 .phy_status = PHYSTATUS_4_20, 4022 - .has_nocsr_reset = true, 4023 4023 4024 4024 /* 20MHz PHY AUX Clock */ 4025 4025 .aux_clock_rate = 20000000, ··· 4051 4053 4052 4054 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4053 4055 .phy_status = PHYSTATUS_4_20, 4054 - .has_nocsr_reset = true, 4055 4056 4056 4057 /* 20MHz PHY AUX Clock */ 4057 4058 .aux_clock_rate = 20000000, ··· 4170 4173 4171 4174 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4172 4175 .phy_status = PHYSTATUS_4_20, 4173 - .has_nocsr_reset = true, 4174 4176 }; 4175 4177 4176 4178 static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = { ··· 4203 4207 4204 4208 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4205 4209 .phy_status = PHYSTATUS_4_20, 4206 - .has_nocsr_reset = true, 4207 4210 }; 4208 4211 4209 4212 static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = { ··· 4228 4233 4229 4234 .reset_list = sdm845_pciephy_reset_l, 4230 4235 .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), 4231 - .vreg_list = sm8550_qmp_phy_vreg_l, 4232 - .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), 4236 + .vreg_list = qmp_phy_vreg_l, 4237 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 4233 4238 .regs = pciephy_v6_regs_layout, 4234 4239 4235 4240 .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, 4236 4241 .phy_status = PHYSTATUS_4_20, 4237 - .has_nocsr_reset = true, 4238 4242 }; 4239 4243 4240 4244 static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = { ··· 4331 4337 { 4332 4338 struct qmp_pcie *qmp = phy_get_drvdata(phy); 4333 4339 const struct qmp_phy_cfg *cfg = qmp->cfg; 4340 + void __iomem *pcs = qmp->pcs; 4341 + bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL])); 4334 4342 int ret; 4343 + 4344 + qmp->skip_init = qmp->nocsr_reset && phy_initialized; 4345 + /* 4346 + * We need to check the existence of init sequences in two cases: 4347 + * 1. The PHY doesn't support no_csr reset. 4348 + * 2. The PHY supports no_csr reset but isn't initialized by bootloader. 4349 + * As we can't skip init in these two cases. 4350 + */ 4351 + if (!qmp->skip_init && !cfg->tbls.serdes_num) { 4352 + dev_err(qmp->dev, "Init sequence not available\n"); 4353 + return -ENODATA; 4354 + } 4335 4355 4336 4356 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); 4337 4357 if (ret) { ··· 4353 4345 return ret; 4354 4346 } 4355 4347 4356 - ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4357 - if (ret) { 4358 - dev_err(qmp->dev, "reset assert failed\n"); 4359 - goto err_disable_regulators; 4348 + /* 4349 + * Toggle BCR reset for PHY that doesn't support no_csr reset or has not 4350 + * been initialized. 4351 + */ 4352 + if (!qmp->skip_init) { 4353 + ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4354 + if (ret) { 4355 + dev_err(qmp->dev, "reset assert failed\n"); 4356 + goto err_disable_regulators; 4357 + } 4360 4358 } 4361 4359 4362 4360 ret = reset_control_assert(qmp->nocsr_reset); ··· 4373 4359 4374 4360 usleep_range(200, 300); 4375 4361 4376 - ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); 4377 - if (ret) { 4378 - dev_err(qmp->dev, "reset deassert failed\n"); 4379 - goto err_assert_reset; 4362 + if (!qmp->skip_init) { 4363 + ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); 4364 + if (ret) { 4365 + dev_err(qmp->dev, "reset deassert failed\n"); 4366 + goto err_assert_reset; 4367 + } 4380 4368 } 4381 4369 4382 4370 ret = clk_bulk_prepare_enable(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks); ··· 4388 4372 return 0; 4389 4373 4390 4374 err_assert_reset: 4391 - reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4375 + if (!qmp->skip_init) 4376 + reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4392 4377 err_disable_regulators: 4393 4378 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); 4394 4379 ··· 4401 4384 struct qmp_pcie *qmp = phy_get_drvdata(phy); 4402 4385 const struct qmp_phy_cfg *cfg = qmp->cfg; 4403 4386 4404 - reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4387 + if (qmp->nocsr_reset) 4388 + reset_control_assert(qmp->nocsr_reset); 4389 + else 4390 + reset_control_bulk_assert(cfg->num_resets, qmp->resets); 4405 4391 4406 4392 clk_bulk_disable_unprepare(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks); 4407 4393 ··· 4423 4403 unsigned int mask, val; 4424 4404 int ret; 4425 4405 4406 + /* 4407 + * Write CSR register for PHY that doesn't support no_csr reset or has not 4408 + * been initialized. 4409 + */ 4410 + if (qmp->skip_init) 4411 + goto skip_tbls_init; 4412 + 4426 4413 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 4427 4414 cfg->pwrdn_ctrl); 4428 4415 ··· 4441 4414 qmp_pcie_init_registers(qmp, &cfg->tbls); 4442 4415 qmp_pcie_init_registers(qmp, mode_tbls); 4443 4416 4417 + skip_tbls_init: 4444 4418 ret = clk_bulk_prepare_enable(qmp->num_pipe_clks, qmp->pipe_clks); 4445 4419 if (ret) 4446 4420 return ret; ··· 4452 4424 goto err_disable_pipe_clk; 4453 4425 } 4454 4426 4427 + if (qmp->skip_init) 4428 + goto skip_serdes_start; 4429 + 4455 4430 /* Pull PHY out of reset state */ 4456 4431 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 4457 4432 ··· 4464 4433 if (!cfg->skip_start_delay) 4465 4434 usleep_range(1000, 1200); 4466 4435 4436 + skip_serdes_start: 4467 4437 status = pcs + cfg->regs[QPHY_PCS_STATUS]; 4468 4438 mask = cfg->phy_status; 4469 4439 ret = readl_poll_timeout(status, val, !(val & mask), 200, ··· 4489 4457 4490 4458 clk_bulk_disable_unprepare(qmp->num_pipe_clks, qmp->pipe_clks); 4491 4459 4460 + /* 4461 + * While powering off the PHY, only qmp->nocsr_reset needs to be checked. In 4462 + * this way, no matter whether the PHY settings were initially programmed by 4463 + * bootloader or PHY driver itself, we can reuse them when PHY is powered on 4464 + * next time. 4465 + */ 4466 + if (qmp->nocsr_reset) 4467 + goto skip_phy_deinit; 4468 + 4492 4469 /* PHY reset */ 4493 4470 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 4494 4471 ··· 4509 4468 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 4510 4469 cfg->pwrdn_ctrl); 4511 4470 4471 + skip_phy_deinit: 4512 4472 return 0; 4513 4473 } 4514 4474 ··· 4599 4557 if (ret) 4600 4558 return dev_err_probe(dev, ret, "failed to get resets\n"); 4601 4559 4602 - if (cfg->has_nocsr_reset) { 4603 - qmp->nocsr_reset = devm_reset_control_get_exclusive(dev, "phy_nocsr"); 4604 - if (IS_ERR(qmp->nocsr_reset)) 4605 - return dev_err_probe(dev, PTR_ERR(qmp->nocsr_reset), 4606 - "failed to get no-csr reset\n"); 4607 - } 4560 + qmp->nocsr_reset = devm_reset_control_get_optional_exclusive(dev, "phy_nocsr"); 4561 + if (IS_ERR(qmp->nocsr_reset)) 4562 + return dev_err_probe(dev, PTR_ERR(qmp->nocsr_reset), 4563 + "failed to get no-csr reset\n"); 4608 4564 4609 4565 return 0; 4610 4566 }
+5 -1
drivers/phy/qualcomm/phy-qcom-qmp-usb.c
··· 2106 2106 int index, bool exclusive) 2107 2107 { 2108 2108 struct resource res; 2109 + void __iomem *mem; 2109 2110 2110 2111 if (!exclusive) { 2111 2112 if (of_address_to_resource(np, index, &res)) 2112 2113 return IOMEM_ERR_PTR(-EINVAL); 2113 2114 2114 - return devm_ioremap(dev, res.start, resource_size(&res)); 2115 + mem = devm_ioremap(dev, res.start, resource_size(&res)); 2116 + if (!mem) 2117 + return IOMEM_ERR_PTR(-ENOMEM); 2118 + return mem; 2115 2119 } 2116 2120 2117 2121 return devm_of_iomap(dev, np, index, NULL);
+1 -26
drivers/phy/qualcomm/phy-qcom-qusb2.c
··· 151 151 QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9F), 152 152 }; 153 153 154 - static const struct qusb2_phy_init_tbl ipq5424_init_tbl[] = { 155 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL, 0x14), 156 - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x00), 157 - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53), 158 - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc3), 159 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30), 160 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79), 161 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21), 162 - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x00), 163 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00), 164 - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14), 165 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TEST, 0x80), 166 - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f), 167 - }; 168 - 169 154 static const struct qusb2_phy_init_tbl qcs615_init_tbl[] = { 170 155 QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xc8), 171 156 QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3), ··· 341 356 .disable_ctrl = POWER_DOWN, 342 357 .mask_core_ready = PLL_LOCKED, 343 358 /* autoresume not used */ 344 - .autoresume_en = BIT(0), 345 - }; 346 - 347 - static const struct qusb2_phy_cfg ipq5424_phy_cfg = { 348 - .tbl = ipq5424_init_tbl, 349 - .tbl_num = ARRAY_SIZE(ipq5424_init_tbl), 350 - .regs = ipq6018_regs_layout, 351 - 352 - .disable_ctrl = POWER_DOWN, 353 - .mask_core_ready = PLL_LOCKED, 354 359 .autoresume_en = BIT(0), 355 360 }; 356 361 ··· 930 955 static const struct of_device_id qusb2_phy_of_match_table[] = { 931 956 { 932 957 .compatible = "qcom,ipq5424-qusb2-phy", 933 - .data = &ipq5424_phy_cfg, 958 + .data = &ipq6018_phy_cfg, 934 959 }, { 935 960 .compatible = "qcom,ipq6018-qusb2-phy", 936 961 .data = &ipq6018_phy_cfg,
-442
drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Copyright (c) 2023, Linaro Limited 4 - */ 5 - 6 - #include <linux/bitfield.h> 7 - #include <linux/clk.h> 8 - #include <linux/delay.h> 9 - #include <linux/iopoll.h> 10 - #include <linux/mod_devicetable.h> 11 - #include <linux/phy/phy.h> 12 - #include <linux/platform_device.h> 13 - #include <linux/regulator/consumer.h> 14 - #include <linux/reset.h> 15 - 16 - #define USB_PHY_UTMI_CTRL0 (0x3c) 17 - #define SLEEPM BIT(0) 18 - #define OPMODE_MASK GENMASK(4, 3) 19 - #define OPMODE_NONDRIVING BIT(3) 20 - 21 - #define USB_PHY_UTMI_CTRL5 (0x50) 22 - #define POR BIT(1) 23 - 24 - #define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) 25 - #define PHY_ENABLE BIT(0) 26 - #define SIDDQ_SEL BIT(1) 27 - #define SIDDQ BIT(2) 28 - #define RETENABLEN BIT(3) 29 - #define FSEL_MASK GENMASK(6, 4) 30 - #define FSEL_19_2_MHZ_VAL (0x0) 31 - #define FSEL_38_4_MHZ_VAL (0x4) 32 - 33 - #define USB_PHY_CFG_CTRL_1 (0x58) 34 - #define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1) 35 - 36 - #define USB_PHY_CFG_CTRL_2 (0x5c) 37 - #define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0) 38 - #define DIV_7_0_19_2_MHZ_VAL (0x90) 39 - #define DIV_7_0_38_4_MHZ_VAL (0xc8) 40 - 41 - #define USB_PHY_CFG_CTRL_3 (0x60) 42 - #define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0) 43 - #define DIV_11_8_19_2_MHZ_VAL (0x1) 44 - #define DIV_11_8_38_4_MHZ_VAL (0x0) 45 - 46 - #define PHY_CFG_PLL_REF_DIV GENMASK(7, 4) 47 - #define PLL_REF_DIV_VAL (0x0) 48 - 49 - #define USB_PHY_HS_PHY_CTRL2 (0x64) 50 - #define VBUSVLDEXT0 BIT(0) 51 - #define USB2_SUSPEND_N BIT(2) 52 - #define USB2_SUSPEND_N_SEL BIT(3) 53 - #define VBUS_DET_EXT_SEL BIT(4) 54 - 55 - #define USB_PHY_CFG_CTRL_4 (0x68) 56 - #define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0) 57 - #define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2) 58 - 59 - #define USB_PHY_CFG_CTRL_5 (0x6c) 60 - #define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0) 61 - #define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6) 62 - 63 - #define USB_PHY_CFG_CTRL_6 (0x70) 64 - #define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0) 65 - 66 - #define USB_PHY_CFG_CTRL_7 (0x74) 67 - 68 - #define USB_PHY_CFG_CTRL_8 (0x78) 69 - #define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0) 70 - #define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2) 71 - #define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3) 72 - #define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6) 73 - 74 - #define USB_PHY_CFG_CTRL_9 (0x7c) 75 - #define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0) 76 - #define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3) 77 - #define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5) 78 - #define PHY_CFG_RCAL_BYPASS BIT(7) 79 - 80 - #define USB_PHY_CFG_CTRL_10 (0x80) 81 - 82 - #define USB_PHY_CFG0 (0x94) 83 - #define DATAPATH_CTRL_OVERRIDE_EN BIT(0) 84 - #define CMN_CTRL_OVERRIDE_EN BIT(1) 85 - 86 - #define UTMI_PHY_CMN_CTRL0 (0x98) 87 - #define TESTBURNIN BIT(6) 88 - 89 - #define USB_PHY_FSEL_SEL (0xb8) 90 - #define FSEL_SEL BIT(0) 91 - 92 - #define USB_PHY_APB_ACCESS_CMD (0x130) 93 - #define RW_ACCESS BIT(0) 94 - #define APB_START_CMD BIT(1) 95 - #define APB_LOGIC_RESET BIT(2) 96 - 97 - #define USB_PHY_APB_ACCESS_STATUS (0x134) 98 - #define ACCESS_DONE BIT(0) 99 - #define TIMED_OUT BIT(1) 100 - #define ACCESS_ERROR BIT(2) 101 - #define ACCESS_IN_PROGRESS BIT(3) 102 - 103 - #define USB_PHY_APB_ADDRESS (0x138) 104 - #define APB_REG_ADDR_MASK GENMASK(7, 0) 105 - 106 - #define USB_PHY_APB_WRDATA_LSB (0x13c) 107 - #define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0) 108 - 109 - #define USB_PHY_APB_WRDATA_MSB (0x140) 110 - #define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4) 111 - 112 - #define USB_PHY_APB_RDDATA_LSB (0x144) 113 - #define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0) 114 - 115 - #define USB_PHY_APB_RDDATA_MSB (0x148) 116 - #define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4) 117 - 118 - static const char * const eusb2_hsphy_vreg_names[] = { 119 - "vdd", "vdda12", 120 - }; 121 - 122 - #define EUSB2_NUM_VREGS ARRAY_SIZE(eusb2_hsphy_vreg_names) 123 - 124 - struct qcom_snps_eusb2_hsphy { 125 - struct phy *phy; 126 - void __iomem *base; 127 - 128 - struct clk *ref_clk; 129 - struct reset_control *phy_reset; 130 - 131 - struct regulator_bulk_data vregs[EUSB2_NUM_VREGS]; 132 - 133 - enum phy_mode mode; 134 - 135 - struct phy *repeater; 136 - }; 137 - 138 - static int qcom_snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode) 139 - { 140 - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); 141 - 142 - phy->mode = mode; 143 - 144 - return phy_set_mode_ext(phy->repeater, mode, submode); 145 - } 146 - 147 - static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset, 148 - u32 mask, u32 val) 149 - { 150 - u32 reg; 151 - 152 - reg = readl_relaxed(base + offset); 153 - reg &= ~mask; 154 - reg |= val & mask; 155 - writel_relaxed(reg, base + offset); 156 - 157 - /* Ensure above write is completed */ 158 - readl_relaxed(base + offset); 159 - } 160 - 161 - static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_hsphy *phy) 162 - { 163 - /* default parameters: tx pre-emphasis */ 164 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, 165 - PHY_CFG_TX_PREEMP_TUNE_MASK, 166 - FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0)); 167 - 168 - /* tx rise/fall time */ 169 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, 170 - PHY_CFG_TX_RISE_TUNE_MASK, 171 - FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2)); 172 - 173 - /* source impedance adjustment */ 174 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, 175 - PHY_CFG_TX_RES_TUNE_MASK, 176 - FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1)); 177 - 178 - /* dc voltage level adjustement */ 179 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8, 180 - PHY_CFG_TX_HS_VREF_TUNE_MASK, 181 - FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3)); 182 - 183 - /* transmitter HS crossover adjustement */ 184 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8, 185 - PHY_CFG_TX_HS_XV_TUNE_MASK, 186 - FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0)); 187 - } 188 - 189 - static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy) 190 - { 191 - unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk); 192 - 193 - switch (ref_clk_freq) { 194 - case 19200000: 195 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, 196 - FSEL_MASK, 197 - FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL)); 198 - 199 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2, 200 - PHY_CFG_PLL_FB_DIV_7_0_MASK, 201 - DIV_7_0_19_2_MHZ_VAL); 202 - 203 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, 204 - PHY_CFG_PLL_FB_DIV_11_8_MASK, 205 - DIV_11_8_19_2_MHZ_VAL); 206 - break; 207 - 208 - case 38400000: 209 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, 210 - FSEL_MASK, 211 - FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL)); 212 - 213 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2, 214 - PHY_CFG_PLL_FB_DIV_7_0_MASK, 215 - DIV_7_0_38_4_MHZ_VAL); 216 - 217 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, 218 - PHY_CFG_PLL_FB_DIV_11_8_MASK, 219 - DIV_11_8_38_4_MHZ_VAL); 220 - break; 221 - 222 - default: 223 - dev_err(&phy->phy->dev, "unsupported ref_clk_freq:%lu\n", ref_clk_freq); 224 - return -EINVAL; 225 - } 226 - 227 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, 228 - PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL); 229 - 230 - return 0; 231 - } 232 - 233 - static int qcom_snps_eusb2_hsphy_init(struct phy *p) 234 - { 235 - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); 236 - int ret; 237 - 238 - ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs); 239 - if (ret) 240 - return ret; 241 - 242 - ret = phy_init(phy->repeater); 243 - if (ret) { 244 - dev_err(&p->dev, "repeater init failed. %d\n", ret); 245 - goto disable_vreg; 246 - } 247 - 248 - ret = clk_prepare_enable(phy->ref_clk); 249 - if (ret) { 250 - dev_err(&p->dev, "failed to enable ref clock, %d\n", ret); 251 - goto disable_vreg; 252 - } 253 - 254 - ret = reset_control_assert(phy->phy_reset); 255 - if (ret) { 256 - dev_err(&p->dev, "failed to assert phy_reset, %d\n", ret); 257 - goto disable_ref_clk; 258 - } 259 - 260 - usleep_range(100, 150); 261 - 262 - ret = reset_control_deassert(phy->phy_reset); 263 - if (ret) { 264 - dev_err(&p->dev, "failed to de-assert phy_reset, %d\n", ret); 265 - goto disable_ref_clk; 266 - } 267 - 268 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG0, 269 - CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN); 270 - 271 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, POR); 272 - 273 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, 274 - PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN); 275 - 276 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_APB_ACCESS_CMD, 277 - APB_LOGIC_RESET, APB_LOGIC_RESET); 278 - 279 - qcom_snps_eusb2_hsphy_write_mask(phy->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0); 280 - 281 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_FSEL_SEL, 282 - FSEL_SEL, FSEL_SEL); 283 - 284 - /* update ref_clk related registers */ 285 - ret = qcom_eusb2_ref_clk_init(phy); 286 - if (ret) 287 - goto disable_ref_clk; 288 - 289 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_1, 290 - PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 291 - FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1)); 292 - 293 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4, 294 - PHY_CFG_PLL_INT_CNTRL_MASK, 295 - FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8)); 296 - 297 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4, 298 - PHY_CFG_PLL_GMP_CNTRL_MASK, 299 - FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1)); 300 - 301 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5, 302 - PHY_CFG_PLL_PROP_CNTRL_MASK, 303 - FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10)); 304 - 305 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_6, 306 - PHY_CFG_PLL_VCO_CNTRL_MASK, 307 - FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0)); 308 - 309 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5, 310 - PHY_CFG_PLL_VREF_TUNE_MASK, 311 - FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1)); 312 - 313 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, 314 - VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL); 315 - 316 - /* set default parameters */ 317 - qcom_eusb2_default_parameters(phy); 318 - 319 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, 320 - USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, 321 - USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); 322 - 323 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM); 324 - 325 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, 326 - SIDDQ_SEL, SIDDQ_SEL); 327 - 328 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, 329 - SIDDQ, 0); 330 - 331 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, 0); 332 - 333 - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, 334 - USB2_SUSPEND_N_SEL, 0); 335 - 336 - return 0; 337 - 338 - disable_ref_clk: 339 - clk_disable_unprepare(phy->ref_clk); 340 - 341 - disable_vreg: 342 - regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs); 343 - 344 - return ret; 345 - } 346 - 347 - static int qcom_snps_eusb2_hsphy_exit(struct phy *p) 348 - { 349 - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); 350 - 351 - clk_disable_unprepare(phy->ref_clk); 352 - 353 - regulator_bulk_disable(ARRAY_SIZE(phy->vregs), phy->vregs); 354 - 355 - phy_exit(phy->repeater); 356 - 357 - return 0; 358 - } 359 - 360 - static const struct phy_ops qcom_snps_eusb2_hsphy_ops = { 361 - .init = qcom_snps_eusb2_hsphy_init, 362 - .exit = qcom_snps_eusb2_hsphy_exit, 363 - .set_mode = qcom_snps_eusb2_hsphy_set_mode, 364 - .owner = THIS_MODULE, 365 - }; 366 - 367 - static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev) 368 - { 369 - struct device *dev = &pdev->dev; 370 - struct device_node *np = dev->of_node; 371 - struct qcom_snps_eusb2_hsphy *phy; 372 - struct phy_provider *phy_provider; 373 - struct phy *generic_phy; 374 - int ret, i; 375 - int num; 376 - 377 - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 378 - if (!phy) 379 - return -ENOMEM; 380 - 381 - phy->base = devm_platform_ioremap_resource(pdev, 0); 382 - if (IS_ERR(phy->base)) 383 - return PTR_ERR(phy->base); 384 - 385 - phy->phy_reset = devm_reset_control_get_exclusive(dev, NULL); 386 - if (IS_ERR(phy->phy_reset)) 387 - return PTR_ERR(phy->phy_reset); 388 - 389 - phy->ref_clk = devm_clk_get(dev, "ref"); 390 - if (IS_ERR(phy->ref_clk)) 391 - return dev_err_probe(dev, PTR_ERR(phy->ref_clk), 392 - "failed to get ref clk\n"); 393 - 394 - num = ARRAY_SIZE(phy->vregs); 395 - for (i = 0; i < num; i++) 396 - phy->vregs[i].supply = eusb2_hsphy_vreg_names[i]; 397 - 398 - ret = devm_regulator_bulk_get(dev, num, phy->vregs); 399 - if (ret) 400 - return dev_err_probe(dev, ret, 401 - "failed to get regulator supplies\n"); 402 - 403 - phy->repeater = devm_of_phy_get_by_index(dev, np, 0); 404 - if (IS_ERR(phy->repeater)) 405 - return dev_err_probe(dev, PTR_ERR(phy->repeater), 406 - "failed to get repeater\n"); 407 - 408 - generic_phy = devm_phy_create(dev, NULL, &qcom_snps_eusb2_hsphy_ops); 409 - if (IS_ERR(generic_phy)) { 410 - dev_err(dev, "failed to create phy %d\n", ret); 411 - return PTR_ERR(generic_phy); 412 - } 413 - 414 - dev_set_drvdata(dev, phy); 415 - phy_set_drvdata(generic_phy, phy); 416 - 417 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 418 - if (IS_ERR(phy_provider)) 419 - return PTR_ERR(phy_provider); 420 - 421 - dev_info(dev, "Registered Qcom-eUSB2 phy\n"); 422 - 423 - return 0; 424 - } 425 - 426 - static const struct of_device_id qcom_snps_eusb2_hsphy_of_match_table[] = { 427 - { .compatible = "qcom,sm8550-snps-eusb2-phy", }, 428 - { }, 429 - }; 430 - MODULE_DEVICE_TABLE(of, qcom_snps_eusb2_hsphy_of_match_table); 431 - 432 - static struct platform_driver qcom_snps_eusb2_hsphy_driver = { 433 - .probe = qcom_snps_eusb2_hsphy_probe, 434 - .driver = { 435 - .name = "qcom-snps-eusb2-hsphy", 436 - .of_match_table = qcom_snps_eusb2_hsphy_of_match_table, 437 - }, 438 - }; 439 - 440 - module_platform_driver(qcom_snps_eusb2_hsphy_driver); 441 - MODULE_DESCRIPTION("Qualcomm SNPS eUSB2 HS PHY driver"); 442 - MODULE_LICENSE("GPL");
+45
drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
··· 75 75 76 76 #define phy_to_dw_phy(x) container_of((x), struct qca_uni_pcie_phy, phy) 77 77 78 + static const struct qcom_uniphy_pcie_regs ipq5018_regs[] = { 79 + { 80 + .offset = SSCG_CTRL_REG_4, 81 + .val = 0x1cb9, 82 + }, { 83 + .offset = SSCG_CTRL_REG_5, 84 + .val = 0x023a, 85 + }, { 86 + .offset = SSCG_CTRL_REG_3, 87 + .val = 0xd360, 88 + }, { 89 + .offset = SSCG_CTRL_REG_1, 90 + .val = 0x1, 91 + }, { 92 + .offset = SSCG_CTRL_REG_2, 93 + .val = 0xeb, 94 + }, { 95 + .offset = CDR_CTRL_REG_4, 96 + .val = 0x3f9, 97 + }, { 98 + .offset = CDR_CTRL_REG_5, 99 + .val = 0x1c9, 100 + }, { 101 + .offset = CDR_CTRL_REG_2, 102 + .val = 0x419, 103 + }, { 104 + .offset = CDR_CTRL_REG_1, 105 + .val = 0x200, 106 + }, { 107 + .offset = PCS_INTERNAL_CONTROL_2, 108 + .val = 0xf101, 109 + }, 110 + }; 111 + 78 112 static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = { 79 113 { 80 114 .offset = PHY_CFG_PLLCFG, ··· 120 86 .offset = PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME, 121 87 .val = 0xcf, 122 88 }, 89 + }; 90 + 91 + static const struct qcom_uniphy_pcie_data ipq5018_data = { 92 + .lane_offset = 0x800, 93 + .phy_type = PHY_TYPE_PCIE_GEN2, 94 + .init_seq = ipq5018_regs, 95 + .init_seq_num = ARRAY_SIZE(ipq5018_regs), 96 + .pipe_clk_rate = 125 * MEGA, 123 97 }; 124 98 125 99 static const struct qcom_uniphy_pcie_data ipq5332_data = { ··· 254 212 255 213 static const struct of_device_id qcom_uniphy_pcie_id_table[] = { 256 214 { 215 + .compatible = "qcom,ipq5018-uniphy-pcie-phy", 216 + .data = &ipq5018_data, 217 + }, { 257 218 .compatible = "qcom,ipq5332-uniphy-pcie-phy", 258 219 .data = &ipq5332_data, 259 220 }, {
+34 -4
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 29 29 #define USB2_INT_ENABLE 0x000 30 30 #define USB2_AHB_BUS_CTR 0x008 31 31 #define USB2_USBCTR 0x00c 32 + #define USB2_REGEN_CG_CTRL 0x104 /* RZ/V2H(P) only */ 32 33 #define USB2_SPD_RSM_TIMSET 0x10c 33 34 #define USB2_OC_TIMSET 0x110 35 + #define USB2_UTMI_CTRL 0x118 /* RZ/V2H(P) only */ 34 36 #define USB2_COMMCTRL 0x600 35 37 #define USB2_OBINTSTA 0x604 36 38 #define USB2_OBINTEN 0x608 ··· 53 51 #define USB2_USBCTR_DIRPD BIT(2) 54 52 #define USB2_USBCTR_PLL_RST BIT(1) 55 53 54 + /* REGEN_CG_CTRL*/ 55 + #define USB2_REGEN_CG_CTRL_UPHY_WEN BIT(0) 56 + 56 57 /* SPD_RSM_TIMSET */ 57 58 #define USB2_SPD_RSM_TIMSET_INIT 0x014e029b 58 59 59 60 /* OC_TIMSET */ 60 61 #define USB2_OC_TIMSET_INIT 0x000209ab 62 + 63 + /* UTMI_CTRL */ 64 + #define USB2_UTMI_CTRL_INIT 0x8000018f 61 65 62 66 /* COMMCTRL */ 63 67 #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ ··· 134 126 bool is_otg_channel; 135 127 bool uses_otg_pins; 136 128 bool soc_no_adp_ctrl; 129 + bool utmi_ctrl; 137 130 }; 138 131 139 132 struct rcar_gen3_phy_drv_data { 140 133 const struct phy_ops *phy_usb2_ops; 141 134 bool no_adp_ctrl; 142 135 bool init_bus; 136 + bool utmi_ctrl; 143 137 }; 144 138 145 139 /* ··· 487 477 if (rphy->int_enable_bits) 488 478 rcar_gen3_init_otg(channel); 489 479 480 + if (channel->utmi_ctrl) { 481 + val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN; 482 + writel(val, usb2_base + USB2_REGEN_CG_CTRL); 483 + 484 + writel(USB2_UTMI_CTRL_INIT, usb2_base + USB2_UTMI_CTRL); 485 + writel(val & ~USB2_REGEN_CG_CTRL_UPHY_WEN, usb2_base + USB2_REGEN_CG_CTRL); 486 + } 487 + 490 488 rphy->initialized = true; 491 489 492 490 return 0; ··· 610 592 .init_bus = true, 611 593 }; 612 594 595 + static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = { 596 + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 597 + .no_adp_ctrl = true, 598 + .utmi_ctrl = true, 599 + }; 600 + 613 601 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { 614 602 { 615 603 .compatible = "renesas,usb2-phy-r8a77470", ··· 634 610 .data = &rcar_gen3_phy_usb2_data, 635 611 }, 636 612 { 637 - .compatible = "renesas,rzg2l-usb2-phy", 638 - .data = &rz_g2l_phy_usb2_data, 639 - }, 640 - { 641 613 .compatible = "renesas,usb2-phy-r9a08g045", 642 614 .data = &rz_g3s_phy_usb2_data, 615 + }, 616 + { 617 + .compatible = "renesas,usb2-phy-r9a09g057", 618 + .data = &rz_v2h_phy_usb2_data, 619 + }, 620 + { 621 + .compatible = "renesas,rzg2l-usb2-phy", 622 + .data = &rz_g2l_phy_usb2_data, 643 623 }, 644 624 { 645 625 .compatible = "renesas,rcar-gen3-usb2-phy", ··· 791 763 channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; 792 764 if (phy_data->no_adp_ctrl) 793 765 channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; 766 + 767 + channel->utmi_ctrl = phy_data->utmi_ctrl; 794 768 795 769 spin_lock_init(&channel->lock); 796 770 for (i = 0; i < NUM_OF_PHYS; i++) {
+81
drivers/phy/rockchip/phy-rockchip-inno-usb2.c
··· 1583 1583 return ret; 1584 1584 } 1585 1585 1586 + static const struct rockchip_usb2phy_cfg rk3036_phy_cfgs[] = { 1587 + { 1588 + .reg = 0x17c, 1589 + .num_ports = 2, 1590 + .phy_tuning = rk3128_usb2phy_tuning, 1591 + .clkout_ctl = { 0x017c, 11, 11, 1, 0 }, 1592 + .port_cfgs = { 1593 + [USB2PHY_PORT_OTG] = { 1594 + .phy_sus = { 0x017c, 8, 0, 0, 0x1d1 }, 1595 + .bvalid_det_en = { 0x017c, 14, 14, 0, 1 }, 1596 + .bvalid_det_st = { 0x017c, 15, 15, 0, 1 }, 1597 + .bvalid_det_clr = { 0x017c, 15, 15, 0, 1 }, 1598 + .ls_det_en = { 0x017c, 12, 12, 0, 1 }, 1599 + .ls_det_st = { 0x017c, 13, 13, 0, 1 }, 1600 + .ls_det_clr = { 0x017c, 13, 13, 0, 1 }, 1601 + .utmi_bvalid = { 0x014c, 8, 8, 0, 1 }, 1602 + .utmi_id = { 0x014c, 11, 11, 0, 1 }, 1603 + .utmi_ls = { 0x014c, 10, 9, 0, 1 }, 1604 + 1605 + }, 1606 + [USB2PHY_PORT_HOST] = { 1607 + .phy_sus = { 0x0194, 8, 0, 0, 0x1d1 }, 1608 + .ls_det_en = { 0x0194, 14, 14, 0, 1 }, 1609 + .ls_det_st = { 0x0194, 15, 15, 0, 1 }, 1610 + .ls_det_clr = { 0x0194, 15, 15, 0, 1 } 1611 + } 1612 + }, 1613 + }, 1614 + { /* sentinel */ } 1615 + }; 1616 + 1586 1617 static const struct rockchip_usb2phy_cfg rk3128_phy_cfgs[] = { 1587 1618 { 1588 1619 .reg = 0x17c, ··· 1918 1887 .utmi_ls = { 0xe2ac, 26, 25, 0, 1 }, 1919 1888 .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 } 1920 1889 } 1890 + }, 1891 + }, 1892 + { /* sentinel */ } 1893 + }; 1894 + 1895 + static const struct rockchip_usb2phy_cfg rk3562_phy_cfgs[] = { 1896 + { 1897 + .reg = 0xff740000, 1898 + .num_ports = 2, 1899 + .clkout_ctl = { 0x0108, 4, 4, 1, 0 }, 1900 + .port_cfgs = { 1901 + [USB2PHY_PORT_OTG] = { 1902 + .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, 1903 + .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, 1904 + .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, 1905 + .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, 1906 + .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, 1907 + .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, 1908 + .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, 1909 + .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, 1910 + .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, 1911 + .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, 1912 + .ls_det_en = { 0x0110, 0, 0, 0, 1 }, 1913 + .ls_det_st = { 0x0114, 0, 0, 0, 1 }, 1914 + .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, 1915 + .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, 1916 + .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, 1917 + .utmi_ls = { 0x0120, 5, 4, 0, 1 }, 1918 + }, 1919 + [USB2PHY_PORT_HOST] = { 1920 + .phy_sus = { 0x0104, 8, 0, 0x1d2, 0x1d1 }, 1921 + .ls_det_en = { 0x0110, 1, 1, 0, 1 }, 1922 + .ls_det_st = { 0x0114, 1, 1, 0, 1 }, 1923 + .ls_det_clr = { 0x0118, 1, 1, 0, 1 }, 1924 + .utmi_ls = { 0x0120, 17, 16, 0, 1 }, 1925 + .utmi_hstdet = { 0x0120, 19, 19, 0, 1 } 1926 + } 1927 + }, 1928 + .chg_det = { 1929 + .cp_det = { 0x0120, 24, 24, 0, 1 }, 1930 + .dcp_det = { 0x0120, 23, 23, 0, 1 }, 1931 + .dp_det = { 0x0120, 25, 25, 0, 1 }, 1932 + .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, 1933 + .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, 1934 + .idp_src_en = { 0x0108, 9, 9, 0, 1 }, 1935 + .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, 1936 + .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, 1937 + .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, 1921 1938 }, 1922 1939 }, 1923 1940 { /* sentinel */ } ··· 2283 2204 2284 2205 static const struct of_device_id rockchip_usb2phy_dt_match[] = { 2285 2206 { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs }, 2207 + { .compatible = "rockchip,rk3036-usb2phy", .data = &rk3036_phy_cfgs }, 2286 2208 { .compatible = "rockchip,rk3128-usb2phy", .data = &rk3128_phy_cfgs }, 2287 2209 { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs }, 2288 2210 { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs }, 2289 2211 { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, 2290 2212 { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, 2291 2213 { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, 2214 + { .compatible = "rockchip,rk3562-usb2phy", .data = &rk3562_phy_cfgs }, 2292 2215 { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, 2293 2216 { .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs }, 2294 2217 { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
+176 -118
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
··· 320 320 #define LN3_TX_SER_RATE_SEL_HBR2_MASK BIT(3) 321 321 #define LN3_TX_SER_RATE_SEL_HBR3_MASK BIT(2) 322 322 323 + #define HDMI14_MAX_RATE 340000000 323 324 #define HDMI20_MAX_RATE 600000000 324 325 325 326 enum dp_link_rate { ··· 329 328 DP_BW_HBR2, 330 329 }; 331 330 332 - struct lcpll_config { 333 - u32 bit_rate; 334 - u8 lcvco_mode_en; 335 - u8 pi_en; 336 - u8 clk_en_100m; 337 - u8 pms_mdiv; 338 - u8 pms_mdiv_afc; 339 - u8 pms_pdiv; 340 - u8 pms_refdiv; 341 - u8 pms_sdiv; 342 - u8 pi_cdiv_rstn; 343 - u8 pi_cdiv_sel; 344 - u8 sdm_en; 345 - u8 sdm_rstn; 346 - u8 sdc_frac_en; 347 - u8 sdc_rstn; 348 - u8 sdm_deno; 349 - u8 sdm_num_sign; 350 - u8 sdm_num; 351 - u8 sdc_n; 352 - u8 sdc_n2; 353 - u8 sdc_num; 354 - u8 sdc_deno; 355 - u8 sdc_ndiv_rstn; 356 - u8 ssc_en; 357 - u8 ssc_fm_dev; 358 - u8 ssc_fm_freq; 359 - u8 ssc_clk_div_sel; 360 - u8 cd_tx_ser_rate_sel; 361 - }; 362 - 363 331 struct ropll_config { 364 - u32 bit_rate; 332 + unsigned long long rate; 365 333 u8 pms_mdiv; 366 334 u8 pms_mdiv_afc; 367 335 u8 pms_pdiv; ··· 392 422 struct regmap *regmap; 393 423 struct regmap *grf; 394 424 395 - /* PHY const config */ 396 - const struct rk_hdptx_phy_cfg *cfgs; 397 425 int phy_id; 398 - 399 426 struct phy *phy; 400 - struct phy_config *phy_cfg; 427 + struct phy_configure_opts_hdmi hdmi_cfg; 401 428 struct clk_bulk_data *clks; 402 429 int nr_clks; 403 430 struct reset_control_bulk_data rsts[RST_MAX]; 404 431 405 432 /* clk provider */ 406 433 struct clk_hw hw; 407 - unsigned long rate; 434 + unsigned long hw_rate; 435 + bool restrict_rate_change; 408 436 409 437 atomic_t usage_count; 410 438 ··· 412 444 }; 413 445 414 446 static const struct ropll_config ropll_tmds_cfg[] = { 415 - { 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 447 + { 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 416 448 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 417 - { 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 449 + { 371250000ULL, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 418 450 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 419 - { 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 451 + { 297000000ULL, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 420 452 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 421 - { 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10, 453 + { 162000000ULL, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10, 422 454 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 423 - { 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 455 + { 185625000ULL, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 424 456 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 425 - { 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1, 457 + { 154000000ULL, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1, 426 458 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 427 - { 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5, 459 + { 148500000ULL, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5, 428 460 0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 429 - { 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1, 461 + { 146250000ULL, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1, 430 462 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 431 - { 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1, 463 + { 119000000ULL, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1, 432 464 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 433 - { 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1, 465 + { 106500000ULL, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1, 434 466 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 435 - { 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 467 + { 108000000ULL, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 436 468 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 437 - { 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1, 469 + { 85500000ULL, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1, 438 470 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 439 - { 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0, 471 + { 83500000ULL, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0, 440 472 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 441 - { 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 473 + { 92812500ULL, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 442 474 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 443 - { 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 475 + { 74250000ULL, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, 444 476 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 445 - { 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1, 477 + { 65000000ULL, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1, 446 478 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 447 - { 502500, 84, 84, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 11, 1, 4, 5, 479 + { 50250000ULL, 84, 84, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 11, 1, 4, 5, 448 480 4, 11, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 449 - { 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5, 481 + { 33750000ULL, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5, 450 482 1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 451 - { 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 483 + { 40000000ULL, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 452 484 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 453 - { 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 485 + { 27000000ULL, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, 454 486 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 455 - { 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1, 487 + { 25175000ULL, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1, 456 488 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, 457 489 }; 458 490 ··· 898 930 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); 899 931 } 900 932 901 - static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate, 933 + static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate, 902 934 struct ropll_config *cfg) 903 935 { 904 - const unsigned int fout = data_rate / 2, fref = 24000; 936 + const unsigned int fout = div_u64(rate, 200), fref = 24000; 905 937 unsigned long k = 0, lc, k_sub, lc_sub; 906 938 unsigned int fvco, sdc; 907 939 u32 mdiv, sdiv, n = 8; ··· 970 1002 return true; 971 1003 } 972 1004 973 - static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx, 974 - unsigned int rate) 1005 + static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) 975 1006 { 976 1007 const struct ropll_config *cfg = NULL; 977 1008 struct ropll_config rc = {0}; 978 - int i; 1009 + int ret, i; 979 1010 980 - hdptx->rate = rate * 100; 1011 + if (!hdptx->hdmi_cfg.tmds_char_rate) 1012 + return 0; 981 1013 982 1014 for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) 983 - if (rate == ropll_tmds_cfg[i].bit_rate) { 1015 + if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) { 984 1016 cfg = &ropll_tmds_cfg[i]; 985 1017 break; 986 1018 } 987 1019 988 1020 if (!cfg) { 989 - if (rk_hdptx_phy_clk_pll_calc(rate, &rc)) { 990 - cfg = &rc; 991 - } else { 992 - dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__); 1021 + if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.tmds_char_rate, &rc)) { 1022 + dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n", 1023 + __func__, hdptx->hdmi_cfg.tmds_char_rate); 993 1024 return -EINVAL; 994 1025 } 1026 + 1027 + cfg = &rc; 995 1028 } 996 1029 997 - dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n", 998 - cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en, 999 - cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno); 1030 + dev_dbg(hdptx->dev, "%s rate=%llu mdiv=%u sdiv=%u sdm_en=%u k_sign=%u k=%u lc=%u\n", 1031 + __func__, hdptx->hdmi_cfg.tmds_char_rate, cfg->pms_mdiv, cfg->pms_sdiv + 1, 1032 + cfg->sdm_en, cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno); 1000 1033 1001 1034 rk_hdptx_pre_power_up(hdptx); 1002 1035 ··· 1030 1061 regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, 1031 1062 FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); 1032 1063 1064 + regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, 1065 + FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->hdmi_cfg.bpc - 8) >> 1)); 1066 + 1033 1067 regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK, 1034 1068 FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1)); 1035 1069 1036 - return rk_hdptx_post_enable_pll(hdptx); 1070 + ret = rk_hdptx_post_enable_pll(hdptx); 1071 + if (!ret) 1072 + hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate; 1073 + 1074 + return ret; 1037 1075 } 1038 1076 1039 - static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx, 1040 - unsigned int rate) 1077 + static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx) 1041 1078 { 1042 1079 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); 1043 1080 1044 1081 regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06); 1045 1082 1046 - if (rate >= 3400000) { 1083 + if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) { 1047 1084 /* For 1/40 bitrate clk */ 1048 1085 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq); 1049 1086 } else { ··· 1101 1126 HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0)); 1102 1127 } 1103 1128 1104 - static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx, 1105 - unsigned int rate) 1129 + static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx) 1106 1130 { 1107 1131 enum phy_mode mode = phy_get_mode(hdptx->phy); 1108 1132 u32 status; ··· 1120 1146 if (mode == PHY_MODE_DP) { 1121 1147 rk_hdptx_dp_reset(hdptx); 1122 1148 } else { 1123 - if (rate) { 1124 - ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate); 1125 - if (ret) 1126 - goto dec_usage; 1127 - } 1149 + ret = rk_hdptx_ropll_tmds_cmn_config(hdptx); 1150 + if (ret) 1151 + goto dec_usage; 1128 1152 } 1129 1153 1130 1154 return 0; ··· 1417 1445 static int rk_hdptx_phy_power_on(struct phy *phy) 1418 1446 { 1419 1447 struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); 1420 - int bus_width = phy_get_bus_width(hdptx->phy); 1421 1448 enum phy_mode mode = phy_get_mode(phy); 1422 1449 int ret, lane; 1423 1450 1424 - /* 1425 - * FIXME: Temporary workaround to pass pixel_clk_rate 1426 - * from the HDMI bridge driver until phy_configure_opts_hdmi 1427 - * becomes available in the PHY API. 1428 - */ 1429 - unsigned int rate = bus_width & 0xfffffff; 1451 + if (mode != PHY_MODE_DP) { 1452 + if (!hdptx->hdmi_cfg.tmds_char_rate) { 1453 + /* 1454 + * FIXME: Temporary workaround to setup TMDS char rate 1455 + * from the RK DW HDMI QP bridge driver. 1456 + * Will be removed as soon the switch to the HDMI PHY 1457 + * configuration API has been completed on both ends. 1458 + */ 1459 + hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff; 1460 + hdptx->hdmi_cfg.tmds_char_rate *= 100; 1461 + } 1430 1462 1431 - dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n", 1432 - __func__, bus_width, rate); 1463 + dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, 1464 + hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); 1465 + } 1433 1466 1434 - ret = rk_hdptx_phy_consumer_get(hdptx, rate); 1467 + ret = rk_hdptx_phy_consumer_get(hdptx); 1435 1468 if (ret) 1436 1469 return ret; 1437 1470 ··· 1467 1490 regmap_write(hdptx->grf, GRF_HDPTX_CON0, 1468 1491 HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0)); 1469 1492 1470 - ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate); 1493 + ret = rk_hdptx_ropll_tmds_mode_config(hdptx); 1471 1494 if (ret) 1472 1495 rk_hdptx_phy_consumer_put(hdptx, true); 1473 1496 } ··· 1482 1505 return rk_hdptx_phy_consumer_put(hdptx, false); 1483 1506 } 1484 1507 1485 - static int rk_hdptx_phy_verify_config(struct rk_hdptx_phy *hdptx, 1486 - struct phy_configure_opts_dp *dp) 1508 + static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx, 1509 + struct phy_configure_opts_hdmi *hdmi) 1510 + { 1511 + int i; 1512 + 1513 + if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE) 1514 + return -EINVAL; 1515 + 1516 + for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) 1517 + if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate) 1518 + break; 1519 + 1520 + if (i == ARRAY_SIZE(ropll_tmds_cfg) && 1521 + !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL)) 1522 + return -EINVAL; 1523 + 1524 + if (!hdmi->bpc) 1525 + hdmi->bpc = 8; 1526 + 1527 + switch (hdmi->bpc) { 1528 + case 8: 1529 + case 10: 1530 + case 12: 1531 + case 16: 1532 + break; 1533 + default: 1534 + return -EINVAL; 1535 + } 1536 + 1537 + return 0; 1538 + } 1539 + 1540 + static int rk_hdptx_phy_verify_dp_config(struct rk_hdptx_phy *hdptx, 1541 + struct phy_configure_opts_dp *dp) 1487 1542 { 1488 1543 int i; 1489 1544 ··· 1775 1766 enum phy_mode mode = phy_get_mode(phy); 1776 1767 int ret; 1777 1768 1778 - if (mode != PHY_MODE_DP) 1779 - return 0; 1769 + if (mode != PHY_MODE_DP) { 1770 + ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); 1771 + if (ret) { 1772 + dev_err(hdptx->dev, "invalid hdmi params for phy configure\n"); 1773 + } else { 1774 + hdptx->hdmi_cfg = opts->hdmi; 1775 + hdptx->restrict_rate_change = true; 1776 + } 1780 1777 1781 - ret = rk_hdptx_phy_verify_config(hdptx, &opts->dp); 1778 + dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, 1779 + hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); 1780 + return ret; 1781 + } 1782 + 1783 + ret = rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp); 1782 1784 if (ret) { 1783 - dev_err(hdptx->dev, "invalid params for phy configure\n"); 1785 + dev_err(hdptx->dev, "invalid dp params for phy configure\n"); 1784 1786 return ret; 1785 1787 } 1786 1788 ··· 1823 1803 return 0; 1824 1804 } 1825 1805 1806 + static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode, 1807 + int submode, union phy_configure_opts *opts) 1808 + { 1809 + struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); 1810 + 1811 + if (mode != PHY_MODE_DP) 1812 + return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); 1813 + 1814 + return rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp); 1815 + } 1816 + 1826 1817 static const struct phy_ops rk_hdptx_phy_ops = { 1827 1818 .power_on = rk_hdptx_phy_power_on, 1828 1819 .power_off = rk_hdptx_phy_power_off, 1829 1820 .configure = rk_hdptx_phy_configure, 1821 + .validate = rk_hdptx_phy_validate, 1830 1822 .owner = THIS_MODULE, 1831 1823 }; 1832 1824 ··· 1851 1819 { 1852 1820 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1853 1821 1854 - return rk_hdptx_phy_consumer_get(hdptx, hdptx->rate / 100); 1822 + return rk_hdptx_phy_consumer_get(hdptx); 1855 1823 } 1856 1824 1857 1825 static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw) ··· 1866 1834 { 1867 1835 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1868 1836 1869 - return hdptx->rate; 1837 + return hdptx->hw_rate; 1870 1838 } 1871 1839 1872 1840 static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, 1873 1841 unsigned long *parent_rate) 1874 1842 { 1875 - u32 bit_rate = rate / 100; 1876 - int i; 1843 + struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1877 1844 1878 - if (rate > HDMI20_MAX_RATE) 1879 - return rate; 1845 + /* 1846 + * FIXME: Temporarily allow altering TMDS char rate via CCF. 1847 + * To be dropped as soon as the RK DW HDMI QP bridge driver 1848 + * switches to make use of phy_configure(). 1849 + */ 1850 + if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) { 1851 + struct phy_configure_opts_hdmi hdmi = { 1852 + .tmds_char_rate = rate, 1853 + }; 1854 + int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi); 1880 1855 1881 - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) 1882 - if (bit_rate == ropll_tmds_cfg[i].bit_rate) 1883 - break; 1856 + if (ret) 1857 + return ret; 1884 1858 1885 - if (i == ARRAY_SIZE(ropll_tmds_cfg) && 1886 - !rk_hdptx_phy_clk_pll_calc(bit_rate, NULL)) 1887 - return -EINVAL; 1859 + hdptx->hdmi_cfg = hdmi; 1860 + } 1888 1861 1889 - return rate; 1862 + /* 1863 + * The TMDS char rate shall be adjusted via phy_configure() only, 1864 + * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with 1865 + * a different rate argument. 1866 + */ 1867 + return hdptx->hdmi_cfg.tmds_char_rate; 1890 1868 } 1891 1869 1892 1870 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, ··· 1904 1862 { 1905 1863 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); 1906 1864 1907 - return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100); 1865 + /* Revert any unlikely TMDS char rate change since round_rate() */ 1866 + if (hdptx->hdmi_cfg.tmds_char_rate != rate) { 1867 + dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n", 1868 + rate, hdptx->hdmi_cfg.tmds_char_rate); 1869 + hdptx->hdmi_cfg.tmds_char_rate = rate; 1870 + } 1871 + 1872 + /* 1873 + * The TMDS char rate would be normally programmed in HW during 1874 + * phy_ops.power_on() or clk_ops.prepare() callbacks, but it might 1875 + * happen that the former gets fired too late, i.e. after this call, 1876 + * while the latter being executed only once, i.e. when clock remains 1877 + * in the prepared state during rate changes. 1878 + */ 1879 + return rk_hdptx_ropll_tmds_cmn_config(hdptx); 1908 1880 } 1909 1881 1910 1882 static const struct clk_ops hdptx_phy_clk_ops = { ··· 1981 1925 1982 1926 static int rk_hdptx_phy_probe(struct platform_device *pdev) 1983 1927 { 1928 + const struct rk_hdptx_phy_cfg *cfgs; 1984 1929 struct phy_provider *phy_provider; 1985 1930 struct device *dev = &pdev->dev; 1986 1931 struct rk_hdptx_phy *hdptx; ··· 1994 1937 return -ENOMEM; 1995 1938 1996 1939 hdptx->dev = dev; 1940 + hdptx->hdmi_cfg.bpc = 8; 1997 1941 1998 1942 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1999 1943 if (IS_ERR(regs)) 2000 1944 return dev_err_probe(dev, PTR_ERR(regs), 2001 1945 "Failed to ioremap resource\n"); 2002 1946 2003 - hdptx->cfgs = device_get_match_data(dev); 2004 - if (!hdptx->cfgs) 1947 + cfgs = device_get_match_data(dev); 1948 + if (!cfgs) 2005 1949 return dev_err_probe(dev, -EINVAL, "missing match data\n"); 2006 1950 2007 1951 /* find the phy-id from the io address */ 2008 1952 hdptx->phy_id = -ENODEV; 2009 - for (id = 0; id < hdptx->cfgs->num_phys; id++) { 2010 - if (res->start == hdptx->cfgs->phy_ids[id]) { 1953 + for (id = 0; id < cfgs->num_phys; id++) { 1954 + if (res->start == cfgs->phy_ids[id]) { 2011 1955 hdptx->phy_id = id; 2012 1956 break; 2013 1957 }
+1 -1
drivers/phy/samsung/Kconfig
··· 85 85 depends on USB_DWC3_EXYNOS 86 86 select GENERIC_PHY 87 87 select MFD_SYSCON 88 - default y 88 + default ARCH_EXYNOS 89 89 help 90 90 Enable USB DRD PHY support for Exynos 5 SoC series. 91 91 This driver provides PHY interface for USB 3.0 DRD controller
+536 -81
drivers/phy/samsung/phy-exynos5-usbdrd.c
··· 36 36 #define EXYNOS5_FSEL_26MHZ 0x6 37 37 #define EXYNOS5_FSEL_50MHZ 0x7 38 38 39 + /* USB 3.2 DRD 4nm PHY link controller registers */ 40 + #define EXYNOS2200_DRD_CLKRST 0x0c 41 + #define EXYNOS2200_CLKRST_LINK_PCLK_SEL BIT(1) 42 + 43 + #define EXYNOS2200_DRD_UTMI 0x10 44 + #define EXYNOS2200_UTMI_FORCE_VBUSVALID BIT(1) 45 + #define EXYNOS2200_UTMI_FORCE_BVALID BIT(0) 46 + 47 + #define EXYNOS2200_DRD_HSP_MISC 0x114 48 + #define HSP_MISC_SET_REQ_IN2 BIT(4) 49 + #define HSP_MISC_RES_TUNE GENMASK(1, 0) 50 + #define RES_TUNE_PHY1_PHY2 0x1 51 + #define RES_TUNE_PHY1 0x2 52 + #define RES_TUNE_PHY2 0x3 53 + 39 54 /* Exynos5: USB 3.0 DRD PHY registers */ 40 55 #define EXYNOS5_DRD_LINKSYSTEM 0x04 41 56 #define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) 42 - #define LINKSYSTEM_FLADJ_MASK (0x3f << 1) 43 - #define LINKSYSTEM_FLADJ(_x) ((_x) << 1) 57 + #define LINKSYSTEM_FORCE_VBUSVALID BIT(8) 58 + #define LINKSYSTEM_FORCE_BVALID BIT(7) 59 + #define LINKSYSTEM_FLADJ GENMASK(6, 1) 44 60 45 61 #define EXYNOS5_DRD_PHYUTMI 0x08 62 + #define PHYUTMI_UTMI_SUSPEND_COM_N BIT(12) 63 + #define PHYUTMI_UTMI_L1_SUSPEND_COM_N BIT(11) 64 + #define PHYUTMI_VBUSVLDEXTSEL BIT(10) 65 + #define PHYUTMI_VBUSVLDEXT BIT(9) 66 + #define PHYUTMI_TXBITSTUFFENH BIT(8) 67 + #define PHYUTMI_TXBITSTUFFEN BIT(7) 46 68 #define PHYUTMI_OTGDISABLE BIT(6) 69 + #define PHYUTMI_IDPULLUP BIT(5) 70 + #define PHYUTMI_DRVVBUS BIT(4) 71 + #define PHYUTMI_DPPULLDOWN BIT(3) 72 + #define PHYUTMI_DMPULLDOWN BIT(2) 47 73 #define PHYUTMI_FORCESUSPEND BIT(1) 48 74 #define PHYUTMI_FORCESLEEP BIT(0) 49 75 ··· 77 51 78 52 #define EXYNOS5_DRD_PHYCLKRST 0x10 79 53 #define PHYCLKRST_EN_UTMISUSPEND BIT(31) 80 - #define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) 81 - #define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) 82 - #define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) 83 - #define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) 54 + #define PHYCLKRST_SSC_REFCLKSEL GENMASK(30, 23) 55 + #define PHYCLKRST_SSC_RANGE GENMASK(22, 21) 84 56 #define PHYCLKRST_SSC_EN BIT(20) 85 57 #define PHYCLKRST_REF_SSP_EN BIT(19) 86 58 #define PHYCLKRST_REF_CLKDIV2 BIT(18) 87 - #define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) 88 - #define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) 89 - #define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x32 << 11) 90 - #define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) 91 - #define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) 92 - #define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) 93 - #define PHYCLKRST_FSEL_PIPE_MASK (0x7 << 8) 94 - #define PHYCLKRST_FSEL_UTMI_MASK (0x7 << 5) 95 - #define PHYCLKRST_FSEL(_x) ((_x) << 5) 96 - #define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) 97 - #define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) 98 - #define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) 99 - #define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) 59 + #define PHYCLKRST_MPLL_MULTIPLIER GENMASK(17, 11) 60 + #define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF 0x19 61 + #define PHYCLKRST_MPLL_MULTIPLIER_50M_REF 0x32 62 + #define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF 0x68 63 + #define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF 0x7d 64 + #define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF 0x02 65 + #define PHYCLKRST_FSEL_PIPE GENMASK(10, 8) 66 + #define PHYCLKRST_FSEL_UTMI GENMASK(7, 5) 67 + #define PHYCLKRST_FSEL_PAD_100MHZ 0x27 68 + #define PHYCLKRST_FSEL_PAD_24MHZ 0x2a 69 + #define PHYCLKRST_FSEL_PAD_20MHZ 0x31 70 + #define PHYCLKRST_FSEL_PAD_19_2MHZ 0x38 100 71 #define PHYCLKRST_RETENABLEN BIT(4) 101 - #define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) 102 - #define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) 103 - #define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) 72 + #define PHYCLKRST_REFCLKSEL GENMASK(3, 2) 73 + #define PHYCLKRST_REFCLKSEL_PAD_REFCLK 0x2 74 + #define PHYCLKRST_REFCLKSEL_EXT_REFCLK 0x3 104 75 #define PHYCLKRST_PORTRESET BIT(1) 105 76 #define PHYCLKRST_COMMONONN BIT(0) 106 77 ··· 106 83 #define PHYREG0_SSC_RANGE BIT(20) 107 84 #define PHYREG0_CR_WRITE BIT(19) 108 85 #define PHYREG0_CR_READ BIT(18) 109 - #define PHYREG0_CR_DATA_IN(_x) ((_x) << 2) 86 + #define PHYREG0_CR_DATA_IN GENMASK(17, 2) 110 87 #define PHYREG0_CR_CAP_DATA BIT(1) 111 88 #define PHYREG0_CR_CAP_ADDR BIT(0) 112 89 113 90 #define EXYNOS5_DRD_PHYREG1 0x18 114 - #define PHYREG1_CR_DATA_OUT(_x) ((_x) << 1) 91 + #define PHYREG0_CR_DATA_OUT GENMASK(16, 1) 115 92 #define PHYREG1_CR_ACK BIT(0) 116 93 117 94 #define EXYNOS5_DRD_PHYPARAM0 0x1c 118 95 #define PHYPARAM0_REF_USE_PAD BIT(31) 119 - #define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) 120 - #define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) 96 + #define PHYPARAM0_REF_LOSLEVEL GENMASK(30, 26) 97 + #define PHYPARAM0_REF_LOSLEVEL_VAL 0x9 98 + #define PHYPARAM0_TXVREFTUNE GENMASK(25, 22) 99 + #define PHYPARAM0_TXRISETUNE GENMASK(21, 20) 100 + #define PHYPARAM0_TXRESTUNE GENMASK(19, 18) 101 + #define PHYPARAM0_TXPREEMPPULSETUNE BIT(17) 102 + #define PHYPARAM0_TXPREEMPAMPTUNE GENMASK(16, 15) 103 + #define PHYPARAM0_TXHSXVTUNE GENMASK(14, 13) 104 + #define PHYPARAM0_TXFSLSTUNE GENMASK(12, 9) 105 + #define PHYPARAM0_SQRXTUNE GENMASK(8, 6) 106 + #define PHYPARAM0_OTGTUNE GENMASK(5, 3) 107 + #define PHYPARAM0_COMPDISTUNE GENMASK(2, 0) 121 108 122 109 #define EXYNOS5_DRD_PHYPARAM1 0x20 123 - #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) 124 - #define PHYPARAM1_PCS_TXDEEMPH (0x1c) 110 + #define PHYPARAM1_PCS_TXDEEMPH GENMASK(4, 0) 111 + #define PHYPARAM1_PCS_TXDEEMPH_VAL 0x1c 125 112 126 113 #define EXYNOS5_DRD_PHYTERM 0x24 127 114 ··· 147 114 #define EXYNOS5_DRD_PHYRESUME 0x34 148 115 149 116 #define EXYNOS5_DRD_LINKPORT 0x44 117 + #define LINKPORT_HOST_U3_PORT_DISABLE BIT(8) 118 + #define LINKPORT_HOST_U2_PORT_DISABLE BIT(7) 119 + #define LINKPORT_HOST_PORT_OVCR_U3 BIT(5) 120 + #define LINKPORT_HOST_PORT_OVCR_U2 BIT(4) 121 + #define LINKPORT_HOST_PORT_OVCR_U3_SEL BIT(3) 122 + #define LINKPORT_HOST_PORT_OVCR_U2_SEL BIT(2) 150 123 151 124 /* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */ 152 125 #define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN (0x15) ··· 173 134 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4) 174 135 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4) 175 136 137 + /* Exynos7870: USB DRD PHY registers */ 138 + #define EXYNOS7870_DRD_PHYPCSVAL 0x3C 139 + #define PHYPCSVAL_PCS_RX_LOS_MASK GENMASK(9, 0) 140 + 141 + #define EXYNOS7870_DRD_PHYPARAM2 0x50 142 + #define PHYPARAM2_TX_VBOOST_LVL GENMASK(6, 4) 143 + #define PHYPARAM2_LOS_BIAS GENMASK(2, 0) 144 + 145 + #define EXYNOS7870_DRD_HSPHYCTRL 0x54 146 + #define HSPHYCTRL_PHYSWRSTALL BIT(31) 147 + #define HSPHYCTRL_SIDDQ BIT(6) 148 + #define HSPHYCTRL_PHYSWRST BIT(0) 149 + 150 + #define EXYNOS7870_DRD_HSPHYPLLTUNE 0x70 151 + #define HSPHYPLLTUNE_PLL_B_TUNE BIT(6) 152 + #define HSPHYPLLTUNE_PLL_I_TUNE GENMASK(5, 4) 153 + #define HSPHYPLLTUNE_PLL_P_TUNE GENMASK(3, 0) 154 + 176 155 /* Exynos850: USB DRD PHY registers */ 177 156 #define EXYNOS850_DRD_LINKCTRL 0x04 178 157 #define LINKCTRL_FORCE_RXELECIDLE BIT(18) 179 158 #define LINKCTRL_FORCE_PHYSTATUS BIT(17) 180 159 #define LINKCTRL_FORCE_PIPE_EN BIT(16) 181 160 #define LINKCTRL_FORCE_QACT BIT(8) 182 - #define LINKCTRL_BUS_FILTER_BYPASS(_x) ((_x) << 4) 161 + #define LINKCTRL_BUS_FILTER_BYPASS GENMASK(7, 4) 183 162 184 163 #define EXYNOS850_DRD_LINKPORT 0x08 185 164 #define LINKPORT_HOST_NUM_U3 GENMASK(19, 16) ··· 446 389 * @clks: clocks for register access 447 390 * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required) 448 391 * @drv_data: pointer to SoC level driver data structure 392 + * @hs_phy: pointer to non-Samsung IP high-speed phy controller 449 393 * @phy_mutex: mutex protecting phy_init/exit & TCPC callbacks 450 394 * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY 451 395 * instances each with its 'phy' and 'phy_cfg'. ··· 464 406 struct clk_bulk_data *clks; 465 407 struct clk_bulk_data *core_clks; 466 408 const struct exynos5_usbdrd_phy_drvdata *drv_data; 409 + struct phy *hs_phy; 467 410 struct mutex phy_mutex; 468 411 struct phy_usb_instance { 469 412 struct phy *phy; ··· 556 497 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 557 498 558 499 /* Use EXTREFCLK as ref clock */ 559 - reg &= ~PHYCLKRST_REFCLKSEL_MASK; 560 - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; 500 + reg &= ~PHYCLKRST_REFCLKSEL; 501 + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_EXT_REFCLK); 561 502 562 503 /* FSEL settings corresponding to reference clock */ 563 - reg &= ~(PHYCLKRST_FSEL_PIPE_MASK | 564 - PHYCLKRST_MPLL_MULTIPLIER_MASK | 565 - PHYCLKRST_SSC_REFCLKSEL_MASK); 504 + reg &= ~(PHYCLKRST_FSEL_PIPE | 505 + PHYCLKRST_MPLL_MULTIPLIER | 506 + PHYCLKRST_SSC_REFCLKSEL); 566 507 switch (phy_drd->extrefclk) { 567 508 case EXYNOS5_FSEL_50MHZ: 568 - reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | 569 - PHYCLKRST_SSC_REFCLKSEL(0x00)); 509 + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x00) | 510 + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, 511 + PHYCLKRST_MPLL_MULTIPLIER_50M_REF)); 570 512 break; 571 513 case EXYNOS5_FSEL_24MHZ: 572 - reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF | 573 - PHYCLKRST_SSC_REFCLKSEL(0x88)); 514 + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x88) | 515 + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, 516 + PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF)); 574 517 break; 575 518 case EXYNOS5_FSEL_20MHZ: 576 - reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF | 577 - PHYCLKRST_SSC_REFCLKSEL(0x00)); 519 + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x00) | 520 + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, 521 + PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF)); 578 522 break; 579 523 case EXYNOS5_FSEL_19MHZ2: 580 - reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF | 581 - PHYCLKRST_SSC_REFCLKSEL(0x88)); 524 + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x88) | 525 + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, 526 + PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF)); 582 527 break; 583 528 default: 584 529 dev_dbg(phy_drd->dev, "unsupported ref clk\n"); ··· 605 542 /* restore any previous reference clock settings */ 606 543 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 607 544 608 - reg &= ~PHYCLKRST_REFCLKSEL_MASK; 609 - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; 545 + reg &= ~PHYCLKRST_REFCLKSEL; 546 + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_EXT_REFCLK); 610 547 611 - reg &= ~(PHYCLKRST_FSEL_UTMI_MASK | 612 - PHYCLKRST_MPLL_MULTIPLIER_MASK | 613 - PHYCLKRST_SSC_REFCLKSEL_MASK); 614 - reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); 548 + reg &= ~(PHYCLKRST_FSEL_UTMI | 549 + PHYCLKRST_MPLL_MULTIPLIER | 550 + PHYCLKRST_SSC_REFCLKSEL); 551 + reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk); 615 552 616 553 return reg; 617 554 } ··· 661 598 662 599 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 663 600 /* Set Tx De-Emphasis level */ 664 - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; 665 - reg |= PHYPARAM1_PCS_TXDEEMPH; 601 + reg &= ~PHYPARAM1_PCS_TXDEEMPH; 602 + reg |= FIELD_PREP(PHYPARAM1_PCS_TXDEEMPH, PHYPARAM1_PCS_TXDEEMPH_VAL); 666 603 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 667 604 668 605 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); ··· 812 749 813 750 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 814 751 /* Set Loss-of-Signal Detector sensitivity */ 815 - reg &= ~PHYPARAM0_REF_LOSLEVEL_MASK; 816 - reg |= PHYPARAM0_REF_LOSLEVEL; 752 + reg &= ~PHYPARAM0_REF_LOSLEVEL; 753 + reg |= FIELD_PREP(PHYPARAM0_REF_LOSLEVEL, PHYPARAM0_REF_LOSLEVEL_VAL); 817 754 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); 818 755 819 756 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 820 757 /* Set Tx De-Emphasis level */ 821 - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; 822 - reg |= PHYPARAM1_PCS_TXDEEMPH; 758 + reg &= ~PHYPARAM1_PCS_TXDEEMPH; 759 + reg |= FIELD_PREP(PHYPARAM1_PCS_TXDEEMPH, PHYPARAM1_PCS_TXDEEMPH_VAL); 823 760 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); 824 761 825 762 /* UTMI Power Control */ ··· 850 787 * See xHCI 1.0 spec, 5.2.4 851 788 */ 852 789 reg = LINKSYSTEM_XHCI_VERSION_CONTROL | 853 - LINKSYSTEM_FLADJ(0x20); 790 + FIELD_PREP(LINKSYSTEM_FLADJ, 0x20); 854 791 writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 855 792 856 793 reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); ··· 1009 946 static int crport_ctrl_write(struct exynos5_usbdrd_phy *phy_drd, 1010 947 u32 addr, u32 data) 1011 948 { 949 + u32 val; 1012 950 int ret; 1013 951 1014 952 /* Write Address */ 1015 - writel(PHYREG0_CR_DATA_IN(addr), 1016 - phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 1017 - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(addr), 1018 - PHYREG0_CR_CAP_ADDR); 953 + val = FIELD_PREP(PHYREG0_CR_DATA_IN, addr); 954 + writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 955 + ret = crport_handshake(phy_drd, val, PHYREG0_CR_CAP_ADDR); 1019 956 if (ret) 1020 957 return ret; 1021 958 1022 959 /* Write Data */ 1023 - writel(PHYREG0_CR_DATA_IN(data), 1024 - phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 1025 - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data), 1026 - PHYREG0_CR_CAP_DATA); 960 + val = FIELD_PREP(PHYREG0_CR_DATA_IN, data); 961 + writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 962 + ret = crport_handshake(phy_drd, val, PHYREG0_CR_CAP_DATA); 1027 963 if (ret) 1028 964 return ret; 1029 965 1030 - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data), 1031 - PHYREG0_CR_WRITE); 966 + ret = crport_handshake(phy_drd, val, PHYREG0_CR_WRITE); 1032 967 1033 968 return ret; 1034 969 } ··· 1136 1075 .owner = THIS_MODULE, 1137 1076 }; 1138 1077 1078 + static void exynos7870_usbdrd_phy_isol(struct phy_usb_instance *inst, 1079 + bool isolate) 1080 + { 1081 + unsigned int val; 1082 + 1083 + if (!inst->reg_pmu) 1084 + return; 1085 + 1086 + val = isolate ? 0 : EXYNOS7870_USB2PHY_ENABLE; 1087 + 1088 + regmap_update_bits(inst->reg_pmu, inst->pmu_offset, 1089 + EXYNOS7870_USB2PHY_ENABLE, val); 1090 + } 1091 + 1092 + static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) 1093 + { 1094 + u32 reg; 1095 + 1096 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 1097 + /* Use PADREFCLK as ref clock */ 1098 + reg &= ~PHYCLKRST_REFCLKSEL; 1099 + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_PAD_REFCLK); 1100 + /* Select ref clock rate */ 1101 + reg &= ~PHYCLKRST_FSEL_UTMI; 1102 + reg &= ~PHYCLKRST_FSEL_PIPE; 1103 + reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk); 1104 + /* Enable suspend and reset the port */ 1105 + reg |= PHYCLKRST_EN_UTMISUSPEND; 1106 + reg |= PHYCLKRST_COMMONONN; 1107 + reg |= PHYCLKRST_PORTRESET; 1108 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 1109 + udelay(10); 1110 + 1111 + /* Clear the port reset bit */ 1112 + reg &= ~PHYCLKRST_PORTRESET; 1113 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); 1114 + 1115 + /* Change PHY PLL tune value */ 1116 + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYPLLTUNE); 1117 + if (phy_drd->extrefclk == EXYNOS5_FSEL_24MHZ) 1118 + reg |= HSPHYPLLTUNE_PLL_B_TUNE; 1119 + else 1120 + reg &= ~HSPHYPLLTUNE_PLL_B_TUNE; 1121 + reg &= ~HSPHYPLLTUNE_PLL_P_TUNE; 1122 + reg |= FIELD_PREP(HSPHYPLLTUNE_PLL_P_TUNE, 14); 1123 + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYPLLTUNE); 1124 + 1125 + /* High-Speed PHY control */ 1126 + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1127 + reg &= ~HSPHYCTRL_SIDDQ; 1128 + reg &= ~HSPHYCTRL_PHYSWRST; 1129 + reg &= ~HSPHYCTRL_PHYSWRSTALL; 1130 + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1131 + udelay(500); 1132 + 1133 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 1134 + /* 1135 + * Setting the Frame length Adj value[6:1] to default 0x20 1136 + * See xHCI 1.0 spec, 5.2.4 1137 + */ 1138 + reg |= LINKSYSTEM_XHCI_VERSION_CONTROL; 1139 + reg &= ~LINKSYSTEM_FLADJ; 1140 + reg |= FIELD_PREP(LINKSYSTEM_FLADJ, 0x20); 1141 + /* Set VBUSVALID signal as the VBUS pad is not used */ 1142 + reg |= LINKSYSTEM_FORCE_BVALID; 1143 + reg |= LINKSYSTEM_FORCE_VBUSVALID; 1144 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 1145 + 1146 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 1147 + /* Release force_sleep & force_suspend */ 1148 + reg &= ~PHYUTMI_FORCESLEEP; 1149 + reg &= ~PHYUTMI_FORCESUSPEND; 1150 + /* DP/DM pull down control */ 1151 + reg &= ~PHYUTMI_DMPULLDOWN; 1152 + reg &= ~PHYUTMI_DPPULLDOWN; 1153 + reg &= ~PHYUTMI_DRVVBUS; 1154 + /* Set DP-pull up as the VBUS pad is not used */ 1155 + reg |= PHYUTMI_VBUSVLDEXTSEL; 1156 + reg |= PHYUTMI_VBUSVLDEXT; 1157 + /* Disable OTG block and VBUS valid comparator */ 1158 + reg |= PHYUTMI_OTGDISABLE; 1159 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 1160 + 1161 + /* Configure OVC IO usage */ 1162 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKPORT); 1163 + reg |= LINKPORT_HOST_PORT_OVCR_U3_SEL | LINKPORT_HOST_PORT_OVCR_U2_SEL; 1164 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKPORT); 1165 + 1166 + /* High-Speed PHY swrst */ 1167 + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1168 + reg |= HSPHYCTRL_PHYSWRST; 1169 + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1170 + udelay(20); 1171 + 1172 + /* Clear the PHY swrst bit */ 1173 + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1174 + reg &= ~HSPHYCTRL_PHYSWRST; 1175 + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1176 + 1177 + if (phy_drd->drv_data->phy_tunes) 1178 + exynos5_usbdrd_apply_phy_tunes(phy_drd, 1179 + PTS_UTMI_POSTINIT); 1180 + } 1181 + 1182 + static int exynos7870_usbdrd_phy_init(struct phy *phy) 1183 + { 1184 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 1185 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 1186 + int ret; 1187 + 1188 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 1189 + if (ret) 1190 + return ret; 1191 + 1192 + /* UTMI or PIPE3 specific init */ 1193 + inst->phy_cfg->phy_init(phy_drd); 1194 + 1195 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 1196 + 1197 + return 0; 1198 + } 1199 + 1200 + static int exynos7870_usbdrd_phy_exit(struct phy *phy) 1201 + { 1202 + int ret; 1203 + u32 reg; 1204 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 1205 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 1206 + 1207 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 1208 + if (ret) 1209 + return ret; 1210 + 1211 + /* 1212 + * Disable the VBUS signal and the ID pull-up resistor. 1213 + * Enable force-suspend and force-sleep modes. 1214 + */ 1215 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 1216 + reg &= ~(PHYUTMI_DRVVBUS | PHYUTMI_VBUSVLDEXT | PHYUTMI_VBUSVLDEXTSEL); 1217 + reg &= ~PHYUTMI_IDPULLUP; 1218 + reg |= PHYUTMI_FORCESUSPEND | PHYUTMI_FORCESLEEP; 1219 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); 1220 + 1221 + /* Power down PHY analog blocks */ 1222 + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1223 + reg |= HSPHYCTRL_SIDDQ; 1224 + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); 1225 + 1226 + /* Clear VBUSVALID signal as the VBUS pad is not used */ 1227 + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 1228 + reg &= ~(LINKSYSTEM_FORCE_BVALID | LINKSYSTEM_FORCE_VBUSVALID); 1229 + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); 1230 + 1231 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 1232 + 1233 + return 0; 1234 + } 1235 + 1236 + static const struct phy_ops exynos7870_usbdrd_phy_ops = { 1237 + .init = exynos7870_usbdrd_phy_init, 1238 + .exit = exynos7870_usbdrd_phy_exit, 1239 + .power_on = exynos5_usbdrd_phy_power_on, 1240 + .power_off = exynos5_usbdrd_phy_power_off, 1241 + .owner = THIS_MODULE, 1242 + }; 1243 + 1244 + static void exynos2200_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) 1245 + { 1246 + /* Configure non-Samsung IP PHY, responsible for UTMI */ 1247 + phy_init(phy_drd->hs_phy); 1248 + } 1249 + 1250 + static void exynos2200_usbdrd_link_init(struct exynos5_usbdrd_phy *phy_drd) 1251 + { 1252 + void __iomem *regs_base = phy_drd->reg_phy; 1253 + u32 reg; 1254 + 1255 + /* 1256 + * Disable HWACG (hardware auto clock gating control). This will force 1257 + * QACTIVE signal in Q-Channel interface to HIGH level, to make sure 1258 + * the PHY clock is not gated by the hardware. 1259 + */ 1260 + reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); 1261 + reg |= LINKCTRL_FORCE_QACT; 1262 + writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); 1263 + 1264 + /* De-assert link reset */ 1265 + reg = readl(regs_base + EXYNOS2200_DRD_CLKRST); 1266 + reg &= ~CLKRST_LINK_SW_RST; 1267 + writel(reg, regs_base + EXYNOS2200_DRD_CLKRST); 1268 + 1269 + /* Set link VBUS Valid */ 1270 + reg = readl(regs_base + EXYNOS2200_DRD_UTMI); 1271 + reg |= EXYNOS2200_UTMI_FORCE_BVALID | EXYNOS2200_UTMI_FORCE_VBUSVALID; 1272 + writel(reg, regs_base + EXYNOS2200_DRD_UTMI); 1273 + } 1274 + 1275 + static void 1276 + exynos2200_usbdrd_link_attach_detach_pipe3_phy(struct phy_usb_instance *inst) 1277 + { 1278 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 1279 + void __iomem *regs_base = phy_drd->reg_phy; 1280 + u32 reg; 1281 + 1282 + reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); 1283 + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { 1284 + /* force pipe3 signal for link */ 1285 + reg &= ~LINKCTRL_FORCE_PHYSTATUS; 1286 + reg |= LINKCTRL_FORCE_PIPE_EN | LINKCTRL_FORCE_RXELECIDLE; 1287 + } else { 1288 + /* disable forcing pipe interface */ 1289 + reg &= ~LINKCTRL_FORCE_PIPE_EN; 1290 + } 1291 + writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); 1292 + 1293 + reg = readl(regs_base + EXYNOS2200_DRD_HSP_MISC); 1294 + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { 1295 + /* calibrate only eUSB phy */ 1296 + reg |= FIELD_PREP(HSP_MISC_RES_TUNE, RES_TUNE_PHY1); 1297 + reg |= HSP_MISC_SET_REQ_IN2; 1298 + } else { 1299 + /* calibrate for dual phy */ 1300 + reg |= FIELD_PREP(HSP_MISC_RES_TUNE, RES_TUNE_PHY1_PHY2); 1301 + reg &= ~HSP_MISC_SET_REQ_IN2; 1302 + } 1303 + writel(reg, regs_base + EXYNOS2200_DRD_HSP_MISC); 1304 + 1305 + reg = readl(regs_base + EXYNOS2200_DRD_CLKRST); 1306 + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) 1307 + reg &= ~EXYNOS2200_CLKRST_LINK_PCLK_SEL; 1308 + else 1309 + reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL; 1310 + 1311 + writel(reg, regs_base + EXYNOS2200_DRD_CLKRST); 1312 + } 1313 + 1314 + static int exynos2200_usbdrd_phy_init(struct phy *phy) 1315 + { 1316 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 1317 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 1318 + int ret; 1319 + 1320 + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { 1321 + /* Power-on PHY ... */ 1322 + ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators, 1323 + phy_drd->regulators); 1324 + if (ret) { 1325 + dev_err(phy_drd->dev, 1326 + "Failed to enable PHY regulator(s)\n"); 1327 + return ret; 1328 + } 1329 + } 1330 + /* 1331 + * ... and ungate power via PMU. Without this here, we get an SError 1332 + * trying to access PMA registers 1333 + */ 1334 + exynos5_usbdrd_phy_isol(inst, false); 1335 + 1336 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 1337 + if (ret) 1338 + return ret; 1339 + 1340 + /* Set up the link controller */ 1341 + exynos2200_usbdrd_link_init(phy_drd); 1342 + 1343 + /* UTMI or PIPE3 link preparation */ 1344 + exynos2200_usbdrd_link_attach_detach_pipe3_phy(inst); 1345 + 1346 + /* UTMI or PIPE3 specific init */ 1347 + inst->phy_cfg->phy_init(phy_drd); 1348 + 1349 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 1350 + 1351 + return 0; 1352 + } 1353 + 1354 + static int exynos2200_usbdrd_phy_exit(struct phy *phy) 1355 + { 1356 + struct phy_usb_instance *inst = phy_get_drvdata(phy); 1357 + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); 1358 + void __iomem *regs_base = phy_drd->reg_phy; 1359 + u32 reg; 1360 + int ret; 1361 + 1362 + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); 1363 + if (ret) 1364 + return ret; 1365 + 1366 + reg = readl(regs_base + EXYNOS2200_DRD_UTMI); 1367 + reg &= ~(EXYNOS2200_UTMI_FORCE_BVALID | EXYNOS2200_UTMI_FORCE_VBUSVALID); 1368 + writel(reg, regs_base + EXYNOS2200_DRD_UTMI); 1369 + 1370 + reg = readl(regs_base + EXYNOS2200_DRD_CLKRST); 1371 + reg |= CLKRST_LINK_SW_RST; 1372 + writel(reg, regs_base + EXYNOS2200_DRD_CLKRST); 1373 + 1374 + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); 1375 + 1376 + exynos5_usbdrd_phy_isol(inst, true); 1377 + return regulator_bulk_disable(phy_drd->drv_data->n_regulators, 1378 + phy_drd->regulators); 1379 + } 1380 + 1381 + static const struct phy_ops exynos2200_usbdrd_phy_ops = { 1382 + .init = exynos2200_usbdrd_phy_init, 1383 + .exit = exynos2200_usbdrd_phy_exit, 1384 + .owner = THIS_MODULE, 1385 + }; 1386 + 1139 1387 static void 1140 1388 exynos5_usbdrd_usb_v3p1_pipe_override(struct exynos5_usbdrd_phy *phy_drd) 1141 1389 { ··· 1504 1134 1505 1135 /* Set VBUS Valid and D+ pull-up control by VBUS pad usage */ 1506 1136 reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); 1507 - reg |= LINKCTRL_BUS_FILTER_BYPASS(0xf); 1137 + reg |= FIELD_PREP(LINKCTRL_BUS_FILTER_BYPASS, 0xf); 1508 1138 writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); 1509 1139 1510 1140 if (!phy_drd->sw) { ··· 1754 1384 return dev_err_probe(phy_drd->dev, ret, 1755 1385 "failed to get phy core clock(s)\n"); 1756 1386 1757 - ref_clk = NULL; 1758 - for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) { 1759 - if (!strcmp(phy_drd->core_clks[i].id, "ref")) { 1760 - ref_clk = phy_drd->core_clks[i].clk; 1761 - break; 1387 + if (phy_drd->drv_data->n_core_clks) { 1388 + ref_clk = NULL; 1389 + for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) { 1390 + if (!strcmp(phy_drd->core_clks[i].id, "ref")) { 1391 + ref_clk = phy_drd->core_clks[i].clk; 1392 + break; 1393 + } 1762 1394 } 1763 - } 1764 - if (!ref_clk) 1765 - return dev_err_probe(phy_drd->dev, -ENODEV, 1766 - "failed to find phy reference clock\n"); 1395 + if (!ref_clk) 1396 + return dev_err_probe(phy_drd->dev, -ENODEV, 1397 + "failed to find phy reference clock\n"); 1767 1398 1768 - ref_rate = clk_get_rate(ref_clk); 1769 - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); 1770 - if (ret) 1771 - return dev_err_probe(phy_drd->dev, ret, 1772 - "clock rate (%ld) not supported\n", 1773 - ref_rate); 1399 + ref_rate = clk_get_rate(ref_clk); 1400 + ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); 1401 + if (ret) 1402 + return dev_err_probe(phy_drd->dev, ret, 1403 + "clock rate (%ld) not supported\n", 1404 + ref_rate); 1405 + } 1774 1406 1775 1407 return 0; 1776 1408 } 1409 + 1410 + static const struct exynos5_usbdrd_phy_config phy_cfg_exynos2200[] = { 1411 + { 1412 + .id = EXYNOS5_DRDPHY_UTMI, 1413 + .phy_isol = exynos5_usbdrd_phy_isol, 1414 + .phy_init = exynos2200_usbdrd_utmi_init, 1415 + }, 1416 + }; 1777 1417 1778 1418 static int exynos5_usbdrd_orien_sw_set(struct typec_switch_dev *sw, 1779 1419 enum typec_orientation orientation) ··· 1881 1501 }, 1882 1502 }; 1883 1503 1504 + static const struct exynos5_usbdrd_phy_config phy_cfg_exynos7870[] = { 1505 + { 1506 + .id = EXYNOS5_DRDPHY_UTMI, 1507 + .phy_isol = exynos7870_usbdrd_phy_isol, 1508 + .phy_init = exynos7870_usbdrd_utmi_init, 1509 + }, 1510 + }; 1511 + 1884 1512 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { 1885 1513 { 1886 1514 .id = EXYNOS5_DRDPHY_UTMI, 1887 1515 .phy_isol = exynos5_usbdrd_phy_isol, 1888 1516 .phy_init = exynos850_usbdrd_utmi_init, 1889 1517 }, 1518 + }; 1519 + 1520 + static 1521 + const struct exynos5_usbdrd_phy_tuning exynos7870_tunes_utmi_postinit[] = { 1522 + PHY_TUNING_ENTRY_PHY(EXYNOS5_DRD_PHYPARAM0, 1523 + (PHYPARAM0_TXVREFTUNE | PHYPARAM0_TXRISETUNE | 1524 + PHYPARAM0_TXRESTUNE | PHYPARAM0_TXPREEMPPULSETUNE | 1525 + PHYPARAM0_TXPREEMPAMPTUNE | PHYPARAM0_TXHSXVTUNE | 1526 + PHYPARAM0_TXFSLSTUNE | PHYPARAM0_SQRXTUNE | 1527 + PHYPARAM0_OTGTUNE | PHYPARAM0_COMPDISTUNE), 1528 + (FIELD_PREP_CONST(PHYPARAM0_TXVREFTUNE, 14) | 1529 + FIELD_PREP_CONST(PHYPARAM0_TXRISETUNE, 1) | 1530 + FIELD_PREP_CONST(PHYPARAM0_TXRESTUNE, 3) | 1531 + FIELD_PREP_CONST(PHYPARAM0_TXPREEMPAMPTUNE, 0) | 1532 + FIELD_PREP_CONST(PHYPARAM0_TXHSXVTUNE, 0) | 1533 + FIELD_PREP_CONST(PHYPARAM0_TXFSLSTUNE, 3) | 1534 + FIELD_PREP_CONST(PHYPARAM0_SQRXTUNE, 6) | 1535 + FIELD_PREP_CONST(PHYPARAM0_OTGTUNE, 2) | 1536 + FIELD_PREP_CONST(PHYPARAM0_COMPDISTUNE, 3))), 1537 + PHY_TUNING_ENTRY_LAST 1538 + }; 1539 + 1540 + static const struct exynos5_usbdrd_phy_tuning *exynos7870_tunes[PTS_MAX] = { 1541 + [PTS_UTMI_POSTINIT] = exynos7870_tunes_utmi_postinit, 1890 1542 }; 1891 1543 1892 1544 static const char * const exynos5_clk_names[] = { ··· 1935 1523 1936 1524 static const char * const exynos5_regulator_names[] = { 1937 1525 "vbus", "vbus-boost", 1526 + }; 1527 + 1528 + static const struct exynos5_usbdrd_phy_drvdata exynos2200_usb32drd_phy = { 1529 + .phy_cfg = phy_cfg_exynos2200, 1530 + .phy_ops = &exynos2200_usbdrd_phy_ops, 1531 + .pmu_offset_usbdrd0_phy = EXYNOS2200_PHY_CTRL_USB20, 1532 + .clk_names = exynos5_clk_names, 1533 + .n_clks = ARRAY_SIZE(exynos5_clk_names), 1534 + /* clocks and regulators are specific to the underlying PHY blocks */ 1535 + .core_clk_names = NULL, 1536 + .n_core_clks = 0, 1537 + .regulator_names = NULL, 1538 + .n_regulators = 0, 1938 1539 }; 1939 1540 1940 1541 static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { ··· 1996 1571 .n_clks = ARRAY_SIZE(exynos5_clk_names), 1997 1572 .core_clk_names = exynos5433_core_clk_names, 1998 1573 .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), 1574 + .regulator_names = exynos5_regulator_names, 1575 + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), 1576 + }; 1577 + 1578 + static const struct exynos5_usbdrd_phy_drvdata exynos7870_usbdrd_phy = { 1579 + .phy_cfg = phy_cfg_exynos7870, 1580 + .phy_tunes = exynos7870_tunes, 1581 + .phy_ops = &exynos7870_usbdrd_phy_ops, 1582 + .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, 1583 + .clk_names = exynos5_clk_names, 1584 + .n_clks = ARRAY_SIZE(exynos5_clk_names), 1585 + .core_clk_names = exynos5_core_clk_names, 1586 + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), 1999 1587 .regulator_names = exynos5_regulator_names, 2000 1588 .n_regulators = ARRAY_SIZE(exynos5_regulator_names), 2001 1589 }; ··· 2208 1770 .compatible = "google,gs101-usb31drd-phy", 2209 1771 .data = &gs101_usbd31rd_phy 2210 1772 }, { 1773 + .compatible = "samsung,exynos2200-usb32drd-phy", 1774 + .data = &exynos2200_usb32drd_phy, 1775 + }, { 2211 1776 .compatible = "samsung,exynos5250-usbdrd-phy", 2212 1777 .data = &exynos5250_usbdrd_phy 2213 1778 }, { ··· 2222 1781 }, { 2223 1782 .compatible = "samsung,exynos7-usbdrd-phy", 2224 1783 .data = &exynos7_usbdrd_phy 1784 + }, { 1785 + .compatible = "samsung,exynos7870-usbdrd-phy", 1786 + .data = &exynos7870_usbdrd_phy 2225 1787 }, { 2226 1788 .compatible = "samsung,exynos850-usbdrd-phy", 2227 1789 .data = &exynos850_usbdrd_phy ··· 2283 1839 phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0); 2284 1840 if (IS_ERR(phy_drd->reg_phy)) 2285 1841 return PTR_ERR(phy_drd->reg_phy); 1842 + } 1843 + 1844 + /* 1845 + * USB32DRD 4nm controller implements Synopsys eUSB2.0 PHY 1846 + * and Synopsys SS/USBDP COMBOPHY, managed by external code. 1847 + */ 1848 + if (of_property_present(dev->of_node, "phy-names")) { 1849 + phy_drd->hs_phy = devm_of_phy_get(dev, dev->of_node, "hs"); 1850 + if (IS_ERR(phy_drd->hs_phy)) 1851 + return dev_err_probe(dev, PTR_ERR(phy_drd->hs_phy), 1852 + "failed to get hs_phy\n"); 2286 1853 } 2287 1854 2288 1855 ret = exynos5_usbdrd_phy_clk_handle(phy_drd);
+1 -1
drivers/phy/tegra/Kconfig
··· 13 13 14 14 config PHY_TEGRA194_P2U 15 15 tristate "NVIDIA Tegra194 PIPE2UPHY PHY driver" 16 - depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || COMPILE_TEST 16 + depends on ARCH_TEGRA || COMPILE_TEST 17 17 select GENERIC_PHY 18 18 help 19 19 Enable this to support the P2U (PIPE to UPHY) that is part of Tegra 19x
+37 -33
drivers/phy/xilinx/phy-zynqmp.c
··· 222 222 * @siou: siou base address 223 223 * @gtr_mutex: mutex for locking 224 224 * @phys: PHY lanes 225 - * @refclk_sscs: spread spectrum settings for the reference clocks 226 225 * @clk: reference clocks 227 226 * @tx_term_fix: fix for GT issue 228 227 * @saved_icm_cfg0: stored value of ICM CFG0 register ··· 234 235 void __iomem *siou; 235 236 struct mutex gtr_mutex; /* mutex for locking */ 236 237 struct xpsgtr_phy phys[NUM_LANES]; 237 - const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; 238 238 struct clk *clk[NUM_LANES]; 239 239 bool tx_term_fix; 240 240 unsigned int saved_icm_cfg0; ··· 396 398 return ret; 397 399 } 398 400 401 + /* Get the spread spectrum (SSC) settings for the reference clock rate */ 402 + static const struct xpsgtr_ssc *xpsgtr_find_sscs(struct xpsgtr_phy *gtr_phy) 403 + { 404 + unsigned long rate; 405 + struct clk *clk; 406 + unsigned int i; 407 + 408 + clk = gtr_phy->dev->clk[gtr_phy->refclk]; 409 + rate = clk_get_rate(clk); 410 + 411 + for (i = 0 ; i < ARRAY_SIZE(ssc_lookup); i++) { 412 + /* Allow an error of 100 ppm */ 413 + unsigned long error = ssc_lookup[i].refclk_rate / 10000; 414 + 415 + if (abs(rate - ssc_lookup[i].refclk_rate) < error) 416 + return &ssc_lookup[i]; 417 + } 418 + 419 + dev_err(gtr_phy->dev->dev, "Invalid rate %lu for reference clock %u\n", 420 + rate, gtr_phy->refclk); 421 + 422 + return NULL; 423 + } 424 + 399 425 /* Configure PLL and spread-sprectrum clock. */ 400 - static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) 426 + static int xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) 401 427 { 402 428 const struct xpsgtr_ssc *ssc; 403 429 u32 step_size; 404 430 405 - ssc = gtr_phy->dev->refclk_sscs[gtr_phy->refclk]; 431 + ssc = xpsgtr_find_sscs(gtr_phy); 432 + if (!ssc) 433 + return -EINVAL; 434 + 406 435 step_size = ssc->step_size; 407 436 408 437 xpsgtr_clr_set(gtr_phy->dev, PLL_REF_SEL(gtr_phy->lane), ··· 471 446 xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_3_MSB, 472 447 STEP_SIZE_3_MASK, (step_size & STEP_SIZE_3_MASK) | 473 448 FORCE_STEP_SIZE | FORCE_STEPS); 449 + 450 + return 0; 474 451 } 475 452 476 453 /* Configure the lane protocol. */ ··· 685 658 * Configure the PLL, the lane protocol, and perform protocol-specific 686 659 * initialization. 687 660 */ 688 - xpsgtr_configure_pll(gtr_phy); 661 + ret = xpsgtr_configure_pll(gtr_phy); 662 + if (ret) 663 + goto out; 664 + 689 665 xpsgtr_lane_set_protocol(gtr_phy); 690 666 691 667 switch (gtr_phy->protocol) { ··· 853 823 } 854 824 855 825 refclk = args->args[3]; 856 - if (refclk >= ARRAY_SIZE(gtr_dev->refclk_sscs) || 857 - !gtr_dev->refclk_sscs[refclk]) { 826 + if (refclk >= ARRAY_SIZE(gtr_dev->clk)) { 858 827 dev_err(dev, "Invalid reference clock number %u\n", refclk); 859 828 return ERR_PTR(-EINVAL); 860 829 } ··· 957 928 { 958 929 unsigned int refclk; 959 930 960 - for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { 961 - unsigned long rate; 962 - unsigned int i; 931 + for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->clk); ++refclk) { 963 932 struct clk *clk; 964 933 char name[8]; 965 934 ··· 973 946 continue; 974 947 975 948 gtr_dev->clk[refclk] = clk; 976 - 977 - /* 978 - * Get the spread spectrum (SSC) settings for the reference 979 - * clock rate. 980 - */ 981 - rate = clk_get_rate(clk); 982 - 983 - for (i = 0 ; i < ARRAY_SIZE(ssc_lookup); i++) { 984 - /* Allow an error of 100 ppm */ 985 - unsigned long error = ssc_lookup[i].refclk_rate / 10000; 986 - 987 - if (abs(rate - ssc_lookup[i].refclk_rate) < error) { 988 - gtr_dev->refclk_sscs[refclk] = &ssc_lookup[i]; 989 - break; 990 - } 991 - } 992 - 993 - if (i == ARRAY_SIZE(ssc_lookup)) { 994 - dev_err(gtr_dev->dev, 995 - "Invalid rate %lu for reference clock %u\n", 996 - rate, refclk); 997 - return -EINVAL; 998 - } 999 949 } 1000 950 1001 951 return 0;
+21
include/linux/phy/phy-hdmi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright 2022,2024 NXP 4 + */ 5 + 6 + #ifndef __PHY_HDMI_H_ 7 + #define __PHY_HDMI_H_ 8 + 9 + /** 10 + * struct phy_configure_opts_hdmi - HDMI configuration set 11 + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. 12 + * @bpc: Bits per color channel. 13 + * 14 + * This structure is used to represent the configuration state of a HDMI phy. 15 + */ 16 + struct phy_configure_opts_hdmi { 17 + unsigned long long tmds_char_rate; 18 + unsigned int bpc; 19 + }; 20 + 21 + #endif /* __PHY_HDMI_H_ */
+6 -1
include/linux/phy/phy.h
··· 17 17 #include <linux/regulator/consumer.h> 18 18 19 19 #include <linux/phy/phy-dp.h> 20 + #include <linux/phy/phy-hdmi.h> 20 21 #include <linux/phy/phy-lvds.h> 21 22 #include <linux/phy/phy-mipi-dphy.h> 22 23 ··· 43 42 PHY_MODE_MIPI_DPHY, 44 43 PHY_MODE_SATA, 45 44 PHY_MODE_LVDS, 46 - PHY_MODE_DP 45 + PHY_MODE_DP, 46 + PHY_MODE_HDMI, 47 47 }; 48 48 49 49 enum phy_media { ··· 62 60 * the DisplayPort protocol. 63 61 * @lvds: Configuration set applicable for phys supporting 64 62 * the LVDS phy mode. 63 + * @hdmi: Configuration set applicable for phys supporting 64 + * the HDMI phy mode. 65 65 */ 66 66 union phy_configure_opts { 67 67 struct phy_configure_opts_mipi_dphy mipi_dphy; 68 68 struct phy_configure_opts_dp dp; 69 69 struct phy_configure_opts_lvds lvds; 70 + struct phy_configure_opts_hdmi hdmi; 70 71 }; 71 72 72 73 /**
+5
include/linux/soc/samsung/exynos-regs-pmu.h
··· 55 55 #define EXYNOS4_MIPI_PHY_SRESETN (1 << 1) 56 56 #define EXYNOS4_MIPI_PHY_MRESETN (1 << 2) 57 57 #define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1) 58 + /* USB PHY enable bit, valid for Exynos7870 */ 59 + #define EXYNOS7870_USB2PHY_ENABLE (1 << 1) 58 60 59 61 #define S5P_INFORM0 0x0800 60 62 #define S5P_INFORM1 0x0804 ··· 186 184 187 185 /* Only for S5Pv210 */ 188 186 #define S5PV210_EINT_WAKEUP_MASK 0xC004 187 + 188 + /* Only for Exynos2200 */ 189 + #define EXYNOS2200_PHY_CTRL_USB20 0x72C 189 190 190 191 /* Only for Exynos4210 */ 191 192 #define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154