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

Merge tag 'phy-for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy into usb-next

Vinod writes:

phy for 5.9

- Core:
- New PHY attribute for max_link_rate

- New phy drivers:
- Rockchip dphy driver moved from staging
- Socionext UniPhier AHCI PHY driver
- Intel LGM SoC USB phy
- Intel Keem Bay eMMC PHY driver

- Updates:
- Support for imx8mp usb phy
- Support for DP Phy and USB3+DP combo phy in QMP driver
- Support for Qualcomm sc7180 DP phy
- Support for cadence torrent PCIe and USB single linke and multilink
configurations along with USB, SGMII/QSGMII configurations

* tag 'phy-for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (72 commits)
phy: qcom-qmp: initialize the pointer to NULL
phy: qcom-qmp: Add support for sc7180 DP phy
phy: qcom-qmp: Add support for DP in USB3+DP combo phy
phy: qcom-qmp: Use devm_platform_ioremap_resource() to simplify
phy: qcom-qmp: Get dp_com I/O resource by index
phy: qcom-qmp: Move 'serdes' and 'cfg' into 'struct qcom_phy'
phy: qcom-qmp: Remove 'initialized' in favor of 'init_count'
phy: qcom-qmp: Move phy mode into struct qmp_phy
dt-bindings: phy: qcom,qmp-usb3-dp: Add DP phy information
dt-bindings: phy: ti,phy-j721e-wiz: fix bindings for torrent phy
dt-bindings: phy: cdns,torrent-phy: add reset-names
phy: rockchip-dphy-rx0: Include linux/delay.h
phy: fix USB_LGM_PHY warning & build errors
phy: cadence-torrent: Add USB + SGMII/QSGMII multilink configuration
phy: cadence-torrent: Add PCIe + USB multilink configuration
phy: cadence-torrent: Add single link USB register sequences
phy: cadence-torrent: Add single link SGMII/QSGMII register sequences
phy: cadence-torrent: Configure PHY_PLL_CFG as part of link_cmn_vals
phy: cadence-torrent: Add PHY link configuration sequences for single link
phy: cadence-torrent: Add clk changes for multilink configuration
...

+4871 -724
+1 -1
Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.txt
··· 1 1 * Freescale i.MX8MQ USB3 PHY binding 2 2 3 3 Required properties: 4 - - compatible: Should be "fsl,imx8mq-usb-phy" 4 + - compatible: Should be "fsl,imx8mq-usb-phy" or "fsl,imx8mp-usb-phy" 5 5 - #phys-cells: must be 0 (see phy-bindings.txt in this directory) 6 6 - reg: The base address and length of the registers 7 7 - clocks: phandles to the clocks for each clock listed in clock-names
+16 -1
Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
··· 23 23 24 24 properties: 25 25 compatible: 26 - const: intel,lgm-emmc-phy 26 + oneOf: 27 + - const: intel,lgm-emmc-phy 28 + - const: intel,keembay-emmc-phy 27 29 28 30 "#phy-cells": 29 31 const: 0 ··· 35 33 36 34 clocks: 37 35 maxItems: 1 36 + 37 + clock-names: 38 + items: 39 + - const: emmcclk 38 40 39 41 required: 40 42 - "#phy-cells" ··· 62 56 clocks = <&emmc>; 63 57 #phy-cells = <0>; 64 58 }; 59 + }; 60 + 61 + - | 62 + phy@20290000 { 63 + compatible = "intel,keembay-emmc-phy"; 64 + reg = <0x20290000 0x54>; 65 + clocks = <&emmc>; 66 + clock-names = "emmcclk"; 67 + #phy-cells = <0>; 65 68 }; 66 69 ...
+58
Documentation/devicetree/bindings/phy/intel,lgm-usb-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/intel,lgm-usb-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intel LGM USB PHY Device Tree Bindings 8 + 9 + maintainers: 10 + - Vadivel Murugan Ramuthevar <vadivel.muruganx.ramuthevar@linux.intel.com> 11 + 12 + properties: 13 + compatible: 14 + const: intel,lgm-usb-phy 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + clocks: 20 + maxItems: 1 21 + 22 + resets: 23 + items: 24 + - description: USB PHY and Host controller reset 25 + - description: APB BUS reset 26 + - description: General Hardware reset 27 + 28 + reset-names: 29 + items: 30 + - const: phy 31 + - const: apb 32 + - const: phy31 33 + 34 + "#phy-cells": 35 + const: 0 36 + 37 + required: 38 + - compatible 39 + - clocks 40 + - reg 41 + - resets 42 + - reset-names 43 + - "#phy-cells" 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + usb-phy@e7e00000 { 50 + compatible = "intel,lgm-usb-phy"; 51 + reg = <0xe7e00000 0x10000>; 52 + clocks = <&cgu0 153>; 53 + resets = <&rcu 0x70 0x24>, 54 + <&rcu 0x70 0x26>, 55 + <&rcu 0x70 0x28>; 56 + reset-names = "phy", "apb", "phy31"; 57 + #phy-cells = <0>; 58 + };
+79 -17
Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
··· 4 4 $id: "http://devicetree.org/schemas/phy/phy-cadence-torrent.yaml#" 5 5 $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 6 7 - title: Cadence Torrent SD0801 PHY binding for DisplayPort 7 + title: Cadence Torrent SD0801 PHY binding 8 8 9 9 description: 10 10 This binding describes the Cadence SD0801 PHY (also known as Torrent PHY) 11 - hardware included with the Cadence MHDP DisplayPort controller. 11 + hardware included with the Cadence MHDP DisplayPort controller. Torrent 12 + PHY also supports multilink multiprotocol combinations including protocols 13 + such as PCIe, USB, SGMII, QSGMII etc. 12 14 13 15 maintainers: 14 16 - Swapnil Jakhade <sjakhade@cadence.com> ··· 51 49 - const: dptx_phy 52 50 53 51 resets: 54 - maxItems: 1 55 - description: 56 - Torrent PHY reset. 57 - See Documentation/devicetree/bindings/reset/reset.txt 52 + minItems: 1 53 + maxItems: 2 54 + items: 55 + - description: Torrent PHY reset. 56 + - description: Torrent APB reset. This is optional. 57 + 58 + reset-names: 59 + minItems: 1 60 + maxItems: 2 61 + items: 62 + - const: torrent_reset 63 + - const: torrent_apb 58 64 59 65 patternProperties: 60 - '^phy@[0-7]+$': 66 + '^phy@[0-3]$': 61 67 type: object 62 68 description: 63 69 Each group of PHY lanes with a single master lane should be represented as a sub-node. ··· 73 63 reg: 74 64 description: 75 65 The master lane number. This is the lowest numbered lane in the lane group. 66 + minimum: 0 67 + maximum: 3 76 68 77 69 resets: 78 70 minItems: 1 ··· 90 78 Specifies the type of PHY for which the group of PHY lanes is used. 91 79 Refer include/dt-bindings/phy/phy.h. Constants from the header should be used. 92 80 $ref: /schemas/types.yaml#/definitions/uint32 93 - enum: [1, 2, 3, 4, 5, 6] 81 + minimum: 1 82 + maximum: 9 94 83 95 84 cdns,num-lanes: 96 85 description: 97 - Number of DisplayPort lanes. 86 + Number of lanes. 98 87 $ref: /schemas/types.yaml#/definitions/uint32 99 - enum: [1, 2, 4] 88 + enum: [1, 2, 3, 4] 100 89 default: 4 90 + 91 + cdns,ssc-mode: 92 + description: 93 + Specifies the Spread Spectrum Clocking mode used. It can be NO_SSC, 94 + EXTERNAL_SSC or INTERNAL_SSC. 95 + Refer include/dt-bindings/phy/phy-cadence-torrent.h for the constants to be used. 96 + $ref: /schemas/types.yaml#/definitions/uint32 97 + enum: [0, 1, 2] 98 + default: 0 101 99 102 100 cdns,max-bit-rate: 103 101 description: ··· 121 99 - resets 122 100 - "#phy-cells" 123 101 - cdns,phy-type 102 + - cdns,num-lanes 124 103 125 104 additionalProperties: false 126 105 ··· 134 111 - reg 135 112 - reg-names 136 113 - resets 114 + - reset-names 137 115 138 116 additionalProperties: false 139 117 ··· 152 128 <0xf0 0xfb030a00 0x0 0x00000040>; 153 129 reg-names = "torrent_phy", "dptx_phy"; 154 130 resets = <&phyrst 0>; 131 + reset-names = "torrent_reset"; 155 132 clocks = <&ref_clk>; 156 133 clock-names = "refclk"; 157 134 #address-cells = <1>; 158 135 #size-cells = <0>; 159 136 phy@0 { 160 - reg = <0>; 161 - resets = <&phyrst 1>, <&phyrst 2>, 162 - <&phyrst 3>, <&phyrst 4>; 163 - #phy-cells = <0>; 164 - cdns,phy-type = <PHY_TYPE_DP>; 165 - cdns,num-lanes = <4>; 166 - cdns,max-bit-rate = <8100>; 137 + reg = <0>; 138 + resets = <&phyrst 1>, <&phyrst 2>, 139 + <&phyrst 3>, <&phyrst 4>; 140 + #phy-cells = <0>; 141 + cdns,phy-type = <PHY_TYPE_DP>; 142 + cdns,num-lanes = <4>; 143 + cdns,max-bit-rate = <8100>; 144 + }; 145 + }; 146 + }; 147 + - | 148 + #include <dt-bindings/phy/phy.h> 149 + #include <dt-bindings/phy/phy-cadence-torrent.h> 150 + 151 + bus { 152 + #address-cells = <2>; 153 + #size-cells = <2>; 154 + 155 + torrent-phy@f0fb500000 { 156 + compatible = "cdns,torrent-phy"; 157 + reg = <0xf0 0xfb500000 0x0 0x00100000>; 158 + reg-names = "torrent_phy"; 159 + resets = <&phyrst 0>, <&phyrst 1>; 160 + reset-names = "torrent_reset", "torrent_apb"; 161 + clocks = <&ref_clk>; 162 + clock-names = "refclk"; 163 + #address-cells = <1>; 164 + #size-cells = <0>; 165 + phy@0 { 166 + reg = <0>; 167 + resets = <&phyrst 2>, <&phyrst 3>; 168 + #phy-cells = <0>; 169 + cdns,phy-type = <PHY_TYPE_PCIE>; 170 + cdns,num-lanes = <2>; 171 + cdns,ssc-mode = <TORRENT_SERDES_NO_SSC>; 172 + }; 173 + 174 + phy@2 { 175 + reg = <2>; 176 + resets = <&phyrst 4>; 177 + #phy-cells = <0>; 178 + cdns,phy-type = <PHY_TYPE_SGMII>; 179 + cdns,num-lanes = <1>; 180 + cdns,ssc-mode = <TORRENT_SERDES_NO_SSC>; 167 181 }; 168 182 }; 169 183 };
+84 -11
Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
··· 13 13 properties: 14 14 compatible: 15 15 enum: 16 + - qcom,sc7180-qmp-usb3-dp-phy 16 17 - qcom,sc7180-qmp-usb3-phy 18 + - qcom,sdm845-qmp-usb3-dp-phy 17 19 - qcom,sdm845-qmp-usb3-phy 18 20 reg: 19 21 items: 20 - - description: Address and length of PHY's common serdes block. 22 + - description: Address and length of PHY's USB serdes block. 21 23 - description: Address and length of the DP_COM control block. 24 + - description: Address and length of PHY's DP serdes block. 22 25 23 26 reg-names: 24 27 items: 25 - - const: reg-base 28 + - const: usb 26 29 - const: dp_com 30 + - const: dp 27 31 28 32 "#clock-cells": 29 33 enum: [ 1, 2 ] ··· 78 74 79 75 #Required nodes: 80 76 patternProperties: 81 - "^phy@[0-9a-f]+$": 77 + "^usb3-phy@[0-9a-f]+$": 82 78 type: object 83 79 description: 84 - Each device node of QMP phy is required to have as many child nodes as 85 - the number of lanes the PHY has. 80 + The USB3 PHY. 81 + 82 + properties: 83 + reg: 84 + items: 85 + - description: Address and length of TX. 86 + - description: Address and length of RX. 87 + - description: Address and length of PCS. 88 + - description: Address and length of TX2. 89 + - description: Address and length of RX2. 90 + - description: Address and length of pcs_misc. 91 + 92 + clocks: 93 + items: 94 + - description: pipe clock 95 + 96 + clock-names: 97 + items: 98 + - const: pipe0 99 + 100 + clock-output-names: 101 + items: 102 + - const: usb3_phy_pipe_clk_src 103 + 104 + '#clock-cells': 105 + const: 0 106 + 107 + '#phy-cells': 108 + const: 0 109 + 110 + required: 111 + - reg 112 + - clocks 113 + - clock-names 114 + - '#clock-cells' 115 + - '#phy-cells' 116 + 117 + "^dp-phy@[0-9a-f]+$": 118 + type: object 119 + description: 120 + The DP PHY. 121 + 122 + properties: 123 + reg: 124 + items: 125 + - description: Address and length of TX. 126 + - description: Address and length of RX. 127 + - description: Address and length of PCS. 128 + - description: Address and length of TX2. 129 + - description: Address and length of RX2. 130 + 131 + '#clock-cells': 132 + const: 1 133 + 134 + '#phy-cells': 135 + const: 0 136 + 137 + required: 138 + - reg 139 + - '#clock-cells' 140 + - '#phy-cells' 86 141 87 142 required: 88 143 - compatible 89 144 - reg 90 - - reg-names 91 145 - "#clock-cells" 92 146 - "#address-cells" 93 147 - "#size-cells" ··· 163 101 - | 164 102 #include <dt-bindings/clock/qcom,gcc-sdm845.h> 165 103 usb_1_qmpphy: phy-wrapper@88e9000 { 166 - compatible = "qcom,sdm845-qmp-usb3-phy"; 104 + compatible = "qcom,sdm845-qmp-usb3-dp-phy"; 167 105 reg = <0x088e9000 0x18c>, 168 - <0x088e8000 0x10>; 169 - reg-names = "reg-base", "dp_com"; 106 + <0x088e8000 0x10>, 107 + <0x088ea000 0x40>; 108 + reg-names = "usb", "dp_com", "dp"; 170 109 #clock-cells = <1>; 171 110 #address-cells = <1>; 172 111 #size-cells = <1>; 173 - ranges = <0x0 0x088e9000 0x1000>; 112 + ranges = <0x0 0x088e9000 0x2000>; 174 113 175 114 clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, 176 115 <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, ··· 186 123 vdda-phy-supply = <&vdda_usb2_ss_1p2>; 187 124 vdda-pll-supply = <&vdda_usb2_ss_core>; 188 125 189 - phy@200 { 126 + usb3-phy@200 { 190 127 reg = <0x200 0x128>, 191 128 <0x400 0x200>, 192 129 <0xc00 0x218>, ··· 198 135 clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; 199 136 clock-names = "pipe0"; 200 137 clock-output-names = "usb3_phy_pipe_clk_src"; 138 + }; 139 + 140 + dp-phy@88ea200 { 141 + reg = <0xa200 0x200>, 142 + <0xa400 0x200>, 143 + <0xaa00 0x200>, 144 + <0xa600 0x200>, 145 + <0xa800 0x200>; 146 + #clock-cells = <1>; 147 + #phy-cells = <0>; 201 148 }; 202 149 };
+76
Documentation/devicetree/bindings/phy/socionext,uniphier-ahci-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/socionext,uniphier-ahci-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Socionext UniPhier AHCI PHY 8 + 9 + description: | 10 + This describes the deivcetree bindings for PHY interfaces built into 11 + AHCI controller implemented on Socionext UniPhier SoCs. 12 + 13 + maintainers: 14 + - Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - socionext,uniphier-pxs2-ahci-phy 20 + - socionext,uniphier-pxs3-ahci-phy 21 + 22 + reg: 23 + description: PHY register region (offset and length) 24 + 25 + "#phy-cells": 26 + const: 0 27 + 28 + clocks: 29 + maxItems: 2 30 + 31 + clock-names: 32 + oneOf: 33 + - items: # for PXs2 34 + - const: link 35 + - items: # for others 36 + - const: link 37 + - const: phy 38 + 39 + resets: 40 + maxItems: 2 41 + 42 + reset-names: 43 + items: 44 + - const: link 45 + - const: phy 46 + 47 + required: 48 + - compatible 49 + - reg 50 + - "#phy-cells" 51 + - clocks 52 + - clock-names 53 + - resets 54 + - reset-names 55 + 56 + additionalProperties: false 57 + 58 + examples: 59 + - | 60 + ahci-glue@65700000 { 61 + compatible = "socionext,uniphier-pxs3-ahci-glue", 62 + "simple-mfd"; 63 + #address-cells = <1>; 64 + #size-cells = <1>; 65 + ranges = <0 0x65700000 0x100>; 66 + 67 + ahci_phy: phy@10 { 68 + compatible = "socionext,uniphier-pxs3-ahci-phy"; 69 + reg = <0x10 0x10>; 70 + #phy-cells = <0>; 71 + clock-names = "link", "phy"; 72 + clocks = <&sys_clk 28>, <&sys_clk 30>; 73 + reset-names = "link", "phy"; 74 + resets = <&sys_rst 28>, <&sys_rst 30>; 75 + }; 76 + };
+74
Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/ti,omap-usb2.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: OMAP USB2 PHY 8 + 9 + maintainers: 10 + - Kishon Vijay Abraham I <kishon@ti.com> 11 + - Roger Quadros <rogerq@ti.com> 12 + 13 + properties: 14 + compatible: 15 + oneOf: 16 + - items: 17 + - enum: 18 + - ti,dra7x-usb2 19 + - ti,dra7x-usb2-phy2 20 + - ti,am654-usb2 21 + - enum: 22 + - ti,omap-usb2 23 + - items: 24 + - const: ti,am437x-usb2 25 + - items: 26 + - const: ti,omap-usb2 27 + 28 + reg: 29 + maxItems: 1 30 + 31 + "#phy-cells": 32 + const: 0 33 + 34 + clocks: 35 + minItems: 1 36 + items: 37 + - description: wakeup clock 38 + - description: reference clock 39 + 40 + clock-names: 41 + minItems: 1 42 + items: 43 + - const: wkupclk 44 + - const: refclk 45 + 46 + syscon-phy-power: 47 + $ref: /schemas/types.yaml#definitions/phandle-array 48 + description: 49 + phandle/offset pair. Phandle to the system control module and 50 + register offset to power on/off the PHY. 51 + 52 + ctrl-module: 53 + $ref: /schemas/types.yaml#definitions/phandle 54 + description: 55 + (deprecated) phandle of the control module used by PHY driver 56 + to power on the PHY. Use syscon-phy-power instead. 57 + 58 + required: 59 + - compatible 60 + - reg 61 + - "#phy-cells" 62 + - clocks 63 + - clock-names 64 + 65 + examples: 66 + - | 67 + usb0_phy: phy@4100000 { 68 + compatible = "ti,am654-usb2", "ti,omap-usb2"; 69 + reg = <0x4100000 0x54>; 70 + syscon-phy-power = <&scm_conf 0x4000>; 71 + clocks = <&k3_clks 151 0>, <&k3_clks 151 1>; 72 + clock-names = "wkupclk", "refclk"; 73 + #phy-cells = <0>; 74 + };
+10 -3
Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
··· 45 45 ranges: true 46 46 47 47 assigned-clocks: 48 + minItems: 1 48 49 maxItems: 2 49 50 50 51 assigned-clock-parents: 52 + minItems: 1 53 + maxItems: 2 54 + 55 + assigned-clock-rates: 56 + minItems: 1 51 57 maxItems: 2 52 58 53 59 typec-dir-gpios: ··· 125 119 logic. 126 120 properties: 127 121 clocks: 122 + minItems: 2 128 123 maxItems: 4 129 - description: Phandle to four clock nodes representing the inputs to 130 - refclk_dig 124 + description: Phandle to two (Torrent) or four (Sierra) clock nodes representing 125 + the inputs to refclk_dig 131 126 132 127 "#clock-cells": 133 128 const: 0 ··· 210 203 }; 211 204 212 205 refclk-dig { 213 - clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, 206 + clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, 214 207 <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>; 215 208 #clock-cells = <0>; 216 209 assigned-clocks = <&wiz0_refclk_dig>;
-37
Documentation/devicetree/bindings/phy/ti-phy.txt
··· 27 27 reg-names = "otghs_control"; 28 28 }; 29 29 30 - OMAP USB2 PHY 31 - 32 - Required properties: 33 - - compatible: Should be "ti,omap-usb2" 34 - Should be "ti,dra7x-usb2" for the 1st instance of USB2 PHY on 35 - DRA7x 36 - Should be "ti,dra7x-usb2-phy2" for the 2nd instance of USB2 PHY 37 - in DRA7x 38 - Should be "ti,am654-usb2" for the USB2 PHYs on AM654. 39 - - reg : Address and length of the register set for the device. 40 - - #phy-cells: determine the number of cells that should be given in the 41 - phandle while referencing this phy. 42 - - clocks: a list of phandles and clock-specifier pairs, one for each entry in 43 - clock-names. 44 - - clock-names: should include: 45 - * "wkupclk" - wakeup clock. 46 - * "refclk" - reference clock (optional). 47 - 48 - Deprecated properties: 49 - - ctrl-module : phandle of the control module used by PHY driver to power on 50 - the PHY. 51 - 52 - Recommended properies: 53 - - syscon-phy-power : phandle/offset pair. Phandle to the system control 54 - module and the register offset to power on/off the PHY. 55 - 56 - This is usually a subnode of ocp2scp to which it is connected. 57 - 58 - usb2phy@4a0ad080 { 59 - compatible = "ti,omap-usb2"; 60 - reg = <0x4a0ad080 0x58>; 61 - ctrl-module = <&omap_control_usb>; 62 - #phy-cells = <0>; 63 - clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>; 64 - clock-names = "wkupclk", "refclk"; 65 - }; 66 - 67 30 TI PIPE3 PHY 68 31 69 32 Required properties:
+11
drivers/phy/Kconfig
··· 49 49 help 50 50 This option enables support for APM X-Gene SoC multi-purpose PHY. 51 51 52 + config USB_LGM_PHY 53 + tristate "INTEL Lightning Mountain USB PHY Driver" 54 + depends on USB_SUPPORT 55 + select USB_PHY 56 + select REGULATOR 57 + select REGULATOR_FIXED_VOLTAGE 58 + help 59 + Enable this to support Intel DWC3 PHY USB phy. This driver provides 60 + interface to interact with USB GEN-II and USB 3.x PHY that is part 61 + of the Intel network SOC. 62 + 52 63 source "drivers/phy/allwinner/Kconfig" 53 64 source "drivers/phy/amlogic/Kconfig" 54 65 source "drivers/phy/broadcom/Kconfig"
+1
drivers/phy/Makefile
··· 8 8 obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o 9 9 obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 10 10 obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 11 + obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o 11 12 obj-y += allwinner/ \ 12 13 amlogic/ \ 13 14 broadcom/ \
+9 -13
drivers/phy/broadcom/phy-bcm-ns-usb3.c
··· 13 13 #include <linux/bcma/bcma.h> 14 14 #include <linux/delay.h> 15 15 #include <linux/err.h> 16 + #include <linux/iopoll.h> 16 17 #include <linux/mdio.h> 17 18 #include <linux/module.h> 18 19 #include <linux/of_address.h> ··· 259 258 **************************************************/ 260 259 261 260 static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr, 262 - u32 mask, u32 value, unsigned long timeout) 261 + u32 mask, u32 value, int usec) 263 262 { 264 - unsigned long deadline = jiffies + timeout; 265 263 u32 val; 264 + int ret; 266 265 267 - do { 268 - val = readl(addr); 269 - if ((val & mask) == value) 270 - return 0; 271 - cpu_relax(); 272 - udelay(10); 273 - } while (!time_after_eq(jiffies, deadline)); 266 + ret = readl_poll_timeout_atomic(addr, val, ((val & mask) == value), 267 + 10, usec); 268 + if (ret) 269 + dev_err(usb3->dev, "Timeout waiting for register %p\n", addr); 274 270 275 - dev_err(usb3->dev, "Timeout waiting for register %p\n", addr); 276 - 277 - return -EBUSY; 271 + return ret; 278 272 } 279 273 280 274 static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3) 281 275 { 282 276 return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL, 283 277 0x0100, 0x0000, 284 - usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US)); 278 + BCM_NS_USB3_MII_MNG_TIMEOUT_US); 285 279 } 286 280 287 281 static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
+4 -9
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
··· 18 18 #include <linux/init.h> 19 19 #include <linux/interrupt.h> 20 20 #include <linux/io.h> 21 + #include <linux/iopoll.h> 21 22 #include <linux/irq.h> 22 23 #include <linux/mfd/syscon.h> 23 24 #include <linux/module.h> ··· 88 87 static inline int pll_lock_stat(u32 usb_reg, int reg_mask, 89 88 struct ns2_phy_driver *driver) 90 89 { 91 - int retry = PLL_LOCK_RETRY; 92 90 u32 val; 93 91 94 - do { 95 - udelay(1); 96 - val = readl(driver->icfgdrd_regs + usb_reg); 97 - if (val & reg_mask) 98 - return 0; 99 - } while (--retry > 0); 100 - 101 - return -EBUSY; 92 + return readl_poll_timeout_atomic(driver->icfgdrd_regs + usb_reg, 93 + val, (val & reg_mask), 1, 94 + PLL_LOCK_RETRY); 102 95 } 103 96 104 97 static int ns2_drd_phy_init(struct phy *phy)
+8 -11
drivers/phy/broadcom/phy-bcm-sr-usb.c
··· 5 5 6 6 #include <linux/delay.h> 7 7 #include <linux/io.h> 8 + #include <linux/iopoll.h> 8 9 #include <linux/module.h> 9 10 #include <linux/of.h> 10 11 #include <linux/phy/phy.h> ··· 110 109 111 110 static int bcm_usb_pll_lock_check(void __iomem *addr, u32 bit) 112 111 { 113 - int retry; 114 - u32 rd_data; 112 + u32 data; 113 + int ret; 115 114 116 - retry = PLL_LOCK_RETRY_COUNT; 117 - do { 118 - rd_data = readl(addr); 119 - if (rd_data & bit) 120 - return 0; 121 - udelay(1); 122 - } while (--retry > 0); 115 + ret = readl_poll_timeout_atomic(addr, data, (data & bit), 1, 116 + PLL_LOCK_RETRY_COUNT); 117 + if (ret) 118 + pr_err("%s: FAIL\n", __func__); 123 119 124 - pr_err("%s: FAIL\n", __func__); 125 - return -ETIMEDOUT; 120 + return ret; 126 121 } 127 122 128 123 static int bcm_usb_ss_phy_init(struct bcm_usb_phy_cfg *phy_cfg)
+4 -4
drivers/phy/cadence/phy-cadence-salvo.c
··· 97 97 98 98 struct cdns_salvo_data { 99 99 u8 reg_offset_shift; 100 - struct cdns_reg_pairs *init_sequence_val; 100 + const struct cdns_reg_pairs *init_sequence_val; 101 101 u8 init_sequence_length; 102 102 }; 103 103 ··· 126 126 * Below bringup sequence pair are from Cadence PHY's User Guide 127 127 * and NXP platform tuning results. 128 128 */ 129 - static struct cdns_reg_pairs cdns_nxp_sequence_pair[] = { 129 + static const struct cdns_reg_pairs cdns_nxp_sequence_pair[] = { 130 130 {0x0830, PHY_PMA_CMN_CTRL1}, 131 131 {0x0010, TB_ADDR_CMN_DIAG_HSCLK_SEL}, 132 132 {0x00f0, TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR}, ··· 217 217 return ret; 218 218 219 219 for (i = 0; i < data->init_sequence_length; i++) { 220 - struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i; 220 + const struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i; 221 221 222 222 cdns_salvo_write(salvo_phy, reg_pair->off, reg_pair->val); 223 223 } ··· 251 251 return 0; 252 252 } 253 253 254 - static struct phy_ops cdns_salvo_phy_ops = { 254 + static const struct phy_ops cdns_salvo_phy_ops = { 255 255 .init = cdns_salvo_phy_init, 256 256 .power_on = cdns_salvo_phy_power_on, 257 257 .power_off = cdns_salvo_phy_power_off,
+12 -12
drivers/phy/cadence/phy-cadence-sierra.c
··· 172 172 u32 pcie_ln_regs; 173 173 u32 usb_cmn_regs; 174 174 u32 usb_ln_regs; 175 - struct cdns_reg_pairs *pcie_cmn_vals; 176 - struct cdns_reg_pairs *pcie_ln_vals; 177 - struct cdns_reg_pairs *usb_cmn_vals; 178 - struct cdns_reg_pairs *usb_ln_vals; 175 + const struct cdns_reg_pairs *pcie_cmn_vals; 176 + const struct cdns_reg_pairs *pcie_ln_vals; 177 + const struct cdns_reg_pairs *usb_cmn_vals; 178 + const struct cdns_reg_pairs *usb_ln_vals; 179 179 }; 180 180 181 181 struct cdns_regmap_cdb_context { ··· 233 233 .reg_read = cdns_regmap_read, \ 234 234 } 235 235 236 - static struct regmap_config cdns_sierra_lane_cdb_config[] = { 236 + static const struct regmap_config cdns_sierra_lane_cdb_config[] = { 237 237 SIERRA_LANE_CDB_REGMAP_CONF("0"), 238 238 SIERRA_LANE_CDB_REGMAP_CONF("1"), 239 239 SIERRA_LANE_CDB_REGMAP_CONF("2"), ··· 252 252 SIERRA_LANE_CDB_REGMAP_CONF("15"), 253 253 }; 254 254 255 - static struct regmap_config cdns_sierra_common_cdb_config = { 255 + static const struct regmap_config cdns_sierra_common_cdb_config = { 256 256 .name = "sierra_common_cdb", 257 257 .reg_stride = 1, 258 258 .fast_io = true, ··· 260 260 .reg_read = cdns_regmap_read, 261 261 }; 262 262 263 - static struct regmap_config cdns_sierra_phy_config_ctrl_config = { 263 + static const struct regmap_config cdns_sierra_phy_config_ctrl_config = { 264 264 .name = "sierra_phy_config_ctrl", 265 265 .reg_stride = 1, 266 266 .fast_io = true, ··· 274 274 struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent); 275 275 struct regmap *regmap; 276 276 int i, j; 277 - struct cdns_reg_pairs *cmn_vals, *ln_vals; 277 + const struct cdns_reg_pairs *cmn_vals, *ln_vals; 278 278 u32 num_cmn_regs, num_ln_regs; 279 279 280 280 /* Initialise the PHY registers, unless auto configured */ ··· 654 654 } 655 655 656 656 /* refclk100MHz_32b_PCIe_cmn_pll_ext_ssc */ 657 - static struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = { 657 + static const struct cdns_reg_pairs cdns_pcie_cmn_regs_ext_ssc[] = { 658 658 {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG}, 659 659 {0x2106, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG}, 660 660 {0x8A06, SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG}, ··· 663 663 }; 664 664 665 665 /* refclk100MHz_32b_PCIe_ln_ext_ssc */ 666 - static struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = { 666 + static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = { 667 667 {0x813E, SIERRA_CLKPATHCTRL_TMR_PREG}, 668 668 {0x8047, SIERRA_RX_CREQ_FLTR_A_MODE3_PREG}, 669 669 {0x808F, SIERRA_RX_CREQ_FLTR_A_MODE2_PREG}, ··· 674 674 }; 675 675 676 676 /* refclk100MHz_20b_USB_cmn_pll_ext_ssc */ 677 - static struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = { 677 + static const struct cdns_reg_pairs cdns_usb_cmn_regs_ext_ssc[] = { 678 678 {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG}, 679 679 {0x2085, SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG}, 680 680 {0x0000, SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG}, ··· 682 682 }; 683 683 684 684 /* refclk100MHz_20b_USB_ln_ext_ssc */ 685 - static struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = { 685 + static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = { 686 686 {0xFE0A, SIERRA_DET_STANDEC_A_PREG}, 687 687 {0x000F, SIERRA_DET_STANDEC_B_PREG}, 688 688 {0x55A5, SIERRA_DET_STANDEC_C_PREG},
+2023 -106
drivers/phy/cadence/phy-cadence-torrent.c
··· 25 25 #define REF_CLK_19_2MHz 19200000 26 26 #define REF_CLK_25MHz 25000000 27 27 28 - #define DEFAULT_NUM_LANES 4 29 28 #define MAX_NUM_LANES 4 30 29 #define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */ 31 30 31 + #define NUM_SSC_MODE 3 32 + #define NUM_PHY_TYPE 6 33 + 32 34 #define POLL_TIMEOUT_US 5000 35 + #define PLL_LOCK_TIMEOUT 100000 33 36 34 37 #define TORRENT_COMMON_CDB_OFFSET 0x0 35 38 ··· 82 79 #define CMN_PLLSM0_PLLLOCK_TMR 0x002CU 83 80 #define CMN_PLLSM1_PLLPRE_TMR 0x0032U 84 81 #define CMN_PLLSM1_PLLLOCK_TMR 0x0034U 82 + #define CMN_CDIAG_CDB_PWRI_OVRD 0x0041U 83 + #define CMN_CDIAG_XCVRC_PWRI_OVRD 0x0047U 85 84 #define CMN_BGCAL_INIT_TMR 0x0064U 86 85 #define CMN_BGCAL_ITER_TMR 0x0065U 87 86 #define CMN_IBCAL_INIT_TMR 0x0074U ··· 104 99 #define CMN_PLL0_LOCK_REFCNT_START 0x009CU 105 100 #define CMN_PLL0_LOCK_PLLCNT_START 0x009EU 106 101 #define CMN_PLL0_LOCK_PLLCNT_THR 0x009FU 102 + #define CMN_PLL0_INTDIV_M1 0x00A0U 103 + #define CMN_PLL0_FRACDIVH_M1 0x00A2U 104 + #define CMN_PLL0_HIGH_THR_M1 0x00A3U 105 + #define CMN_PLL0_DSM_DIAG_M1 0x00A4U 106 + #define CMN_PLL0_SS_CTRL1_M1 0x00A8U 107 + #define CMN_PLL0_SS_CTRL2_M1 0x00A9U 108 + #define CMN_PLL0_SS_CTRL3_M1 0x00AAU 109 + #define CMN_PLL0_SS_CTRL4_M1 0x00ABU 107 110 #define CMN_PLL1_VCOCAL_TCTRL 0x00C2U 108 111 #define CMN_PLL1_VCOCAL_INIT_TMR 0x00C4U 109 112 #define CMN_PLL1_VCOCAL_ITER_TMR 0x00C5U ··· 129 116 #define CMN_PLL1_LOCK_REFCNT_START 0x00DCU 130 117 #define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU 131 118 #define CMN_PLL1_LOCK_PLLCNT_THR 0x00DFU 119 + #define CMN_TXPUCAL_TUNE 0x0103U 132 120 #define CMN_TXPUCAL_INIT_TMR 0x0104U 133 121 #define CMN_TXPUCAL_ITER_TMR 0x0105U 122 + #define CMN_TXPDCAL_TUNE 0x010BU 134 123 #define CMN_TXPDCAL_INIT_TMR 0x010CU 135 124 #define CMN_TXPDCAL_ITER_TMR 0x010DU 136 125 #define CMN_RXCAL_INIT_TMR 0x0114U ··· 146 131 #define CMN_PDIAG_PLL0_CP_PADJ_M0 0x01A4U 147 132 #define CMN_PDIAG_PLL0_CP_IADJ_M0 0x01A5U 148 133 #define CMN_PDIAG_PLL0_FILT_PADJ_M0 0x01A6U 134 + #define CMN_PDIAG_PLL0_CTRL_M1 0x01B0U 135 + #define CMN_PDIAG_PLL0_CLK_SEL_M1 0x01B1U 149 136 #define CMN_PDIAG_PLL0_CP_PADJ_M1 0x01B4U 150 137 #define CMN_PDIAG_PLL0_CP_IADJ_M1 0x01B5U 138 + #define CMN_PDIAG_PLL0_FILT_PADJ_M1 0x01B6U 151 139 #define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U 152 140 #define CMN_PDIAG_PLL1_CLK_SEL_M0 0x01C1U 153 141 #define CMN_PDIAG_PLL1_CP_PADJ_M0 0x01C4U 154 142 #define CMN_PDIAG_PLL1_CP_IADJ_M0 0x01C5U 155 143 #define CMN_PDIAG_PLL1_FILT_PADJ_M0 0x01C6U 144 + #define CMN_DIAG_BIAS_OVRD1 0x01E1U 156 145 157 146 /* PMA TX Lane registers */ 158 147 #define TX_TXCC_CTRL 0x0040U 159 148 #define TX_TXCC_CPOST_MULT_00 0x004CU 149 + #define TX_TXCC_CPOST_MULT_01 0x004DU 160 150 #define TX_TXCC_MGNFS_MULT_000 0x0050U 161 151 #define DRV_DIAG_TX_DRV 0x00C6U 162 152 #define XCVR_DIAG_PLLDRC_CTRL 0x00E5U 163 153 #define XCVR_DIAG_HSCLK_SEL 0x00E6U 164 154 #define XCVR_DIAG_HSCLK_DIV 0x00E7U 165 155 #define XCVR_DIAG_BIDI_CTRL 0x00EAU 156 + #define XCVR_DIAG_PSC_OVRD 0x00EBU 166 157 #define TX_PSC_A0 0x0100U 158 + #define TX_PSC_A1 0x0101U 167 159 #define TX_PSC_A2 0x0102U 168 160 #define TX_PSC_A3 0x0103U 169 161 #define TX_RCVDET_ST_TMR 0x0123U ··· 179 157 180 158 /* PMA RX Lane registers */ 181 159 #define RX_PSC_A0 0x0000U 160 + #define RX_PSC_A1 0x0001U 182 161 #define RX_PSC_A2 0x0002U 183 162 #define RX_PSC_A3 0x0003U 184 163 #define RX_PSC_CAL 0x0006U 164 + #define RX_CDRLF_CNFG 0x0080U 165 + #define RX_CDRLF_CNFG3 0x0082U 166 + #define RX_SIGDET_HL_FILT_TMR 0x0090U 185 167 #define RX_REE_GCSM1_CTRL 0x0108U 168 + #define RX_REE_GCSM1_EQENM_PH1 0x0109U 169 + #define RX_REE_GCSM1_EQENM_PH2 0x010AU 186 170 #define RX_REE_GCSM2_CTRL 0x0110U 187 171 #define RX_REE_PERGCSM_CTRL 0x0118U 172 + #define RX_REE_ATTEN_THR 0x0149U 173 + #define RX_REE_TAP1_CLIP 0x0171U 174 + #define RX_REE_TAP2TON_CLIP 0x0172U 175 + #define RX_REE_SMGM_CTRL1 0x0177U 176 + #define RX_REE_SMGM_CTRL2 0x0178U 177 + #define RX_DIAG_DFE_CTRL 0x01E0U 178 + #define RX_DIAG_DFE_AMP_TUNE_2 0x01E2U 179 + #define RX_DIAG_DFE_AMP_TUNE_3 0x01E3U 180 + #define RX_DIAG_NQST_CTRL 0x01E5U 181 + #define RX_DIAG_SIGDET_TUNE 0x01E8U 182 + #define RX_DIAG_PI_RATE 0x01F4U 183 + #define RX_DIAG_PI_CAP 0x01F5U 184 + #define RX_DIAG_ACYA 0x01FFU 188 185 189 186 /* PHY PCS common registers */ 190 187 #define PHY_PLL_CFG 0x000EU 188 + #define PHY_PIPE_USB3_GEN2_PRE_CFG0 0x0020U 189 + #define PHY_PIPE_USB3_GEN2_POST_CFG0 0x0022U 190 + #define PHY_PIPE_USB3_GEN2_POST_CFG1 0x0023U 191 191 192 192 /* PHY PMA common registers */ 193 + #define PHY_PMA_CMN_CTRL1 0x0000U 193 194 #define PHY_PMA_CMN_CTRL2 0x0001U 194 195 #define PHY_PMA_PLL_RAW_CTRL 0x0003U 195 196 196 197 static const struct reg_field phy_pll_cfg = 197 198 REG_FIELD(PHY_PLL_CFG, 0, 1); 199 + 200 + static const struct reg_field phy_pma_cmn_ctrl_1 = 201 + REG_FIELD(PHY_PMA_CMN_CTRL1, 0, 0); 198 202 199 203 static const struct reg_field phy_pma_cmn_ctrl_2 = 200 204 REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7); ··· 231 183 static const struct reg_field phy_reset_ctrl = 232 184 REG_FIELD(PHY_RESET, 8, 8); 233 185 234 - static const struct of_device_id cdns_torrent_phy_of_match[]; 186 + enum cdns_torrent_phy_type { 187 + TYPE_NONE, 188 + TYPE_DP, 189 + TYPE_PCIE, 190 + TYPE_SGMII, 191 + TYPE_QSGMII, 192 + TYPE_USB, 193 + }; 194 + 195 + enum cdns_torrent_ssc_mode { 196 + NO_SSC, 197 + EXTERNAL_SSC, 198 + INTERNAL_SSC 199 + }; 235 200 236 201 struct cdns_torrent_inst { 237 202 struct phy *phy; 238 203 u32 mlane; 239 - u32 phy_type; 204 + enum cdns_torrent_phy_type phy_type; 240 205 u32 num_lanes; 241 206 struct reset_control *lnk_rst; 207 + enum cdns_torrent_ssc_mode ssc_mode; 242 208 }; 243 209 244 210 struct cdns_torrent_phy { ··· 260 198 void __iomem *sd_base; /* SD0801 registers base */ 261 199 u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */ 262 200 struct reset_control *phy_rst; 201 + struct reset_control *apb_rst; 263 202 struct device *dev; 264 203 struct clk *clk; 265 204 unsigned long ref_clk_rate; 266 205 struct cdns_torrent_inst phys[MAX_NUM_LANES]; 267 206 int nsubnodes; 207 + const struct cdns_torrent_data *init_data; 268 208 struct regmap *regmap; 269 209 struct regmap *regmap_common_cdb; 270 210 struct regmap *regmap_phy_pcs_common_cdb; ··· 275 211 struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES]; 276 212 struct regmap *regmap_dptx_phy_reg; 277 213 struct regmap_field *phy_pll_cfg; 214 + struct regmap_field *phy_pma_cmn_ctrl_1; 278 215 struct regmap_field *phy_pma_cmn_ctrl_2; 279 216 struct regmap_field *phy_pma_pll_raw_ctrl; 280 217 struct regmap_field *phy_reset_ctrl; ··· 288 223 POWERSTATE_A3 = 3, 289 224 }; 290 225 226 + static int cdns_torrent_phy_init(struct phy *phy); 291 227 static int cdns_torrent_dp_init(struct phy *phy); 292 - static int cdns_torrent_dp_exit(struct phy *phy); 293 228 static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, 294 229 u32 num_lanes); 295 230 static ··· 319 254 static int cdns_torrent_phy_off(struct phy *phy); 320 255 321 256 static const struct phy_ops cdns_torrent_phy_ops = { 322 - .init = cdns_torrent_dp_init, 323 - .exit = cdns_torrent_dp_exit, 257 + .init = cdns_torrent_phy_init, 324 258 .configure = cdns_torrent_dp_configure, 325 259 .power_on = cdns_torrent_phy_on, 326 260 .power_off = cdns_torrent_phy_off, 327 261 .owner = THIS_MODULE, 328 262 }; 329 263 264 + struct cdns_reg_pairs { 265 + u32 val; 266 + u32 off; 267 + }; 268 + 269 + struct cdns_torrent_vals { 270 + struct cdns_reg_pairs *reg_pairs; 271 + u32 num_regs; 272 + }; 273 + 330 274 struct cdns_torrent_data { 331 - u8 block_offset_shift; 332 - u8 reg_offset_shift; 275 + u8 block_offset_shift; 276 + u8 reg_offset_shift; 277 + struct cdns_torrent_vals *link_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 278 + [NUM_SSC_MODE]; 279 + struct cdns_torrent_vals *xcvr_diag_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 280 + [NUM_SSC_MODE]; 281 + struct cdns_torrent_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 282 + [NUM_SSC_MODE]; 283 + struct cdns_torrent_vals *cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 284 + [NUM_SSC_MODE]; 285 + struct cdns_torrent_vals *tx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 286 + [NUM_SSC_MODE]; 287 + struct cdns_torrent_vals *rx_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] 288 + [NUM_SSC_MODE]; 333 289 }; 334 290 335 291 struct cdns_regmap_cdb_context { ··· 417 331 .reg_read = cdns_regmap_read, \ 418 332 } 419 333 420 - static struct regmap_config cdns_torrent_tx_lane_cdb_config[] = { 334 + static const struct regmap_config cdns_torrent_tx_lane_cdb_config[] = { 421 335 TORRENT_TX_LANE_CDB_REGMAP_CONF("0"), 422 336 TORRENT_TX_LANE_CDB_REGMAP_CONF("1"), 423 337 TORRENT_TX_LANE_CDB_REGMAP_CONF("2"), 424 338 TORRENT_TX_LANE_CDB_REGMAP_CONF("3"), 425 339 }; 426 340 427 - static struct regmap_config cdns_torrent_rx_lane_cdb_config[] = { 341 + static const struct regmap_config cdns_torrent_rx_lane_cdb_config[] = { 428 342 TORRENT_RX_LANE_CDB_REGMAP_CONF("0"), 429 343 TORRENT_RX_LANE_CDB_REGMAP_CONF("1"), 430 344 TORRENT_RX_LANE_CDB_REGMAP_CONF("2"), 431 345 TORRENT_RX_LANE_CDB_REGMAP_CONF("3"), 432 346 }; 433 347 434 - static struct regmap_config cdns_torrent_common_cdb_config = { 348 + static const struct regmap_config cdns_torrent_common_cdb_config = { 435 349 .name = "torrent_common_cdb", 436 350 .reg_stride = 1, 437 351 .fast_io = true, ··· 439 353 .reg_read = cdns_regmap_read, 440 354 }; 441 355 442 - static struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = { 356 + static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = { 443 357 .name = "torrent_phy_pcs_cmn_cdb", 444 358 .reg_stride = 1, 445 359 .fast_io = true, ··· 447 361 .reg_read = cdns_regmap_read, 448 362 }; 449 363 450 - static struct regmap_config cdns_torrent_phy_pma_cmn_cdb_config = { 364 + static const struct regmap_config cdns_torrent_phy_pma_cmn_cdb_config = { 451 365 .name = "torrent_phy_pma_cmn_cdb", 452 366 .reg_stride = 1, 453 367 .fast_io = true, ··· 455 369 .reg_read = cdns_regmap_read, 456 370 }; 457 371 458 - static struct regmap_config cdns_torrent_dptx_phy_config = { 372 + static const struct regmap_config cdns_torrent_dptx_phy_config = { 459 373 .name = "torrent_dptx_phy", 460 374 .reg_stride = 1, 461 375 .fast_io = true, ··· 934 848 struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 935 849 struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 936 850 937 - ret = clk_prepare_enable(cdns_phy->clk); 938 - if (ret) { 939 - dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); 940 - return ret; 941 - } 942 - 943 - cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk); 944 - if (!(cdns_phy->ref_clk_rate)) { 945 - dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); 946 - clk_disable_unprepare(cdns_phy->clk); 947 - return -EINVAL; 948 - } 949 - 950 851 switch (cdns_phy->ref_clk_rate) { 951 852 case REF_CLK_19_2MHz: 952 853 case REF_CLK_25MHz: ··· 991 918 ret = cdns_torrent_dp_run(cdns_phy, inst->num_lanes); 992 919 993 920 return ret; 994 - } 995 - 996 - static int cdns_torrent_dp_exit(struct phy *phy) 997 - { 998 - struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 999 - 1000 - clk_disable_unprepare(cdns_phy->clk); 1001 - return 0; 1002 921 } 1003 922 1004 923 static ··· 1608 1543 { 1609 1544 struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 1610 1545 struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 1546 + u32 read_val; 1611 1547 int ret; 1612 1548 1613 - /* Take the PHY out of reset */ 1614 - ret = reset_control_deassert(cdns_phy->phy_rst); 1615 - if (ret) 1616 - return ret; 1549 + if (cdns_phy->nsubnodes == 1) { 1550 + /* Take the PHY lane group out of reset */ 1551 + reset_control_deassert(inst->lnk_rst); 1617 1552 1618 - /* Take the PHY lane group out of reset */ 1619 - return reset_control_deassert(inst->lnk_rst); 1553 + /* Take the PHY out of reset */ 1554 + ret = reset_control_deassert(cdns_phy->phy_rst); 1555 + if (ret) 1556 + return ret; 1557 + } 1558 + 1559 + /* 1560 + * Wait for cmn_ready assertion 1561 + * PHY_PMA_CMN_CTRL1[0] == 1 1562 + */ 1563 + ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_1, 1564 + read_val, read_val, 1000, 1565 + PLL_LOCK_TIMEOUT); 1566 + if (ret) { 1567 + dev_err(cdns_phy->dev, "Timeout waiting for CMN ready\n"); 1568 + return ret; 1569 + } 1570 + 1571 + mdelay(10); 1572 + 1573 + return 0; 1620 1574 } 1621 1575 1622 1576 static int cdns_torrent_phy_off(struct phy *phy) ··· 1643 1559 struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 1644 1560 struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 1645 1561 int ret; 1562 + 1563 + if (cdns_phy->nsubnodes != 1) 1564 + return 0; 1646 1565 1647 1566 ret = reset_control_assert(cdns_phy->phy_rst); 1648 1567 if (ret) ··· 1672 1585 return devm_regmap_init(dev, NULL, ctx, config); 1673 1586 } 1674 1587 1675 - static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy) 1588 + static int cdns_torrent_dp_regfield_init(struct cdns_torrent_phy *cdns_phy) 1589 + { 1590 + struct device *dev = cdns_phy->dev; 1591 + struct regmap_field *field; 1592 + struct regmap *regmap; 1593 + 1594 + regmap = cdns_phy->regmap_dptx_phy_reg; 1595 + field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl); 1596 + if (IS_ERR(field)) { 1597 + dev_err(dev, "PHY_RESET reg field init failed\n"); 1598 + return PTR_ERR(field); 1599 + } 1600 + cdns_phy->phy_reset_ctrl = field; 1601 + 1602 + return 0; 1603 + } 1604 + 1605 + static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy) 1676 1606 { 1677 1607 struct device *dev = cdns_phy->dev; 1678 1608 struct regmap_field *field; ··· 1702 1598 return PTR_ERR(field); 1703 1599 } 1704 1600 cdns_phy->phy_pll_cfg = field; 1601 + 1602 + regmap = cdns_phy->regmap_phy_pma_common_cdb; 1603 + field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1); 1604 + if (IS_ERR(field)) { 1605 + dev_err(dev, "PHY_PMA_CMN_CTRL1 reg field init failed\n"); 1606 + return PTR_ERR(field); 1607 + } 1608 + cdns_phy->phy_pma_cmn_ctrl_1 = field; 1705 1609 1706 1610 regmap = cdns_phy->regmap_phy_pma_common_cdb; 1707 1611 field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2); ··· 1727 1615 } 1728 1616 cdns_phy->phy_pma_pll_raw_ctrl = field; 1729 1617 1730 - regmap = cdns_phy->regmap_dptx_phy_reg; 1731 - field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl); 1732 - if (IS_ERR(field)) { 1733 - dev_err(dev, "PHY_RESET reg field init failed\n"); 1734 - return PTR_ERR(field); 1618 + return 0; 1619 + } 1620 + 1621 + static int cdns_torrent_dp_regmap_init(struct cdns_torrent_phy *cdns_phy) 1622 + { 1623 + void __iomem *base = cdns_phy->base; 1624 + struct device *dev = cdns_phy->dev; 1625 + struct regmap *regmap; 1626 + u8 reg_offset_shift; 1627 + u32 block_offset; 1628 + 1629 + reg_offset_shift = cdns_phy->init_data->reg_offset_shift; 1630 + 1631 + block_offset = TORRENT_DPTX_PHY_OFFSET; 1632 + regmap = cdns_regmap_init(dev, base, block_offset, 1633 + reg_offset_shift, 1634 + &cdns_torrent_dptx_phy_config); 1635 + if (IS_ERR(regmap)) { 1636 + dev_err(dev, "Failed to init DPTX PHY regmap\n"); 1637 + return PTR_ERR(regmap); 1735 1638 } 1736 - cdns_phy->phy_reset_ctrl = field; 1639 + cdns_phy->regmap_dptx_phy_reg = regmap; 1737 1640 1738 1641 return 0; 1739 1642 } 1740 1643 1741 - static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy, 1742 - void __iomem *sd_base, 1743 - void __iomem *base, 1744 - u8 block_offset_shift, 1745 - u8 reg_offset_shift) 1644 + static int cdns_torrent_regmap_init(struct cdns_torrent_phy *cdns_phy) 1746 1645 { 1646 + void __iomem *sd_base = cdns_phy->sd_base; 1647 + u8 block_offset_shift, reg_offset_shift; 1747 1648 struct device *dev = cdns_phy->dev; 1748 1649 struct regmap *regmap; 1749 1650 u32 block_offset; 1750 1651 int i; 1652 + 1653 + block_offset_shift = cdns_phy->init_data->block_offset_shift; 1654 + reg_offset_shift = cdns_phy->init_data->reg_offset_shift; 1751 1655 1752 1656 for (i = 0; i < MAX_NUM_LANES; i++) { 1753 1657 block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift, ··· 1819 1691 } 1820 1692 cdns_phy->regmap_phy_pma_common_cdb = regmap; 1821 1693 1822 - block_offset = TORRENT_DPTX_PHY_OFFSET; 1823 - regmap = cdns_regmap_init(dev, base, block_offset, 1824 - reg_offset_shift, 1825 - &cdns_torrent_dptx_phy_config); 1826 - if (IS_ERR(regmap)) { 1827 - dev_err(dev, "Failed to init DPTX PHY regmap\n"); 1828 - return PTR_ERR(regmap); 1694 + return 0; 1695 + } 1696 + 1697 + static int cdns_torrent_phy_init(struct phy *phy) 1698 + { 1699 + struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 1700 + const struct cdns_torrent_data *init_data = cdns_phy->init_data; 1701 + struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; 1702 + struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; 1703 + struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 1704 + enum cdns_torrent_phy_type phy_type = inst->phy_type; 1705 + enum cdns_torrent_ssc_mode ssc = inst->ssc_mode; 1706 + struct cdns_torrent_vals *pcs_cmn_vals; 1707 + struct cdns_reg_pairs *reg_pairs; 1708 + struct regmap *regmap; 1709 + u32 num_regs; 1710 + int i, j; 1711 + 1712 + if (cdns_phy->nsubnodes > 1) 1713 + return 0; 1714 + 1715 + if (phy_type == TYPE_DP) 1716 + return cdns_torrent_dp_init(phy); 1717 + 1718 + /** 1719 + * Spread spectrum generation is not required or supported 1720 + * for SGMII/QSGMII 1721 + */ 1722 + if (phy_type == TYPE_SGMII || phy_type == TYPE_QSGMII) 1723 + ssc = NO_SSC; 1724 + 1725 + /* PHY configuration specific registers for single link */ 1726 + link_cmn_vals = init_data->link_cmn_vals[phy_type][TYPE_NONE][ssc]; 1727 + if (link_cmn_vals) { 1728 + reg_pairs = link_cmn_vals->reg_pairs; 1729 + num_regs = link_cmn_vals->num_regs; 1730 + regmap = cdns_phy->regmap_common_cdb; 1731 + 1732 + /** 1733 + * First array value in link_cmn_vals must be of 1734 + * PHY_PLL_CFG register 1735 + */ 1736 + regmap_field_write(cdns_phy->phy_pll_cfg, reg_pairs[0].val); 1737 + 1738 + for (i = 1; i < num_regs; i++) 1739 + regmap_write(regmap, reg_pairs[i].off, 1740 + reg_pairs[i].val); 1829 1741 } 1830 - cdns_phy->regmap_dptx_phy_reg = regmap; 1742 + 1743 + xcvr_diag_vals = init_data->xcvr_diag_vals[phy_type][TYPE_NONE][ssc]; 1744 + if (xcvr_diag_vals) { 1745 + reg_pairs = xcvr_diag_vals->reg_pairs; 1746 + num_regs = xcvr_diag_vals->num_regs; 1747 + for (i = 0; i < inst->num_lanes; i++) { 1748 + regmap = cdns_phy->regmap_tx_lane_cdb[i + inst->mlane]; 1749 + for (j = 0; j < num_regs; j++) 1750 + regmap_write(regmap, reg_pairs[j].off, 1751 + reg_pairs[j].val); 1752 + } 1753 + } 1754 + 1755 + /* PHY PCS common registers configurations */ 1756 + pcs_cmn_vals = init_data->pcs_cmn_vals[phy_type][TYPE_NONE][ssc]; 1757 + if (pcs_cmn_vals) { 1758 + reg_pairs = pcs_cmn_vals->reg_pairs; 1759 + num_regs = pcs_cmn_vals->num_regs; 1760 + regmap = cdns_phy->regmap_phy_pcs_common_cdb; 1761 + for (i = 0; i < num_regs; i++) 1762 + regmap_write(regmap, reg_pairs[i].off, 1763 + reg_pairs[i].val); 1764 + } 1765 + 1766 + /* PMA common registers configurations */ 1767 + cmn_vals = init_data->cmn_vals[phy_type][TYPE_NONE][ssc]; 1768 + if (cmn_vals) { 1769 + reg_pairs = cmn_vals->reg_pairs; 1770 + num_regs = cmn_vals->num_regs; 1771 + regmap = cdns_phy->regmap_common_cdb; 1772 + for (i = 0; i < num_regs; i++) 1773 + regmap_write(regmap, reg_pairs[i].off, 1774 + reg_pairs[i].val); 1775 + } 1776 + 1777 + /* PMA TX lane registers configurations */ 1778 + tx_ln_vals = init_data->tx_ln_vals[phy_type][TYPE_NONE][ssc]; 1779 + if (tx_ln_vals) { 1780 + reg_pairs = tx_ln_vals->reg_pairs; 1781 + num_regs = tx_ln_vals->num_regs; 1782 + for (i = 0; i < inst->num_lanes; i++) { 1783 + regmap = cdns_phy->regmap_tx_lane_cdb[i + inst->mlane]; 1784 + for (j = 0; j < num_regs; j++) 1785 + regmap_write(regmap, reg_pairs[j].off, 1786 + reg_pairs[j].val); 1787 + } 1788 + } 1789 + 1790 + /* PMA RX lane registers configurations */ 1791 + rx_ln_vals = init_data->rx_ln_vals[phy_type][TYPE_NONE][ssc]; 1792 + if (rx_ln_vals) { 1793 + reg_pairs = rx_ln_vals->reg_pairs; 1794 + num_regs = rx_ln_vals->num_regs; 1795 + for (i = 0; i < inst->num_lanes; i++) { 1796 + regmap = cdns_phy->regmap_rx_lane_cdb[i + inst->mlane]; 1797 + for (j = 0; j < num_regs; j++) 1798 + regmap_write(regmap, reg_pairs[j].off, 1799 + reg_pairs[j].val); 1800 + } 1801 + } 1802 + 1803 + return 0; 1804 + } 1805 + 1806 + static 1807 + int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) 1808 + { 1809 + const struct cdns_torrent_data *init_data = cdns_phy->init_data; 1810 + struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; 1811 + struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; 1812 + enum cdns_torrent_phy_type phy_t1, phy_t2, tmp_phy_type; 1813 + struct cdns_torrent_vals *pcs_cmn_vals; 1814 + int i, j, node, mlane, num_lanes, ret; 1815 + struct cdns_reg_pairs *reg_pairs; 1816 + enum cdns_torrent_ssc_mode ssc; 1817 + struct regmap *regmap; 1818 + u32 num_regs; 1819 + 1820 + /* Maximum 2 links (subnodes) are supported */ 1821 + if (cdns_phy->nsubnodes != 2) 1822 + return -EINVAL; 1823 + 1824 + phy_t1 = cdns_phy->phys[0].phy_type; 1825 + phy_t2 = cdns_phy->phys[1].phy_type; 1826 + 1827 + /** 1828 + * First configure the PHY for first link with phy_t1. Get the array 1829 + * values as [phy_t1][phy_t2][ssc]. 1830 + */ 1831 + for (node = 0; node < cdns_phy->nsubnodes; node++) { 1832 + if (node == 1) { 1833 + /** 1834 + * If first link with phy_t1 is configured, then 1835 + * configure the PHY for second link with phy_t2. 1836 + * Get the array values as [phy_t2][phy_t1][ssc]. 1837 + */ 1838 + tmp_phy_type = phy_t1; 1839 + phy_t1 = phy_t2; 1840 + phy_t2 = tmp_phy_type; 1841 + } 1842 + 1843 + mlane = cdns_phy->phys[node].mlane; 1844 + ssc = cdns_phy->phys[node].ssc_mode; 1845 + num_lanes = cdns_phy->phys[node].num_lanes; 1846 + 1847 + /** 1848 + * PHY configuration specific registers: 1849 + * link_cmn_vals depend on combination of PHY types being 1850 + * configured and are common for both PHY types, so array 1851 + * values should be same for [phy_t1][phy_t2][ssc] and 1852 + * [phy_t2][phy_t1][ssc]. 1853 + * xcvr_diag_vals also depend on combination of PHY types 1854 + * being configured, but these can be different for particular 1855 + * PHY type and are per lane. 1856 + */ 1857 + link_cmn_vals = init_data->link_cmn_vals[phy_t1][phy_t2][ssc]; 1858 + if (link_cmn_vals) { 1859 + reg_pairs = link_cmn_vals->reg_pairs; 1860 + num_regs = link_cmn_vals->num_regs; 1861 + regmap = cdns_phy->regmap_common_cdb; 1862 + 1863 + /** 1864 + * First array value in link_cmn_vals must be of 1865 + * PHY_PLL_CFG register 1866 + */ 1867 + regmap_field_write(cdns_phy->phy_pll_cfg, 1868 + reg_pairs[0].val); 1869 + 1870 + for (i = 1; i < num_regs; i++) 1871 + regmap_write(regmap, reg_pairs[i].off, 1872 + reg_pairs[i].val); 1873 + } 1874 + 1875 + xcvr_diag_vals = init_data->xcvr_diag_vals[phy_t1][phy_t2][ssc]; 1876 + if (xcvr_diag_vals) { 1877 + reg_pairs = xcvr_diag_vals->reg_pairs; 1878 + num_regs = xcvr_diag_vals->num_regs; 1879 + for (i = 0; i < num_lanes; i++) { 1880 + regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; 1881 + for (j = 0; j < num_regs; j++) 1882 + regmap_write(regmap, reg_pairs[j].off, 1883 + reg_pairs[j].val); 1884 + } 1885 + } 1886 + 1887 + /* PHY PCS common registers configurations */ 1888 + pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc]; 1889 + if (pcs_cmn_vals) { 1890 + reg_pairs = pcs_cmn_vals->reg_pairs; 1891 + num_regs = pcs_cmn_vals->num_regs; 1892 + regmap = cdns_phy->regmap_phy_pcs_common_cdb; 1893 + for (i = 0; i < num_regs; i++) 1894 + regmap_write(regmap, reg_pairs[i].off, 1895 + reg_pairs[i].val); 1896 + } 1897 + 1898 + /* PMA common registers configurations */ 1899 + cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc]; 1900 + if (cmn_vals) { 1901 + reg_pairs = cmn_vals->reg_pairs; 1902 + num_regs = cmn_vals->num_regs; 1903 + regmap = cdns_phy->regmap_common_cdb; 1904 + for (i = 0; i < num_regs; i++) 1905 + regmap_write(regmap, reg_pairs[i].off, 1906 + reg_pairs[i].val); 1907 + } 1908 + 1909 + /* PMA TX lane registers configurations */ 1910 + tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc]; 1911 + if (tx_ln_vals) { 1912 + reg_pairs = tx_ln_vals->reg_pairs; 1913 + num_regs = tx_ln_vals->num_regs; 1914 + for (i = 0; i < num_lanes; i++) { 1915 + regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; 1916 + for (j = 0; j < num_regs; j++) 1917 + regmap_write(regmap, reg_pairs[j].off, 1918 + reg_pairs[j].val); 1919 + } 1920 + } 1921 + 1922 + /* PMA RX lane registers configurations */ 1923 + rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc]; 1924 + if (rx_ln_vals) { 1925 + reg_pairs = rx_ln_vals->reg_pairs; 1926 + num_regs = rx_ln_vals->num_regs; 1927 + for (i = 0; i < num_lanes; i++) { 1928 + regmap = cdns_phy->regmap_rx_lane_cdb[i + mlane]; 1929 + for (j = 0; j < num_regs; j++) 1930 + regmap_write(regmap, reg_pairs[j].off, 1931 + reg_pairs[j].val); 1932 + } 1933 + } 1934 + 1935 + reset_control_deassert(cdns_phy->phys[node].lnk_rst); 1936 + } 1937 + 1938 + /* Take the PHY out of reset */ 1939 + ret = reset_control_deassert(cdns_phy->phy_rst); 1940 + if (ret) 1941 + return ret; 1831 1942 1832 1943 return 0; 1833 1944 } 1834 1945 1835 1946 static int cdns_torrent_phy_probe(struct platform_device *pdev) 1836 1947 { 1837 - struct resource *regs; 1838 1948 struct cdns_torrent_phy *cdns_phy; 1839 1949 struct device *dev = &pdev->dev; 1840 1950 struct phy_provider *phy_provider; 1841 - const struct of_device_id *match; 1842 - struct cdns_torrent_data *data; 1951 + const struct cdns_torrent_data *data; 1843 1952 struct device_node *child; 1844 1953 int ret, subnodes, node = 0, i; 1954 + u32 total_num_lanes = 0; 1955 + u8 init_dp_regmap = 0; 1956 + u32 phy_type; 1845 1957 1846 1958 /* Get init data for this PHY */ 1847 - match = of_match_device(cdns_torrent_phy_of_match, dev); 1848 - if (!match) 1959 + data = of_device_get_match_data(dev); 1960 + if (!data) 1849 1961 return -EINVAL; 1850 - 1851 - data = (struct cdns_torrent_data *)match->data; 1852 1962 1853 1963 cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL); 1854 1964 if (!cdns_phy) ··· 2094 1728 2095 1729 dev_set_drvdata(dev, cdns_phy); 2096 1730 cdns_phy->dev = dev; 1731 + cdns_phy->init_data = data; 2097 1732 2098 1733 cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0); 2099 1734 if (IS_ERR(cdns_phy->phy_rst)) { ··· 2103 1736 return PTR_ERR(cdns_phy->phy_rst); 2104 1737 } 2105 1738 1739 + cdns_phy->apb_rst = devm_reset_control_get_optional(dev, "torrent_apb"); 1740 + if (IS_ERR(cdns_phy->apb_rst)) { 1741 + dev_err(dev, "%s: failed to get apb reset\n", 1742 + dev->of_node->full_name); 1743 + return PTR_ERR(cdns_phy->apb_rst); 1744 + } 1745 + 2106 1746 cdns_phy->clk = devm_clk_get(dev, "refclk"); 2107 1747 if (IS_ERR(cdns_phy->clk)) { 2108 1748 dev_err(dev, "phy ref clock not found\n"); 2109 1749 return PTR_ERR(cdns_phy->clk); 2110 1750 } 2111 1751 2112 - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2113 - cdns_phy->sd_base = devm_ioremap_resource(&pdev->dev, regs); 1752 + cdns_phy->sd_base = devm_platform_ioremap_resource(pdev, 0); 2114 1753 if (IS_ERR(cdns_phy->sd_base)) 2115 1754 return PTR_ERR(cdns_phy->sd_base); 2116 1755 ··· 2124 1751 if (subnodes == 0) { 2125 1752 dev_err(dev, "No available link subnodes found\n"); 2126 1753 return -EINVAL; 2127 - } else if (subnodes != 1) { 2128 - dev_err(dev, "Driver supports only one link subnode.\n"); 1754 + } 1755 + 1756 + ret = cdns_torrent_regmap_init(cdns_phy); 1757 + if (ret) 1758 + return ret; 1759 + 1760 + ret = cdns_torrent_regfield_init(cdns_phy); 1761 + if (ret) 1762 + return ret; 1763 + 1764 + ret = clk_prepare_enable(cdns_phy->clk); 1765 + if (ret) { 1766 + dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); 1767 + return ret; 1768 + } 1769 + 1770 + cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk); 1771 + if (!(cdns_phy->ref_clk_rate)) { 1772 + dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); 1773 + clk_disable_unprepare(cdns_phy->clk); 2129 1774 return -EINVAL; 2130 1775 } 2131 1776 1777 + /* Enable APB */ 1778 + reset_control_deassert(cdns_phy->apb_rst); 1779 + 2132 1780 for_each_available_child_of_node(dev->of_node, child) { 2133 1781 struct phy *gphy; 1782 + 1783 + /* PHY subnode name must be 'phy'. */ 1784 + if (!(of_node_name_eq(child, "phy"))) 1785 + continue; 2134 1786 2135 1787 cdns_phy->phys[node].lnk_rst = 2136 1788 of_reset_control_array_get_exclusive(child); ··· 2174 1776 goto put_child; 2175 1777 } 2176 1778 2177 - if (cdns_phy->phys[node].mlane != 0) { 2178 - dev_err(dev, 2179 - "%s: Driver supports only lane-0 as master lane.\n", 2180 - child->full_name); 2181 - ret = -EINVAL; 2182 - goto put_child; 2183 - } 2184 - 2185 - if (of_property_read_u32(child, "cdns,phy-type", 2186 - &cdns_phy->phys[node].phy_type)) { 1779 + if (of_property_read_u32(child, "cdns,phy-type", &phy_type)) { 2187 1780 dev_err(dev, "%s: No \"cdns,phy-type\"-property.\n", 2188 1781 child->full_name); 2189 1782 ret = -EINVAL; 2190 1783 goto put_child; 2191 1784 } 2192 1785 2193 - cdns_phy->phys[node].num_lanes = DEFAULT_NUM_LANES; 2194 - of_property_read_u32(child, "cdns,num-lanes", 2195 - &cdns_phy->phys[node].num_lanes); 1786 + switch (phy_type) { 1787 + case PHY_TYPE_PCIE: 1788 + cdns_phy->phys[node].phy_type = TYPE_PCIE; 1789 + break; 1790 + case PHY_TYPE_DP: 1791 + cdns_phy->phys[node].phy_type = TYPE_DP; 1792 + break; 1793 + case PHY_TYPE_SGMII: 1794 + cdns_phy->phys[node].phy_type = TYPE_SGMII; 1795 + break; 1796 + case PHY_TYPE_QSGMII: 1797 + cdns_phy->phys[node].phy_type = TYPE_QSGMII; 1798 + break; 1799 + case PHY_TYPE_USB3: 1800 + cdns_phy->phys[node].phy_type = TYPE_USB; 1801 + break; 1802 + default: 1803 + dev_err(dev, "Unsupported protocol\n"); 1804 + ret = -EINVAL; 1805 + goto put_child; 1806 + } 2196 1807 2197 - if (cdns_phy->phys[node].phy_type == PHY_TYPE_DP) { 1808 + if (of_property_read_u32(child, "cdns,num-lanes", 1809 + &cdns_phy->phys[node].num_lanes)) { 1810 + dev_err(dev, "%s: No \"cdns,num-lanes\"-property.\n", 1811 + child->full_name); 1812 + ret = -EINVAL; 1813 + goto put_child; 1814 + } 1815 + 1816 + total_num_lanes += cdns_phy->phys[node].num_lanes; 1817 + 1818 + /* Get SSC mode */ 1819 + cdns_phy->phys[node].ssc_mode = NO_SSC; 1820 + of_property_read_u32(child, "cdns,ssc-mode", 1821 + &cdns_phy->phys[node].ssc_mode); 1822 + 1823 + gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops); 1824 + if (IS_ERR(gphy)) { 1825 + ret = PTR_ERR(gphy); 1826 + goto put_child; 1827 + } 1828 + 1829 + if (cdns_phy->phys[node].phy_type == TYPE_DP) { 2198 1830 switch (cdns_phy->phys[node].num_lanes) { 2199 1831 case 1: 2200 1832 case 2: ··· 2261 1833 } 2262 1834 2263 1835 /* DPTX registers */ 2264 - regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); 2265 - cdns_phy->base = devm_ioremap_resource(&pdev->dev, 2266 - regs); 1836 + cdns_phy->base = devm_platform_ioremap_resource(pdev, 1); 2267 1837 if (IS_ERR(cdns_phy->base)) { 2268 1838 ret = PTR_ERR(cdns_phy->base); 2269 1839 goto put_child; 2270 1840 } 2271 1841 2272 - gphy = devm_phy_create(dev, child, 2273 - &cdns_torrent_phy_ops); 2274 - if (IS_ERR(gphy)) { 2275 - ret = PTR_ERR(gphy); 2276 - goto put_child; 1842 + if (!init_dp_regmap) { 1843 + ret = cdns_torrent_dp_regmap_init(cdns_phy); 1844 + if (ret) 1845 + goto put_child; 1846 + 1847 + ret = cdns_torrent_dp_regfield_init(cdns_phy); 1848 + if (ret) 1849 + goto put_child; 1850 + 1851 + init_dp_regmap++; 2277 1852 } 2278 1853 2279 1854 dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n", 2280 1855 cdns_phy->phys[node].num_lanes, 2281 1856 cdns_phy->max_bit_rate / 1000, 2282 1857 cdns_phy->max_bit_rate % 1000); 2283 - } else { 2284 - dev_err(dev, "Driver supports only PHY_TYPE_DP\n"); 2285 - ret = -ENOTSUPP; 2286 - goto put_child; 1858 + 1859 + gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes; 1860 + gphy->attrs.max_link_rate = cdns_phy->max_bit_rate; 1861 + gphy->attrs.mode = PHY_MODE_DP; 2287 1862 } 1863 + 2288 1864 cdns_phy->phys[node].phy = gphy; 2289 1865 phy_set_drvdata(gphy, &cdns_phy->phys[node]); 2290 1866 ··· 2296 1864 } 2297 1865 cdns_phy->nsubnodes = node; 2298 1866 2299 - ret = cdns_regmap_init_torrent_dp(cdns_phy, cdns_phy->sd_base, 2300 - cdns_phy->base, 2301 - data->block_offset_shift, 2302 - data->reg_offset_shift); 2303 - if (ret) 1867 + if (total_num_lanes > MAX_NUM_LANES) { 1868 + dev_err(dev, "Invalid lane configuration\n"); 2304 1869 goto put_lnk_rst; 1870 + } 2305 1871 2306 - ret = cdns_regfield_init(cdns_phy); 2307 - if (ret) 2308 - goto put_lnk_rst; 1872 + if (cdns_phy->nsubnodes > 1) { 1873 + ret = cdns_torrent_phy_configure_multilink(cdns_phy); 1874 + if (ret) 1875 + goto put_lnk_rst; 1876 + } 2309 1877 2310 1878 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 2311 1879 if (IS_ERR(phy_provider)) { ··· 2321 1889 for (i = 0; i < node; i++) 2322 1890 reset_control_put(cdns_phy->phys[i].lnk_rst); 2323 1891 of_node_put(child); 1892 + reset_control_assert(cdns_phy->apb_rst); 1893 + clk_disable_unprepare(cdns_phy->clk); 2324 1894 return ret; 2325 1895 } 2326 1896 ··· 2332 1898 int i; 2333 1899 2334 1900 reset_control_assert(cdns_phy->phy_rst); 1901 + reset_control_assert(cdns_phy->apb_rst); 2335 1902 for (i = 0; i < cdns_phy->nsubnodes; i++) { 2336 1903 reset_control_assert(cdns_phy->phys[i].lnk_rst); 2337 1904 reset_control_put(cdns_phy->phys[i].lnk_rst); 2338 1905 } 2339 1906 1907 + clk_disable_unprepare(cdns_phy->clk); 1908 + 2340 1909 return 0; 2341 1910 } 1911 + 1912 + /* USB and SGMII/QSGMII link configuration */ 1913 + static struct cdns_reg_pairs usb_sgmii_link_cmn_regs[] = { 1914 + {0x0002, PHY_PLL_CFG}, 1915 + {0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0}, 1916 + {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0} 1917 + }; 1918 + 1919 + static struct cdns_reg_pairs usb_sgmii_xcvr_diag_ln_regs[] = { 1920 + {0x0000, XCVR_DIAG_HSCLK_SEL}, 1921 + {0x0001, XCVR_DIAG_HSCLK_DIV}, 1922 + {0x0041, XCVR_DIAG_PLLDRC_CTRL} 1923 + }; 1924 + 1925 + static struct cdns_reg_pairs sgmii_usb_xcvr_diag_ln_regs[] = { 1926 + {0x0011, XCVR_DIAG_HSCLK_SEL}, 1927 + {0x0003, XCVR_DIAG_HSCLK_DIV}, 1928 + {0x009B, XCVR_DIAG_PLLDRC_CTRL} 1929 + }; 1930 + 1931 + static struct cdns_torrent_vals usb_sgmii_link_cmn_vals = { 1932 + .reg_pairs = usb_sgmii_link_cmn_regs, 1933 + .num_regs = ARRAY_SIZE(usb_sgmii_link_cmn_regs), 1934 + }; 1935 + 1936 + static struct cdns_torrent_vals usb_sgmii_xcvr_diag_ln_vals = { 1937 + .reg_pairs = usb_sgmii_xcvr_diag_ln_regs, 1938 + .num_regs = ARRAY_SIZE(usb_sgmii_xcvr_diag_ln_regs), 1939 + }; 1940 + 1941 + static struct cdns_torrent_vals sgmii_usb_xcvr_diag_ln_vals = { 1942 + .reg_pairs = sgmii_usb_xcvr_diag_ln_regs, 1943 + .num_regs = ARRAY_SIZE(sgmii_usb_xcvr_diag_ln_regs), 1944 + }; 1945 + 1946 + /* PCIe and USB Unique SSC link configuration */ 1947 + static struct cdns_reg_pairs pcie_usb_link_cmn_regs[] = { 1948 + {0x0003, PHY_PLL_CFG}, 1949 + {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}, 1950 + {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1}, 1951 + {0x8600, CMN_PDIAG_PLL1_CLK_SEL_M0} 1952 + }; 1953 + 1954 + static struct cdns_reg_pairs pcie_usb_xcvr_diag_ln_regs[] = { 1955 + {0x0000, XCVR_DIAG_HSCLK_SEL}, 1956 + {0x0001, XCVR_DIAG_HSCLK_DIV}, 1957 + {0x0012, XCVR_DIAG_PLLDRC_CTRL} 1958 + }; 1959 + 1960 + static struct cdns_reg_pairs usb_pcie_xcvr_diag_ln_regs[] = { 1961 + {0x0011, XCVR_DIAG_HSCLK_SEL}, 1962 + {0x0001, XCVR_DIAG_HSCLK_DIV}, 1963 + {0x00C9, XCVR_DIAG_PLLDRC_CTRL} 1964 + }; 1965 + 1966 + static struct cdns_torrent_vals pcie_usb_link_cmn_vals = { 1967 + .reg_pairs = pcie_usb_link_cmn_regs, 1968 + .num_regs = ARRAY_SIZE(pcie_usb_link_cmn_regs), 1969 + }; 1970 + 1971 + static struct cdns_torrent_vals pcie_usb_xcvr_diag_ln_vals = { 1972 + .reg_pairs = pcie_usb_xcvr_diag_ln_regs, 1973 + .num_regs = ARRAY_SIZE(pcie_usb_xcvr_diag_ln_regs), 1974 + }; 1975 + 1976 + static struct cdns_torrent_vals usb_pcie_xcvr_diag_ln_vals = { 1977 + .reg_pairs = usb_pcie_xcvr_diag_ln_regs, 1978 + .num_regs = ARRAY_SIZE(usb_pcie_xcvr_diag_ln_regs), 1979 + }; 1980 + 1981 + /* USB 100 MHz Ref clk, internal SSC */ 1982 + static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = { 1983 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 1984 + {0x0004, CMN_PLL0_DSM_DIAG_M1}, 1985 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 1986 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 1987 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1}, 1988 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 1989 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 1990 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1}, 1991 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 1992 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 1993 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1}, 1994 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 1995 + {0x0064, CMN_PLL0_INTDIV_M0}, 1996 + {0x0050, CMN_PLL0_INTDIV_M1}, 1997 + {0x0064, CMN_PLL1_INTDIV_M0}, 1998 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 1999 + {0x0002, CMN_PLL0_FRACDIVH_M1}, 2000 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2001 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2002 + {0x0036, CMN_PLL0_HIGH_THR_M1}, 2003 + {0x0044, CMN_PLL1_HIGH_THR_M0}, 2004 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2005 + {0x0002, CMN_PDIAG_PLL0_CTRL_M1}, 2006 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2007 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2008 + {0x0001, CMN_PLL0_SS_CTRL1_M1}, 2009 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2010 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2011 + {0x011B, CMN_PLL0_SS_CTRL2_M1}, 2012 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2013 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2014 + {0x0058, CMN_PLL0_SS_CTRL3_M1}, 2015 + {0x006E, CMN_PLL1_SS_CTRL3_M0}, 2016 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2017 + {0x0012, CMN_PLL0_SS_CTRL4_M1}, 2018 + {0x000E, CMN_PLL1_SS_CTRL4_M0}, 2019 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2020 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2021 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2022 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2023 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2024 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2025 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2026 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2027 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2028 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2029 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2030 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR}, 2031 + {0x8200, CMN_CDIAG_CDB_PWRI_OVRD}, 2032 + {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD} 2033 + }; 2034 + 2035 + static struct cdns_torrent_vals usb_100_int_ssc_cmn_vals = { 2036 + .reg_pairs = usb_100_int_ssc_cmn_regs, 2037 + .num_regs = ARRAY_SIZE(usb_100_int_ssc_cmn_regs), 2038 + }; 2039 + 2040 + /* Single USB link configuration */ 2041 + static struct cdns_reg_pairs sl_usb_link_cmn_regs[] = { 2042 + {0x0000, PHY_PLL_CFG}, 2043 + {0x8600, CMN_PDIAG_PLL0_CLK_SEL_M0} 2044 + }; 2045 + 2046 + static struct cdns_reg_pairs sl_usb_xcvr_diag_ln_regs[] = { 2047 + {0x0000, XCVR_DIAG_HSCLK_SEL}, 2048 + {0x0001, XCVR_DIAG_HSCLK_DIV}, 2049 + {0x0041, XCVR_DIAG_PLLDRC_CTRL} 2050 + }; 2051 + 2052 + static struct cdns_torrent_vals sl_usb_link_cmn_vals = { 2053 + .reg_pairs = sl_usb_link_cmn_regs, 2054 + .num_regs = ARRAY_SIZE(sl_usb_link_cmn_regs), 2055 + }; 2056 + 2057 + static struct cdns_torrent_vals sl_usb_xcvr_diag_ln_vals = { 2058 + .reg_pairs = sl_usb_xcvr_diag_ln_regs, 2059 + .num_regs = ARRAY_SIZE(sl_usb_xcvr_diag_ln_regs), 2060 + }; 2061 + 2062 + /* USB PHY PCS common configuration */ 2063 + static struct cdns_reg_pairs usb_phy_pcs_cmn_regs[] = { 2064 + {0x0A0A, PHY_PIPE_USB3_GEN2_PRE_CFG0}, 2065 + {0x1000, PHY_PIPE_USB3_GEN2_POST_CFG0}, 2066 + {0x0010, PHY_PIPE_USB3_GEN2_POST_CFG1} 2067 + }; 2068 + 2069 + static struct cdns_torrent_vals usb_phy_pcs_cmn_vals = { 2070 + .reg_pairs = usb_phy_pcs_cmn_regs, 2071 + .num_regs = ARRAY_SIZE(usb_phy_pcs_cmn_regs), 2072 + }; 2073 + 2074 + /* USB 100 MHz Ref clk, no SSC */ 2075 + static struct cdns_reg_pairs usb_100_no_ssc_cmn_regs[] = { 2076 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2077 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2078 + {0x8200, CMN_CDIAG_CDB_PWRI_OVRD}, 2079 + {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD} 2080 + }; 2081 + 2082 + static struct cdns_reg_pairs usb_100_no_ssc_tx_ln_regs[] = { 2083 + {0x02FF, TX_PSC_A0}, 2084 + {0x06AF, TX_PSC_A1}, 2085 + {0x06AE, TX_PSC_A2}, 2086 + {0x06AE, TX_PSC_A3}, 2087 + {0x2A82, TX_TXCC_CTRL}, 2088 + {0x0014, TX_TXCC_CPOST_MULT_01}, 2089 + {0x0003, XCVR_DIAG_PSC_OVRD} 2090 + }; 2091 + 2092 + static struct cdns_reg_pairs usb_100_no_ssc_rx_ln_regs[] = { 2093 + {0x0D1D, RX_PSC_A0}, 2094 + {0x0D1D, RX_PSC_A1}, 2095 + {0x0D00, RX_PSC_A2}, 2096 + {0x0500, RX_PSC_A3}, 2097 + {0x0013, RX_SIGDET_HL_FILT_TMR}, 2098 + {0x0000, RX_REE_GCSM1_CTRL}, 2099 + {0x0C02, RX_REE_ATTEN_THR}, 2100 + {0x0330, RX_REE_SMGM_CTRL1}, 2101 + {0x0300, RX_REE_SMGM_CTRL2}, 2102 + {0x0019, RX_REE_TAP1_CLIP}, 2103 + {0x0019, RX_REE_TAP2TON_CLIP}, 2104 + {0x1004, RX_DIAG_SIGDET_TUNE}, 2105 + {0x00F9, RX_DIAG_NQST_CTRL}, 2106 + {0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, 2107 + {0x0002, RX_DIAG_DFE_AMP_TUNE_3}, 2108 + {0x0000, RX_DIAG_PI_CAP}, 2109 + {0x0031, RX_DIAG_PI_RATE}, 2110 + {0x0001, RX_DIAG_ACYA}, 2111 + {0x018C, RX_CDRLF_CNFG}, 2112 + {0x0003, RX_CDRLF_CNFG3} 2113 + }; 2114 + 2115 + static struct cdns_torrent_vals usb_100_no_ssc_cmn_vals = { 2116 + .reg_pairs = usb_100_no_ssc_cmn_regs, 2117 + .num_regs = ARRAY_SIZE(usb_100_no_ssc_cmn_regs), 2118 + }; 2119 + 2120 + static struct cdns_torrent_vals usb_100_no_ssc_tx_ln_vals = { 2121 + .reg_pairs = usb_100_no_ssc_tx_ln_regs, 2122 + .num_regs = ARRAY_SIZE(usb_100_no_ssc_tx_ln_regs), 2123 + }; 2124 + 2125 + static struct cdns_torrent_vals usb_100_no_ssc_rx_ln_vals = { 2126 + .reg_pairs = usb_100_no_ssc_rx_ln_regs, 2127 + .num_regs = ARRAY_SIZE(usb_100_no_ssc_rx_ln_regs), 2128 + }; 2129 + 2130 + /* Single link USB, 100 MHz Ref clk, internal SSC */ 2131 + static struct cdns_reg_pairs sl_usb_100_int_ssc_cmn_regs[] = { 2132 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 2133 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 2134 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 2135 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 2136 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 2137 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 2138 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 2139 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 2140 + {0x0064, CMN_PLL0_INTDIV_M0}, 2141 + {0x0064, CMN_PLL1_INTDIV_M0}, 2142 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 2143 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2144 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2145 + {0x0044, CMN_PLL1_HIGH_THR_M0}, 2146 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2147 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2148 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2149 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2150 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2151 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2152 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2153 + {0x006E, CMN_PLL1_SS_CTRL3_M0}, 2154 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2155 + {0x000E, CMN_PLL1_SS_CTRL4_M0}, 2156 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2157 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2158 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2159 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2160 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2161 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2162 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2163 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2164 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2165 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2166 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2167 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR}, 2168 + {0x8200, CMN_CDIAG_CDB_PWRI_OVRD}, 2169 + {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD} 2170 + }; 2171 + 2172 + static struct cdns_torrent_vals sl_usb_100_int_ssc_cmn_vals = { 2173 + .reg_pairs = sl_usb_100_int_ssc_cmn_regs, 2174 + .num_regs = ARRAY_SIZE(sl_usb_100_int_ssc_cmn_regs), 2175 + }; 2176 + 2177 + /* PCIe and SGMII/QSGMII Unique SSC link configuration */ 2178 + static struct cdns_reg_pairs pcie_sgmii_link_cmn_regs[] = { 2179 + {0x0003, PHY_PLL_CFG}, 2180 + {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0}, 2181 + {0x0400, CMN_PDIAG_PLL0_CLK_SEL_M1}, 2182 + {0x0601, CMN_PDIAG_PLL1_CLK_SEL_M0} 2183 + }; 2184 + 2185 + static struct cdns_reg_pairs pcie_sgmii_xcvr_diag_ln_regs[] = { 2186 + {0x0000, XCVR_DIAG_HSCLK_SEL}, 2187 + {0x0001, XCVR_DIAG_HSCLK_DIV}, 2188 + {0x0012, XCVR_DIAG_PLLDRC_CTRL} 2189 + }; 2190 + 2191 + static struct cdns_reg_pairs sgmii_pcie_xcvr_diag_ln_regs[] = { 2192 + {0x0011, XCVR_DIAG_HSCLK_SEL}, 2193 + {0x0003, XCVR_DIAG_HSCLK_DIV}, 2194 + {0x009B, XCVR_DIAG_PLLDRC_CTRL} 2195 + }; 2196 + 2197 + static struct cdns_torrent_vals pcie_sgmii_link_cmn_vals = { 2198 + .reg_pairs = pcie_sgmii_link_cmn_regs, 2199 + .num_regs = ARRAY_SIZE(pcie_sgmii_link_cmn_regs), 2200 + }; 2201 + 2202 + static struct cdns_torrent_vals pcie_sgmii_xcvr_diag_ln_vals = { 2203 + .reg_pairs = pcie_sgmii_xcvr_diag_ln_regs, 2204 + .num_regs = ARRAY_SIZE(pcie_sgmii_xcvr_diag_ln_regs), 2205 + }; 2206 + 2207 + static struct cdns_torrent_vals sgmii_pcie_xcvr_diag_ln_vals = { 2208 + .reg_pairs = sgmii_pcie_xcvr_diag_ln_regs, 2209 + .num_regs = ARRAY_SIZE(sgmii_pcie_xcvr_diag_ln_regs), 2210 + }; 2211 + 2212 + /* SGMII 100 MHz Ref clk, no SSC */ 2213 + static struct cdns_reg_pairs sgmii_100_no_ssc_cmn_regs[] = { 2214 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2215 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2216 + {0x3700, CMN_DIAG_BIAS_OVRD1}, 2217 + {0x0008, CMN_TXPUCAL_TUNE}, 2218 + {0x0008, CMN_TXPDCAL_TUNE} 2219 + }; 2220 + 2221 + static struct cdns_reg_pairs sgmii_100_no_ssc_tx_ln_regs[] = { 2222 + {0x00F3, TX_PSC_A0}, 2223 + {0x04A2, TX_PSC_A2}, 2224 + {0x04A2, TX_PSC_A3}, 2225 + {0x0000, TX_TXCC_CPOST_MULT_00}, 2226 + {0x00B3, DRV_DIAG_TX_DRV} 2227 + }; 2228 + 2229 + static struct cdns_reg_pairs sgmii_100_no_ssc_rx_ln_regs[] = { 2230 + {0x091D, RX_PSC_A0}, 2231 + {0x0900, RX_PSC_A2}, 2232 + {0x0100, RX_PSC_A3}, 2233 + {0x03C7, RX_REE_GCSM1_EQENM_PH1}, 2234 + {0x01C7, RX_REE_GCSM1_EQENM_PH2}, 2235 + {0x0000, RX_DIAG_DFE_CTRL}, 2236 + {0x0019, RX_REE_TAP1_CLIP}, 2237 + {0x0019, RX_REE_TAP2TON_CLIP}, 2238 + {0x0098, RX_DIAG_NQST_CTRL}, 2239 + {0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, 2240 + {0x0000, RX_DIAG_DFE_AMP_TUNE_3}, 2241 + {0x0000, RX_DIAG_PI_CAP}, 2242 + {0x0010, RX_DIAG_PI_RATE}, 2243 + {0x0001, RX_DIAG_ACYA}, 2244 + {0x018C, RX_CDRLF_CNFG}, 2245 + }; 2246 + 2247 + static struct cdns_torrent_vals sgmii_100_no_ssc_cmn_vals = { 2248 + .reg_pairs = sgmii_100_no_ssc_cmn_regs, 2249 + .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_cmn_regs), 2250 + }; 2251 + 2252 + static struct cdns_torrent_vals sgmii_100_no_ssc_tx_ln_vals = { 2253 + .reg_pairs = sgmii_100_no_ssc_tx_ln_regs, 2254 + .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_tx_ln_regs), 2255 + }; 2256 + 2257 + static struct cdns_torrent_vals sgmii_100_no_ssc_rx_ln_vals = { 2258 + .reg_pairs = sgmii_100_no_ssc_rx_ln_regs, 2259 + .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_rx_ln_regs), 2260 + }; 2261 + 2262 + /* SGMII 100 MHz Ref clk, internal SSC */ 2263 + static struct cdns_reg_pairs sgmii_100_int_ssc_cmn_regs[] = { 2264 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 2265 + {0x0004, CMN_PLL0_DSM_DIAG_M1}, 2266 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 2267 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 2268 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1}, 2269 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 2270 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 2271 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1}, 2272 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 2273 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 2274 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1}, 2275 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 2276 + {0x0064, CMN_PLL0_INTDIV_M0}, 2277 + {0x0050, CMN_PLL0_INTDIV_M1}, 2278 + {0x0064, CMN_PLL1_INTDIV_M0}, 2279 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 2280 + {0x0002, CMN_PLL0_FRACDIVH_M1}, 2281 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2282 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2283 + {0x0036, CMN_PLL0_HIGH_THR_M1}, 2284 + {0x0044, CMN_PLL1_HIGH_THR_M0}, 2285 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2286 + {0x0002, CMN_PDIAG_PLL0_CTRL_M1}, 2287 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2288 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2289 + {0x0001, CMN_PLL0_SS_CTRL1_M1}, 2290 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2291 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2292 + {0x011B, CMN_PLL0_SS_CTRL2_M1}, 2293 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2294 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2295 + {0x0058, CMN_PLL0_SS_CTRL3_M1}, 2296 + {0x006E, CMN_PLL1_SS_CTRL3_M0}, 2297 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2298 + {0x0012, CMN_PLL0_SS_CTRL4_M1}, 2299 + {0x000E, CMN_PLL1_SS_CTRL4_M0}, 2300 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2301 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2302 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2303 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2304 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2305 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2306 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2307 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2308 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2309 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2310 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2311 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR}, 2312 + {0x3700, CMN_DIAG_BIAS_OVRD1}, 2313 + {0x0008, CMN_TXPUCAL_TUNE}, 2314 + {0x0008, CMN_TXPDCAL_TUNE} 2315 + }; 2316 + 2317 + static struct cdns_torrent_vals sgmii_100_int_ssc_cmn_vals = { 2318 + .reg_pairs = sgmii_100_int_ssc_cmn_regs, 2319 + .num_regs = ARRAY_SIZE(sgmii_100_int_ssc_cmn_regs), 2320 + }; 2321 + 2322 + /* QSGMII 100 MHz Ref clk, no SSC */ 2323 + static struct cdns_reg_pairs qsgmii_100_no_ssc_cmn_regs[] = { 2324 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2325 + {0x0003, CMN_PLL1_VCOCAL_TCTRL} 2326 + }; 2327 + 2328 + static struct cdns_reg_pairs qsgmii_100_no_ssc_tx_ln_regs[] = { 2329 + {0x00F3, TX_PSC_A0}, 2330 + {0x04A2, TX_PSC_A2}, 2331 + {0x04A2, TX_PSC_A3}, 2332 + {0x0000, TX_TXCC_CPOST_MULT_00}, 2333 + {0x0003, DRV_DIAG_TX_DRV} 2334 + }; 2335 + 2336 + static struct cdns_reg_pairs qsgmii_100_no_ssc_rx_ln_regs[] = { 2337 + {0x091D, RX_PSC_A0}, 2338 + {0x0900, RX_PSC_A2}, 2339 + {0x0100, RX_PSC_A3}, 2340 + {0x03C7, RX_REE_GCSM1_EQENM_PH1}, 2341 + {0x01C7, RX_REE_GCSM1_EQENM_PH2}, 2342 + {0x0000, RX_DIAG_DFE_CTRL}, 2343 + {0x0019, RX_REE_TAP1_CLIP}, 2344 + {0x0019, RX_REE_TAP2TON_CLIP}, 2345 + {0x0098, RX_DIAG_NQST_CTRL}, 2346 + {0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, 2347 + {0x0000, RX_DIAG_DFE_AMP_TUNE_3}, 2348 + {0x0000, RX_DIAG_PI_CAP}, 2349 + {0x0010, RX_DIAG_PI_RATE}, 2350 + {0x0001, RX_DIAG_ACYA}, 2351 + {0x018C, RX_CDRLF_CNFG}, 2352 + }; 2353 + 2354 + static struct cdns_torrent_vals qsgmii_100_no_ssc_cmn_vals = { 2355 + .reg_pairs = qsgmii_100_no_ssc_cmn_regs, 2356 + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_cmn_regs), 2357 + }; 2358 + 2359 + static struct cdns_torrent_vals qsgmii_100_no_ssc_tx_ln_vals = { 2360 + .reg_pairs = qsgmii_100_no_ssc_tx_ln_regs, 2361 + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_tx_ln_regs), 2362 + }; 2363 + 2364 + static struct cdns_torrent_vals qsgmii_100_no_ssc_rx_ln_vals = { 2365 + .reg_pairs = qsgmii_100_no_ssc_rx_ln_regs, 2366 + .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_rx_ln_regs), 2367 + }; 2368 + 2369 + /* QSGMII 100 MHz Ref clk, internal SSC */ 2370 + static struct cdns_reg_pairs qsgmii_100_int_ssc_cmn_regs[] = { 2371 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 2372 + {0x0004, CMN_PLL0_DSM_DIAG_M1}, 2373 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 2374 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 2375 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1}, 2376 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 2377 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 2378 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1}, 2379 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 2380 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 2381 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1}, 2382 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 2383 + {0x0064, CMN_PLL0_INTDIV_M0}, 2384 + {0x0050, CMN_PLL0_INTDIV_M1}, 2385 + {0x0064, CMN_PLL1_INTDIV_M0}, 2386 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 2387 + {0x0002, CMN_PLL0_FRACDIVH_M1}, 2388 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2389 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2390 + {0x0036, CMN_PLL0_HIGH_THR_M1}, 2391 + {0x0044, CMN_PLL1_HIGH_THR_M0}, 2392 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2393 + {0x0002, CMN_PDIAG_PLL0_CTRL_M1}, 2394 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2395 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2396 + {0x0001, CMN_PLL0_SS_CTRL1_M1}, 2397 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2398 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2399 + {0x011B, CMN_PLL0_SS_CTRL2_M1}, 2400 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2401 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2402 + {0x0058, CMN_PLL0_SS_CTRL3_M1}, 2403 + {0x006E, CMN_PLL1_SS_CTRL3_M0}, 2404 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2405 + {0x0012, CMN_PLL0_SS_CTRL4_M1}, 2406 + {0x000E, CMN_PLL1_SS_CTRL4_M0}, 2407 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2408 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2409 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2410 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2411 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2412 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2413 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2414 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2415 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2416 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2417 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2418 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR} 2419 + }; 2420 + 2421 + static struct cdns_torrent_vals qsgmii_100_int_ssc_cmn_vals = { 2422 + .reg_pairs = qsgmii_100_int_ssc_cmn_regs, 2423 + .num_regs = ARRAY_SIZE(qsgmii_100_int_ssc_cmn_regs), 2424 + }; 2425 + 2426 + /* Single SGMII/QSGMII link configuration */ 2427 + static struct cdns_reg_pairs sl_sgmii_link_cmn_regs[] = { 2428 + {0x0000, PHY_PLL_CFG}, 2429 + {0x0601, CMN_PDIAG_PLL0_CLK_SEL_M0} 2430 + }; 2431 + 2432 + static struct cdns_reg_pairs sl_sgmii_xcvr_diag_ln_regs[] = { 2433 + {0x0000, XCVR_DIAG_HSCLK_SEL}, 2434 + {0x0003, XCVR_DIAG_HSCLK_DIV}, 2435 + {0x0013, XCVR_DIAG_PLLDRC_CTRL} 2436 + }; 2437 + 2438 + static struct cdns_torrent_vals sl_sgmii_link_cmn_vals = { 2439 + .reg_pairs = sl_sgmii_link_cmn_regs, 2440 + .num_regs = ARRAY_SIZE(sl_sgmii_link_cmn_regs), 2441 + }; 2442 + 2443 + static struct cdns_torrent_vals sl_sgmii_xcvr_diag_ln_vals = { 2444 + .reg_pairs = sl_sgmii_xcvr_diag_ln_regs, 2445 + .num_regs = ARRAY_SIZE(sl_sgmii_xcvr_diag_ln_regs), 2446 + }; 2447 + 2448 + /* Multi link PCIe, 100 MHz Ref clk, internal SSC */ 2449 + static struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = { 2450 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 2451 + {0x0004, CMN_PLL0_DSM_DIAG_M1}, 2452 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 2453 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 2454 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1}, 2455 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 2456 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 2457 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1}, 2458 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 2459 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 2460 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1}, 2461 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 2462 + {0x0064, CMN_PLL0_INTDIV_M0}, 2463 + {0x0050, CMN_PLL0_INTDIV_M1}, 2464 + {0x0064, CMN_PLL1_INTDIV_M0}, 2465 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 2466 + {0x0002, CMN_PLL0_FRACDIVH_M1}, 2467 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2468 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2469 + {0x0036, CMN_PLL0_HIGH_THR_M1}, 2470 + {0x0044, CMN_PLL1_HIGH_THR_M0}, 2471 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2472 + {0x0002, CMN_PDIAG_PLL0_CTRL_M1}, 2473 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2474 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2475 + {0x0001, CMN_PLL0_SS_CTRL1_M1}, 2476 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2477 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2478 + {0x011B, CMN_PLL0_SS_CTRL2_M1}, 2479 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2480 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2481 + {0x0058, CMN_PLL0_SS_CTRL3_M1}, 2482 + {0x006E, CMN_PLL1_SS_CTRL3_M0}, 2483 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2484 + {0x0012, CMN_PLL0_SS_CTRL4_M1}, 2485 + {0x000E, CMN_PLL1_SS_CTRL4_M0}, 2486 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2487 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2488 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2489 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2490 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2491 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2492 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2493 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2494 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2495 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2496 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2497 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR} 2498 + }; 2499 + 2500 + static struct cdns_torrent_vals pcie_100_int_ssc_cmn_vals = { 2501 + .reg_pairs = pcie_100_int_ssc_cmn_regs, 2502 + .num_regs = ARRAY_SIZE(pcie_100_int_ssc_cmn_regs), 2503 + }; 2504 + 2505 + /* Single link PCIe, 100 MHz Ref clk, internal SSC */ 2506 + static struct cdns_reg_pairs sl_pcie_100_int_ssc_cmn_regs[] = { 2507 + {0x0004, CMN_PLL0_DSM_DIAG_M0}, 2508 + {0x0004, CMN_PLL0_DSM_DIAG_M1}, 2509 + {0x0004, CMN_PLL1_DSM_DIAG_M0}, 2510 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M0}, 2511 + {0x0509, CMN_PDIAG_PLL0_CP_PADJ_M1}, 2512 + {0x0509, CMN_PDIAG_PLL1_CP_PADJ_M0}, 2513 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M0}, 2514 + {0x0F00, CMN_PDIAG_PLL0_CP_IADJ_M1}, 2515 + {0x0F00, CMN_PDIAG_PLL1_CP_IADJ_M0}, 2516 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M0}, 2517 + {0x0F08, CMN_PDIAG_PLL0_FILT_PADJ_M1}, 2518 + {0x0F08, CMN_PDIAG_PLL1_FILT_PADJ_M0}, 2519 + {0x0064, CMN_PLL0_INTDIV_M0}, 2520 + {0x0050, CMN_PLL0_INTDIV_M1}, 2521 + {0x0050, CMN_PLL1_INTDIV_M0}, 2522 + {0x0002, CMN_PLL0_FRACDIVH_M0}, 2523 + {0x0002, CMN_PLL0_FRACDIVH_M1}, 2524 + {0x0002, CMN_PLL1_FRACDIVH_M0}, 2525 + {0x0044, CMN_PLL0_HIGH_THR_M0}, 2526 + {0x0036, CMN_PLL0_HIGH_THR_M1}, 2527 + {0x0036, CMN_PLL1_HIGH_THR_M0}, 2528 + {0x0002, CMN_PDIAG_PLL0_CTRL_M0}, 2529 + {0x0002, CMN_PDIAG_PLL0_CTRL_M1}, 2530 + {0x0002, CMN_PDIAG_PLL1_CTRL_M0}, 2531 + {0x0001, CMN_PLL0_SS_CTRL1_M0}, 2532 + {0x0001, CMN_PLL0_SS_CTRL1_M1}, 2533 + {0x0001, CMN_PLL1_SS_CTRL1_M0}, 2534 + {0x011B, CMN_PLL0_SS_CTRL2_M0}, 2535 + {0x011B, CMN_PLL0_SS_CTRL2_M1}, 2536 + {0x011B, CMN_PLL1_SS_CTRL2_M0}, 2537 + {0x006E, CMN_PLL0_SS_CTRL3_M0}, 2538 + {0x0058, CMN_PLL0_SS_CTRL3_M1}, 2539 + {0x0058, CMN_PLL1_SS_CTRL3_M0}, 2540 + {0x000E, CMN_PLL0_SS_CTRL4_M0}, 2541 + {0x0012, CMN_PLL0_SS_CTRL4_M1}, 2542 + {0x0012, CMN_PLL1_SS_CTRL4_M0}, 2543 + {0x0C5E, CMN_PLL0_VCOCAL_REFTIM_START}, 2544 + {0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START}, 2545 + {0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START}, 2546 + {0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START}, 2547 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2548 + {0x0003, CMN_PLL1_VCOCAL_TCTRL}, 2549 + {0x00C7, CMN_PLL0_LOCK_REFCNT_START}, 2550 + {0x00C7, CMN_PLL1_LOCK_REFCNT_START}, 2551 + {0x00C7, CMN_PLL0_LOCK_PLLCNT_START}, 2552 + {0x00C7, CMN_PLL1_LOCK_PLLCNT_START}, 2553 + {0x0005, CMN_PLL0_LOCK_PLLCNT_THR}, 2554 + {0x0005, CMN_PLL1_LOCK_PLLCNT_THR} 2555 + }; 2556 + 2557 + static struct cdns_torrent_vals sl_pcie_100_int_ssc_cmn_vals = { 2558 + .reg_pairs = sl_pcie_100_int_ssc_cmn_regs, 2559 + .num_regs = ARRAY_SIZE(sl_pcie_100_int_ssc_cmn_regs), 2560 + }; 2561 + 2562 + /* PCIe, 100 MHz Ref clk, no SSC & external SSC */ 2563 + static struct cdns_reg_pairs pcie_100_ext_no_ssc_cmn_regs[] = { 2564 + {0x0003, CMN_PLL0_VCOCAL_TCTRL}, 2565 + {0x0003, CMN_PLL1_VCOCAL_TCTRL} 2566 + }; 2567 + 2568 + static struct cdns_reg_pairs pcie_100_ext_no_ssc_rx_ln_regs[] = { 2569 + {0x0019, RX_REE_TAP1_CLIP}, 2570 + {0x0019, RX_REE_TAP2TON_CLIP}, 2571 + {0x0001, RX_DIAG_ACYA} 2572 + }; 2573 + 2574 + static struct cdns_torrent_vals pcie_100_no_ssc_cmn_vals = { 2575 + .reg_pairs = pcie_100_ext_no_ssc_cmn_regs, 2576 + .num_regs = ARRAY_SIZE(pcie_100_ext_no_ssc_cmn_regs), 2577 + }; 2578 + 2579 + static struct cdns_torrent_vals pcie_100_no_ssc_rx_ln_vals = { 2580 + .reg_pairs = pcie_100_ext_no_ssc_rx_ln_regs, 2581 + .num_regs = ARRAY_SIZE(pcie_100_ext_no_ssc_rx_ln_regs), 2582 + }; 2342 2583 2343 2584 static const struct cdns_torrent_data cdns_map_torrent = { 2344 2585 .block_offset_shift = 0x2, 2345 2586 .reg_offset_shift = 0x2, 2587 + .link_cmn_vals = { 2588 + [TYPE_PCIE] = { 2589 + [TYPE_NONE] = { 2590 + [NO_SSC] = NULL, 2591 + [EXTERNAL_SSC] = NULL, 2592 + [INTERNAL_SSC] = NULL, 2593 + }, 2594 + [TYPE_SGMII] = { 2595 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 2596 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2597 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2598 + }, 2599 + [TYPE_QSGMII] = { 2600 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 2601 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2602 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2603 + }, 2604 + [TYPE_USB] = { 2605 + [NO_SSC] = &pcie_usb_link_cmn_vals, 2606 + [EXTERNAL_SSC] = &pcie_usb_link_cmn_vals, 2607 + [INTERNAL_SSC] = &pcie_usb_link_cmn_vals, 2608 + }, 2609 + }, 2610 + [TYPE_SGMII] = { 2611 + [TYPE_NONE] = { 2612 + [NO_SSC] = &sl_sgmii_link_cmn_vals, 2613 + }, 2614 + [TYPE_PCIE] = { 2615 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 2616 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2617 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2618 + }, 2619 + [TYPE_USB] = { 2620 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 2621 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2622 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2623 + }, 2624 + }, 2625 + [TYPE_QSGMII] = { 2626 + [TYPE_NONE] = { 2627 + [NO_SSC] = &sl_sgmii_link_cmn_vals, 2628 + }, 2629 + [TYPE_PCIE] = { 2630 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 2631 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2632 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 2633 + }, 2634 + [TYPE_USB] = { 2635 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 2636 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2637 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2638 + }, 2639 + }, 2640 + [TYPE_USB] = { 2641 + [TYPE_NONE] = { 2642 + [NO_SSC] = &sl_usb_link_cmn_vals, 2643 + [EXTERNAL_SSC] = &sl_usb_link_cmn_vals, 2644 + [INTERNAL_SSC] = &sl_usb_link_cmn_vals, 2645 + }, 2646 + [TYPE_PCIE] = { 2647 + [NO_SSC] = &pcie_usb_link_cmn_vals, 2648 + [EXTERNAL_SSC] = &pcie_usb_link_cmn_vals, 2649 + [INTERNAL_SSC] = &pcie_usb_link_cmn_vals, 2650 + }, 2651 + [TYPE_SGMII] = { 2652 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 2653 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2654 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2655 + }, 2656 + [TYPE_QSGMII] = { 2657 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 2658 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2659 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 2660 + }, 2661 + }, 2662 + }, 2663 + .xcvr_diag_vals = { 2664 + [TYPE_PCIE] = { 2665 + [TYPE_NONE] = { 2666 + [NO_SSC] = NULL, 2667 + [EXTERNAL_SSC] = NULL, 2668 + [INTERNAL_SSC] = NULL, 2669 + }, 2670 + [TYPE_SGMII] = { 2671 + [NO_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2672 + [EXTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2673 + [INTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2674 + }, 2675 + [TYPE_QSGMII] = { 2676 + [NO_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2677 + [EXTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2678 + [INTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 2679 + }, 2680 + [TYPE_USB] = { 2681 + [NO_SSC] = &pcie_usb_xcvr_diag_ln_vals, 2682 + [EXTERNAL_SSC] = &pcie_usb_xcvr_diag_ln_vals, 2683 + [INTERNAL_SSC] = &pcie_usb_xcvr_diag_ln_vals, 2684 + }, 2685 + }, 2686 + [TYPE_SGMII] = { 2687 + [TYPE_NONE] = { 2688 + [NO_SSC] = &sl_sgmii_xcvr_diag_ln_vals, 2689 + }, 2690 + [TYPE_PCIE] = { 2691 + [NO_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2692 + [EXTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2693 + [INTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2694 + }, 2695 + [TYPE_USB] = { 2696 + [NO_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2697 + [EXTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2698 + [INTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2699 + }, 2700 + }, 2701 + [TYPE_QSGMII] = { 2702 + [TYPE_NONE] = { 2703 + [NO_SSC] = &sl_sgmii_xcvr_diag_ln_vals, 2704 + }, 2705 + [TYPE_PCIE] = { 2706 + [NO_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2707 + [EXTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2708 + [INTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 2709 + }, 2710 + [TYPE_USB] = { 2711 + [NO_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2712 + [EXTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2713 + [INTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 2714 + }, 2715 + }, 2716 + [TYPE_USB] = { 2717 + [TYPE_NONE] = { 2718 + [NO_SSC] = &sl_usb_xcvr_diag_ln_vals, 2719 + [EXTERNAL_SSC] = &sl_usb_xcvr_diag_ln_vals, 2720 + [INTERNAL_SSC] = &sl_usb_xcvr_diag_ln_vals, 2721 + }, 2722 + [TYPE_PCIE] = { 2723 + [NO_SSC] = &usb_pcie_xcvr_diag_ln_vals, 2724 + [EXTERNAL_SSC] = &usb_pcie_xcvr_diag_ln_vals, 2725 + [INTERNAL_SSC] = &usb_pcie_xcvr_diag_ln_vals, 2726 + }, 2727 + [TYPE_SGMII] = { 2728 + [NO_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2729 + [EXTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2730 + [INTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2731 + }, 2732 + [TYPE_QSGMII] = { 2733 + [NO_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2734 + [EXTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2735 + [INTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 2736 + }, 2737 + }, 2738 + }, 2739 + .pcs_cmn_vals = { 2740 + [TYPE_USB] = { 2741 + [TYPE_NONE] = { 2742 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 2743 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2744 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2745 + }, 2746 + [TYPE_PCIE] = { 2747 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 2748 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2749 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2750 + }, 2751 + [TYPE_SGMII] = { 2752 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 2753 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2754 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2755 + }, 2756 + [TYPE_QSGMII] = { 2757 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 2758 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2759 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 2760 + }, 2761 + }, 2762 + }, 2763 + .cmn_vals = { 2764 + [TYPE_PCIE] = { 2765 + [TYPE_NONE] = { 2766 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 2767 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 2768 + [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals, 2769 + }, 2770 + [TYPE_SGMII] = { 2771 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 2772 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 2773 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 2774 + }, 2775 + [TYPE_QSGMII] = { 2776 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 2777 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 2778 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 2779 + }, 2780 + [TYPE_USB] = { 2781 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 2782 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 2783 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 2784 + }, 2785 + }, 2786 + [TYPE_SGMII] = { 2787 + [TYPE_NONE] = { 2788 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 2789 + }, 2790 + [TYPE_PCIE] = { 2791 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 2792 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 2793 + [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals, 2794 + }, 2795 + [TYPE_USB] = { 2796 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 2797 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 2798 + [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 2799 + }, 2800 + }, 2801 + [TYPE_QSGMII] = { 2802 + [TYPE_NONE] = { 2803 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2804 + }, 2805 + [TYPE_PCIE] = { 2806 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2807 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2808 + [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals, 2809 + }, 2810 + [TYPE_USB] = { 2811 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2812 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2813 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 2814 + }, 2815 + }, 2816 + [TYPE_USB] = { 2817 + [TYPE_NONE] = { 2818 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 2819 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 2820 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 2821 + }, 2822 + [TYPE_PCIE] = { 2823 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 2824 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 2825 + [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals, 2826 + }, 2827 + [TYPE_SGMII] = { 2828 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 2829 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 2830 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 2831 + }, 2832 + [TYPE_QSGMII] = { 2833 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 2834 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 2835 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 2836 + }, 2837 + }, 2838 + }, 2839 + .tx_ln_vals = { 2840 + [TYPE_PCIE] = { 2841 + [TYPE_NONE] = { 2842 + [NO_SSC] = NULL, 2843 + [EXTERNAL_SSC] = NULL, 2844 + [INTERNAL_SSC] = NULL, 2845 + }, 2846 + [TYPE_SGMII] = { 2847 + [NO_SSC] = NULL, 2848 + [EXTERNAL_SSC] = NULL, 2849 + [INTERNAL_SSC] = NULL, 2850 + }, 2851 + [TYPE_QSGMII] = { 2852 + [NO_SSC] = NULL, 2853 + [EXTERNAL_SSC] = NULL, 2854 + [INTERNAL_SSC] = NULL, 2855 + }, 2856 + [TYPE_USB] = { 2857 + [NO_SSC] = NULL, 2858 + [EXTERNAL_SSC] = NULL, 2859 + [INTERNAL_SSC] = NULL, 2860 + }, 2861 + }, 2862 + [TYPE_SGMII] = { 2863 + [TYPE_NONE] = { 2864 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2865 + }, 2866 + [TYPE_PCIE] = { 2867 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2868 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2869 + [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2870 + }, 2871 + [TYPE_USB] = { 2872 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2873 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2874 + [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 2875 + }, 2876 + }, 2877 + [TYPE_QSGMII] = { 2878 + [TYPE_NONE] = { 2879 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2880 + }, 2881 + [TYPE_PCIE] = { 2882 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2883 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2884 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2885 + }, 2886 + [TYPE_USB] = { 2887 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2888 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2889 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 2890 + }, 2891 + }, 2892 + [TYPE_USB] = { 2893 + [TYPE_NONE] = { 2894 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 2895 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2896 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2897 + }, 2898 + [TYPE_PCIE] = { 2899 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 2900 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2901 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2902 + }, 2903 + [TYPE_SGMII] = { 2904 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 2905 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2906 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2907 + }, 2908 + [TYPE_QSGMII] = { 2909 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 2910 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2911 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 2912 + }, 2913 + }, 2914 + }, 2915 + .rx_ln_vals = { 2916 + [TYPE_PCIE] = { 2917 + [TYPE_NONE] = { 2918 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2919 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2920 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2921 + }, 2922 + [TYPE_SGMII] = { 2923 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2924 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2925 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2926 + }, 2927 + [TYPE_QSGMII] = { 2928 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2929 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2930 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2931 + }, 2932 + [TYPE_USB] = { 2933 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2934 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2935 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 2936 + }, 2937 + }, 2938 + [TYPE_SGMII] = { 2939 + [TYPE_NONE] = { 2940 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2941 + }, 2942 + [TYPE_PCIE] = { 2943 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2944 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2945 + [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2946 + }, 2947 + [TYPE_USB] = { 2948 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2949 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2950 + [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 2951 + }, 2952 + }, 2953 + [TYPE_QSGMII] = { 2954 + [TYPE_NONE] = { 2955 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2956 + }, 2957 + [TYPE_PCIE] = { 2958 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2959 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2960 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2961 + }, 2962 + [TYPE_USB] = { 2963 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2964 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2965 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 2966 + }, 2967 + }, 2968 + [TYPE_USB] = { 2969 + [TYPE_NONE] = { 2970 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 2971 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2972 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2973 + }, 2974 + [TYPE_PCIE] = { 2975 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 2976 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2977 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2978 + }, 2979 + [TYPE_SGMII] = { 2980 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 2981 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2982 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2983 + }, 2984 + [TYPE_QSGMII] = { 2985 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 2986 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2987 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 2988 + }, 2989 + }, 2990 + }, 2346 2991 }; 2347 2992 2348 2993 static const struct cdns_torrent_data ti_j721e_map_torrent = { 2349 2994 .block_offset_shift = 0x0, 2350 2995 .reg_offset_shift = 0x1, 2996 + .link_cmn_vals = { 2997 + [TYPE_PCIE] = { 2998 + [TYPE_NONE] = { 2999 + [NO_SSC] = NULL, 3000 + [EXTERNAL_SSC] = NULL, 3001 + [INTERNAL_SSC] = NULL, 3002 + }, 3003 + [TYPE_SGMII] = { 3004 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 3005 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3006 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3007 + }, 3008 + [TYPE_QSGMII] = { 3009 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 3010 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3011 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3012 + }, 3013 + [TYPE_USB] = { 3014 + [NO_SSC] = &pcie_usb_link_cmn_vals, 3015 + [EXTERNAL_SSC] = &pcie_usb_link_cmn_vals, 3016 + [INTERNAL_SSC] = &pcie_usb_link_cmn_vals, 3017 + }, 3018 + }, 3019 + [TYPE_SGMII] = { 3020 + [TYPE_NONE] = { 3021 + [NO_SSC] = &sl_sgmii_link_cmn_vals, 3022 + }, 3023 + [TYPE_PCIE] = { 3024 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 3025 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3026 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3027 + }, 3028 + [TYPE_USB] = { 3029 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 3030 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3031 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3032 + }, 3033 + }, 3034 + [TYPE_QSGMII] = { 3035 + [TYPE_NONE] = { 3036 + [NO_SSC] = &sl_sgmii_link_cmn_vals, 3037 + }, 3038 + [TYPE_PCIE] = { 3039 + [NO_SSC] = &pcie_sgmii_link_cmn_vals, 3040 + [EXTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3041 + [INTERNAL_SSC] = &pcie_sgmii_link_cmn_vals, 3042 + }, 3043 + [TYPE_USB] = { 3044 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 3045 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3046 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3047 + }, 3048 + }, 3049 + [TYPE_USB] = { 3050 + [TYPE_NONE] = { 3051 + [NO_SSC] = &sl_usb_link_cmn_vals, 3052 + [EXTERNAL_SSC] = &sl_usb_link_cmn_vals, 3053 + [INTERNAL_SSC] = &sl_usb_link_cmn_vals, 3054 + }, 3055 + [TYPE_PCIE] = { 3056 + [NO_SSC] = &pcie_usb_link_cmn_vals, 3057 + [EXTERNAL_SSC] = &pcie_usb_link_cmn_vals, 3058 + [INTERNAL_SSC] = &pcie_usb_link_cmn_vals, 3059 + }, 3060 + [TYPE_SGMII] = { 3061 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 3062 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3063 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3064 + }, 3065 + [TYPE_QSGMII] = { 3066 + [NO_SSC] = &usb_sgmii_link_cmn_vals, 3067 + [EXTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3068 + [INTERNAL_SSC] = &usb_sgmii_link_cmn_vals, 3069 + }, 3070 + }, 3071 + }, 3072 + .xcvr_diag_vals = { 3073 + [TYPE_PCIE] = { 3074 + [TYPE_NONE] = { 3075 + [NO_SSC] = NULL, 3076 + [EXTERNAL_SSC] = NULL, 3077 + [INTERNAL_SSC] = NULL, 3078 + }, 3079 + [TYPE_SGMII] = { 3080 + [NO_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3081 + [EXTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3082 + [INTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3083 + }, 3084 + [TYPE_QSGMII] = { 3085 + [NO_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3086 + [EXTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3087 + [INTERNAL_SSC] = &pcie_sgmii_xcvr_diag_ln_vals, 3088 + }, 3089 + [TYPE_USB] = { 3090 + [NO_SSC] = &pcie_usb_xcvr_diag_ln_vals, 3091 + [EXTERNAL_SSC] = &pcie_usb_xcvr_diag_ln_vals, 3092 + [INTERNAL_SSC] = &pcie_usb_xcvr_diag_ln_vals, 3093 + }, 3094 + }, 3095 + [TYPE_SGMII] = { 3096 + [TYPE_NONE] = { 3097 + [NO_SSC] = &sl_sgmii_xcvr_diag_ln_vals, 3098 + }, 3099 + [TYPE_PCIE] = { 3100 + [NO_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3101 + [EXTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3102 + [INTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3103 + }, 3104 + [TYPE_USB] = { 3105 + [NO_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3106 + [EXTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3107 + [INTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3108 + }, 3109 + }, 3110 + [TYPE_QSGMII] = { 3111 + [TYPE_NONE] = { 3112 + [NO_SSC] = &sl_sgmii_xcvr_diag_ln_vals, 3113 + }, 3114 + [TYPE_PCIE] = { 3115 + [NO_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3116 + [EXTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3117 + [INTERNAL_SSC] = &sgmii_pcie_xcvr_diag_ln_vals, 3118 + }, 3119 + [TYPE_USB] = { 3120 + [NO_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3121 + [EXTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3122 + [INTERNAL_SSC] = &sgmii_usb_xcvr_diag_ln_vals, 3123 + }, 3124 + }, 3125 + [TYPE_USB] = { 3126 + [TYPE_NONE] = { 3127 + [NO_SSC] = &sl_usb_xcvr_diag_ln_vals, 3128 + [EXTERNAL_SSC] = &sl_usb_xcvr_diag_ln_vals, 3129 + [INTERNAL_SSC] = &sl_usb_xcvr_diag_ln_vals, 3130 + }, 3131 + [TYPE_PCIE] = { 3132 + [NO_SSC] = &usb_pcie_xcvr_diag_ln_vals, 3133 + [EXTERNAL_SSC] = &usb_pcie_xcvr_diag_ln_vals, 3134 + [INTERNAL_SSC] = &usb_pcie_xcvr_diag_ln_vals, 3135 + }, 3136 + [TYPE_SGMII] = { 3137 + [NO_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3138 + [EXTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3139 + [INTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3140 + }, 3141 + [TYPE_QSGMII] = { 3142 + [NO_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3143 + [EXTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3144 + [INTERNAL_SSC] = &usb_sgmii_xcvr_diag_ln_vals, 3145 + }, 3146 + }, 3147 + }, 3148 + .pcs_cmn_vals = { 3149 + [TYPE_USB] = { 3150 + [TYPE_NONE] = { 3151 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 3152 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3153 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3154 + }, 3155 + [TYPE_PCIE] = { 3156 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 3157 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3158 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3159 + }, 3160 + [TYPE_SGMII] = { 3161 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 3162 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3163 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3164 + }, 3165 + [TYPE_QSGMII] = { 3166 + [NO_SSC] = &usb_phy_pcs_cmn_vals, 3167 + [EXTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3168 + [INTERNAL_SSC] = &usb_phy_pcs_cmn_vals, 3169 + }, 3170 + }, 3171 + }, 3172 + .cmn_vals = { 3173 + [TYPE_PCIE] = { 3174 + [TYPE_NONE] = { 3175 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 3176 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 3177 + [INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals, 3178 + }, 3179 + [TYPE_SGMII] = { 3180 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 3181 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 3182 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 3183 + }, 3184 + [TYPE_QSGMII] = { 3185 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 3186 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 3187 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 3188 + }, 3189 + [TYPE_USB] = { 3190 + [NO_SSC] = &pcie_100_no_ssc_cmn_vals, 3191 + [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals, 3192 + [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, 3193 + }, 3194 + }, 3195 + [TYPE_SGMII] = { 3196 + [TYPE_NONE] = { 3197 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 3198 + }, 3199 + [TYPE_PCIE] = { 3200 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 3201 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 3202 + [INTERNAL_SSC] = &sgmii_100_int_ssc_cmn_vals, 3203 + }, 3204 + [TYPE_USB] = { 3205 + [NO_SSC] = &sgmii_100_no_ssc_cmn_vals, 3206 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 3207 + [INTERNAL_SSC] = &sgmii_100_no_ssc_cmn_vals, 3208 + }, 3209 + }, 3210 + [TYPE_QSGMII] = { 3211 + [TYPE_NONE] = { 3212 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3213 + }, 3214 + [TYPE_PCIE] = { 3215 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3216 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3217 + [INTERNAL_SSC] = &qsgmii_100_int_ssc_cmn_vals, 3218 + }, 3219 + [TYPE_USB] = { 3220 + [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3221 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3222 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_cmn_vals, 3223 + }, 3224 + }, 3225 + [TYPE_USB] = { 3226 + [TYPE_NONE] = { 3227 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 3228 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 3229 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 3230 + }, 3231 + [TYPE_PCIE] = { 3232 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 3233 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 3234 + [INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals, 3235 + }, 3236 + [TYPE_SGMII] = { 3237 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 3238 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 3239 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 3240 + }, 3241 + [TYPE_QSGMII] = { 3242 + [NO_SSC] = &usb_100_no_ssc_cmn_vals, 3243 + [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals, 3244 + [INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals, 3245 + }, 3246 + }, 3247 + }, 3248 + .tx_ln_vals = { 3249 + [TYPE_PCIE] = { 3250 + [TYPE_NONE] = { 3251 + [NO_SSC] = NULL, 3252 + [EXTERNAL_SSC] = NULL, 3253 + [INTERNAL_SSC] = NULL, 3254 + }, 3255 + [TYPE_SGMII] = { 3256 + [NO_SSC] = NULL, 3257 + [EXTERNAL_SSC] = NULL, 3258 + [INTERNAL_SSC] = NULL, 3259 + }, 3260 + [TYPE_QSGMII] = { 3261 + [NO_SSC] = NULL, 3262 + [EXTERNAL_SSC] = NULL, 3263 + [INTERNAL_SSC] = NULL, 3264 + }, 3265 + [TYPE_USB] = { 3266 + [NO_SSC] = NULL, 3267 + [EXTERNAL_SSC] = NULL, 3268 + [INTERNAL_SSC] = NULL, 3269 + }, 3270 + }, 3271 + [TYPE_SGMII] = { 3272 + [TYPE_NONE] = { 3273 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3274 + }, 3275 + [TYPE_PCIE] = { 3276 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3277 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3278 + [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3279 + }, 3280 + [TYPE_USB] = { 3281 + [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3282 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3283 + [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals, 3284 + }, 3285 + }, 3286 + [TYPE_QSGMII] = { 3287 + [TYPE_NONE] = { 3288 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3289 + }, 3290 + [TYPE_PCIE] = { 3291 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3292 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3293 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3294 + }, 3295 + [TYPE_USB] = { 3296 + [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3297 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3298 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals, 3299 + }, 3300 + }, 3301 + [TYPE_USB] = { 3302 + [TYPE_NONE] = { 3303 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 3304 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3305 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3306 + }, 3307 + [TYPE_PCIE] = { 3308 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 3309 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3310 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3311 + }, 3312 + [TYPE_SGMII] = { 3313 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 3314 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3315 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3316 + }, 3317 + [TYPE_QSGMII] = { 3318 + [NO_SSC] = &usb_100_no_ssc_tx_ln_vals, 3319 + [EXTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3320 + [INTERNAL_SSC] = &usb_100_no_ssc_tx_ln_vals, 3321 + }, 3322 + }, 3323 + }, 3324 + .rx_ln_vals = { 3325 + [TYPE_PCIE] = { 3326 + [TYPE_NONE] = { 3327 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3328 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3329 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3330 + }, 3331 + [TYPE_SGMII] = { 3332 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3333 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3334 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3335 + }, 3336 + [TYPE_QSGMII] = { 3337 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3338 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3339 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3340 + }, 3341 + [TYPE_USB] = { 3342 + [NO_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3343 + [EXTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3344 + [INTERNAL_SSC] = &pcie_100_no_ssc_rx_ln_vals, 3345 + }, 3346 + }, 3347 + [TYPE_SGMII] = { 3348 + [TYPE_NONE] = { 3349 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3350 + }, 3351 + [TYPE_PCIE] = { 3352 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3353 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3354 + [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3355 + }, 3356 + [TYPE_USB] = { 3357 + [NO_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3358 + [EXTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3359 + [INTERNAL_SSC] = &sgmii_100_no_ssc_rx_ln_vals, 3360 + }, 3361 + }, 3362 + [TYPE_QSGMII] = { 3363 + [TYPE_NONE] = { 3364 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3365 + }, 3366 + [TYPE_PCIE] = { 3367 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3368 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3369 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3370 + }, 3371 + [TYPE_USB] = { 3372 + [NO_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3373 + [EXTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3374 + [INTERNAL_SSC] = &qsgmii_100_no_ssc_rx_ln_vals, 3375 + }, 3376 + }, 3377 + [TYPE_USB] = { 3378 + [TYPE_NONE] = { 3379 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 3380 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3381 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3382 + }, 3383 + [TYPE_PCIE] = { 3384 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 3385 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3386 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3387 + }, 3388 + [TYPE_SGMII] = { 3389 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 3390 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3391 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3392 + }, 3393 + [TYPE_QSGMII] = { 3394 + [NO_SSC] = &usb_100_no_ssc_rx_ln_vals, 3395 + [EXTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3396 + [INTERNAL_SSC] = &usb_100_no_ssc_rx_ln_vals, 3397 + }, 3398 + }, 3399 + }, 2351 3400 }; 2352 3401 2353 3402 static const struct of_device_id cdns_torrent_phy_of_match[] = {
+71 -8
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0+ 2 2 /* Copyright (c) 2017 NXP. */ 3 3 4 + #include <linux/bitfield.h> 4 5 #include <linux/clk.h> 6 + #include <linux/delay.h> 5 7 #include <linux/io.h> 6 8 #include <linux/module.h> 9 + #include <linux/of_platform.h> 7 10 #include <linux/phy/phy.h> 8 11 #include <linux/platform_device.h> 9 12 #include <linux/regulator/consumer.h> 10 13 11 14 #define PHY_CTRL0 0x0 12 15 #define PHY_CTRL0_REF_SSP_EN BIT(2) 16 + #define PHY_CTRL0_FSEL_MASK GENMASK(10, 5) 17 + #define PHY_CTRL0_FSEL_24M 0x2a 13 18 14 19 #define PHY_CTRL1 0x4 15 20 #define PHY_CTRL1_RESET BIT(0) ··· 25 20 26 21 #define PHY_CTRL2 0x8 27 22 #define PHY_CTRL2_TXENABLEN0 BIT(8) 23 + #define PHY_CTRL2_OTG_DISABLE BIT(9) 24 + 25 + #define PHY_CTRL6 0x18 26 + #define PHY_CTRL6_ALT_CLK_EN BIT(1) 27 + #define PHY_CTRL6_ALT_CLK_SEL BIT(0) 28 28 29 29 struct imx8mq_usb_phy { 30 30 struct phy *phy; ··· 64 54 return 0; 65 55 } 66 56 57 + static int imx8mp_usb_phy_init(struct phy *phy) 58 + { 59 + struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 60 + u32 value; 61 + 62 + /* USB3.0 PHY signal fsel for 24M ref */ 63 + value = readl(imx_phy->base + PHY_CTRL0); 64 + value &= ~PHY_CTRL0_FSEL_MASK; 65 + value |= FIELD_PREP(PHY_CTRL0_FSEL_MASK, PHY_CTRL0_FSEL_24M); 66 + writel(value, imx_phy->base + PHY_CTRL0); 67 + 68 + /* Disable alt_clk_en and use internal MPLL clocks */ 69 + value = readl(imx_phy->base + PHY_CTRL6); 70 + value &= ~(PHY_CTRL6_ALT_CLK_SEL | PHY_CTRL6_ALT_CLK_EN); 71 + writel(value, imx_phy->base + PHY_CTRL6); 72 + 73 + value = readl(imx_phy->base + PHY_CTRL1); 74 + value &= ~(PHY_CTRL1_VDATSRCENB0 | PHY_CTRL1_VDATDETENB0); 75 + value |= PHY_CTRL1_RESET | PHY_CTRL1_ATERESET; 76 + writel(value, imx_phy->base + PHY_CTRL1); 77 + 78 + value = readl(imx_phy->base + PHY_CTRL0); 79 + value |= PHY_CTRL0_REF_SSP_EN; 80 + writel(value, imx_phy->base + PHY_CTRL0); 81 + 82 + value = readl(imx_phy->base + PHY_CTRL2); 83 + value |= PHY_CTRL2_TXENABLEN0 | PHY_CTRL2_OTG_DISABLE; 84 + writel(value, imx_phy->base + PHY_CTRL2); 85 + 86 + udelay(10); 87 + 88 + value = readl(imx_phy->base + PHY_CTRL1); 89 + value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET); 90 + writel(value, imx_phy->base + PHY_CTRL1); 91 + 92 + return 0; 93 + } 94 + 67 95 static int imx8mq_phy_power_on(struct phy *phy) 68 96 { 69 97 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); ··· 124 76 return 0; 125 77 } 126 78 127 - static struct phy_ops imx8mq_usb_phy_ops = { 79 + static const struct phy_ops imx8mq_usb_phy_ops = { 128 80 .init = imx8mq_usb_phy_init, 129 81 .power_on = imx8mq_phy_power_on, 130 82 .power_off = imx8mq_phy_power_off, 131 83 .owner = THIS_MODULE, 132 84 }; 85 + 86 + static struct phy_ops imx8mp_usb_phy_ops = { 87 + .init = imx8mp_usb_phy_init, 88 + .power_on = imx8mq_phy_power_on, 89 + .power_off = imx8mq_phy_power_off, 90 + .owner = THIS_MODULE, 91 + }; 92 + 93 + static const struct of_device_id imx8mq_usb_phy_of_match[] = { 94 + {.compatible = "fsl,imx8mq-usb-phy", 95 + .data = &imx8mq_usb_phy_ops,}, 96 + {.compatible = "fsl,imx8mp-usb-phy", 97 + .data = &imx8mp_usb_phy_ops,}, 98 + { } 99 + }; 100 + MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match); 133 101 134 102 static int imx8mq_usb_phy_probe(struct platform_device *pdev) 135 103 { ··· 153 89 struct device *dev = &pdev->dev; 154 90 struct imx8mq_usb_phy *imx_phy; 155 91 struct resource *res; 92 + const struct phy_ops *phy_ops; 156 93 157 94 imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL); 158 95 if (!imx_phy) ··· 170 105 if (IS_ERR(imx_phy->base)) 171 106 return PTR_ERR(imx_phy->base); 172 107 173 - imx_phy->phy = devm_phy_create(dev, NULL, &imx8mq_usb_phy_ops); 108 + phy_ops = of_device_get_match_data(dev); 109 + if (!phy_ops) 110 + return -EINVAL; 111 + 112 + imx_phy->phy = devm_phy_create(dev, NULL, phy_ops); 174 113 if (IS_ERR(imx_phy->phy)) 175 114 return PTR_ERR(imx_phy->phy); 176 115 ··· 188 119 189 120 return PTR_ERR_OR_ZERO(phy_provider); 190 121 } 191 - 192 - static const struct of_device_id imx8mq_usb_phy_of_match[] = { 193 - {.compatible = "fsl,imx8mq-usb-phy",}, 194 - { }, 195 - }; 196 - MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match); 197 122 198 123 static struct platform_driver imx8mq_usb_phy_driver = { 199 124 .probe = imx8mq_usb_phy_probe,
+1 -1
drivers/phy/hisilicon/phy-hi3660-usb3.c
··· 161 161 return ret; 162 162 } 163 163 164 - static struct phy_ops hi3660_phy_ops = { 164 + static const struct phy_ops hi3660_phy_ops = { 165 165 .init = hi3660_phy_init, 166 166 .exit = hi3660_phy_exit, 167 167 .owner = THIS_MODULE,
+17 -5
drivers/phy/intel/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # 3 - # Phy drivers for Intel Lightning Mountain(LGM) platform 3 + # Phy drivers for Intel platforms 4 4 # 5 - config PHY_INTEL_COMBO 6 - bool "Intel ComboPHY driver" 5 + config PHY_INTEL_KEEMBAY_EMMC 6 + tristate "Intel Keem Bay EMMC PHY driver" 7 + depends on (OF && ARM64) || COMPILE_TEST 8 + depends on HAS_IOMEM 9 + select GENERIC_PHY 10 + select REGMAP_MMIO 11 + help 12 + Choose this option if you have an Intel Keem Bay SoC. 13 + 14 + To compile this driver as a module, choose M here: the module 15 + will be called phy-keembay-emmc.ko. 16 + 17 + config PHY_INTEL_LGM_COMBO 18 + bool "Intel Lightning Mountain ComboPHY driver" 7 19 depends on X86 || COMPILE_TEST 8 20 depends on OF && HAS_IOMEM 9 21 select MFD_SYSCON ··· 28 16 chipsets which provides PHYs for various controllers, EMAC, 29 17 SATA and PCIe. 30 18 31 - config PHY_INTEL_EMMC 32 - tristate "Intel EMMC PHY driver" 19 + config PHY_INTEL_LGM_EMMC 20 + tristate "Intel Lightning Mountain EMMC PHY driver" 33 21 depends on X86 || COMPILE_TEST 34 22 select GENERIC_PHY 35 23 help
+3 -2
drivers/phy/intel/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_PHY_INTEL_COMBO) += phy-intel-combo.o 3 - obj-$(CONFIG_PHY_INTEL_EMMC) += phy-intel-emmc.o 2 + obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC) += phy-intel-keembay-emmc.o 3 + obj-$(CONFIG_PHY_INTEL_LGM_COMBO) += phy-intel-lgm-combo.o 4 + obj-$(CONFIG_PHY_INTEL_LGM_EMMC) += phy-intel-lgm-emmc.o
drivers/phy/intel/phy-intel-combo.c drivers/phy/intel/phy-intel-lgm-combo.c
drivers/phy/intel/phy-intel-emmc.c drivers/phy/intel/phy-intel-lgm-emmc.c
+307
drivers/phy/intel/phy-intel-keembay-emmc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Intel Keem Bay eMMC PHY driver 4 + * Copyright (C) 2020 Intel Corporation 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/clk.h> 9 + #include <linux/delay.h> 10 + #include <linux/mfd/syscon.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/of_address.h> 14 + #include <linux/phy/phy.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + 18 + /* eMMC/SD/SDIO core/phy configuration registers */ 19 + #define PHY_CFG_0 0x24 20 + #define SEL_DLY_TXCLK_MASK BIT(29) 21 + #define OTAP_DLY_ENA_MASK BIT(27) 22 + #define OTAP_DLY_SEL_MASK GENMASK(26, 23) 23 + #define DLL_EN_MASK BIT(10) 24 + #define PWR_DOWN_MASK BIT(0) 25 + 26 + #define PHY_CFG_2 0x2c 27 + #define SEL_FREQ_MASK GENMASK(12, 10) 28 + 29 + #define PHY_STAT 0x40 30 + #define CAL_DONE_MASK BIT(6) 31 + #define IS_CALDONE(x) ((x) & CAL_DONE_MASK) 32 + #define DLL_RDY_MASK BIT(5) 33 + #define IS_DLLRDY(x) ((x) & DLL_RDY_MASK) 34 + 35 + /* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */ 36 + #define FREQSEL_200M_170M 0x0 37 + #define FREQSEL_170M_140M 0x1 38 + #define FREQSEL_140M_110M 0x2 39 + #define FREQSEL_110M_80M 0x3 40 + #define FREQSEL_80M_50M 0x4 41 + 42 + struct keembay_emmc_phy { 43 + struct regmap *syscfg; 44 + struct clk *emmcclk; 45 + }; 46 + 47 + static const struct regmap_config keembay_regmap_config = { 48 + .reg_bits = 32, 49 + .val_bits = 32, 50 + .reg_stride = 4, 51 + }; 52 + 53 + static int keembay_emmc_phy_power(struct phy *phy, bool on_off) 54 + { 55 + struct keembay_emmc_phy *priv = phy_get_drvdata(phy); 56 + unsigned int caldone; 57 + unsigned int dllrdy; 58 + unsigned int freqsel; 59 + unsigned int mhz; 60 + int ret; 61 + 62 + /* 63 + * Keep phyctrl_pdb and phyctrl_endll low to allow 64 + * initialization of CALIO state M/C DFFs 65 + */ 66 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, PWR_DOWN_MASK, 67 + FIELD_PREP(PWR_DOWN_MASK, 0)); 68 + if (ret) { 69 + dev_err(&phy->dev, "CALIO power down bar failed: %d\n", ret); 70 + return ret; 71 + } 72 + 73 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, DLL_EN_MASK, 74 + FIELD_PREP(DLL_EN_MASK, 0)); 75 + if (ret) { 76 + dev_err(&phy->dev, "turn off the dll failed: %d\n", ret); 77 + return ret; 78 + } 79 + 80 + /* Already finish power off above */ 81 + if (!on_off) 82 + return 0; 83 + 84 + mhz = DIV_ROUND_CLOSEST(clk_get_rate(priv->emmcclk), 1000000); 85 + if (mhz <= 200 && mhz >= 170) 86 + freqsel = FREQSEL_200M_170M; 87 + else if (mhz <= 170 && mhz >= 140) 88 + freqsel = FREQSEL_170M_140M; 89 + else if (mhz <= 140 && mhz >= 110) 90 + freqsel = FREQSEL_140M_110M; 91 + else if (mhz <= 110 && mhz >= 80) 92 + freqsel = FREQSEL_110M_80M; 93 + else if (mhz <= 80 && mhz >= 50) 94 + freqsel = FREQSEL_80M_50M; 95 + else 96 + freqsel = 0x0; 97 + 98 + if (mhz < 50 || mhz > 200) 99 + dev_warn(&phy->dev, "Unsupported rate: %d MHz\n", mhz); 100 + 101 + /* 102 + * According to the user manual, calpad calibration 103 + * cycle takes more than 2us without the minimal recommended 104 + * value, so we may need a little margin here 105 + */ 106 + udelay(5); 107 + 108 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, PWR_DOWN_MASK, 109 + FIELD_PREP(PWR_DOWN_MASK, 1)); 110 + if (ret) { 111 + dev_err(&phy->dev, "CALIO power down bar failed: %d\n", ret); 112 + return ret; 113 + } 114 + 115 + /* 116 + * According to the user manual, it asks driver to wait 5us for 117 + * calpad busy trimming. However it is documented that this value is 118 + * PVT(A.K.A. process, voltage and temperature) relevant, so some 119 + * failure cases are found which indicates we should be more tolerant 120 + * to calpad busy trimming. 121 + */ 122 + ret = regmap_read_poll_timeout(priv->syscfg, PHY_STAT, 123 + caldone, IS_CALDONE(caldone), 124 + 0, 50); 125 + if (ret) { 126 + dev_err(&phy->dev, "caldone failed, ret=%d\n", ret); 127 + return ret; 128 + } 129 + 130 + /* Set the frequency of the DLL operation */ 131 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_2, SEL_FREQ_MASK, 132 + FIELD_PREP(SEL_FREQ_MASK, freqsel)); 133 + if (ret) { 134 + dev_err(&phy->dev, "set the frequency of dll failed:%d\n", ret); 135 + return ret; 136 + } 137 + 138 + /* Turn on the DLL */ 139 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, DLL_EN_MASK, 140 + FIELD_PREP(DLL_EN_MASK, 1)); 141 + if (ret) { 142 + dev_err(&phy->dev, "turn on the dll failed: %d\n", ret); 143 + return ret; 144 + } 145 + 146 + /* 147 + * We turned on the DLL even though the rate was 0 because we the 148 + * clock might be turned on later. ...but we can't wait for the DLL 149 + * to lock when the rate is 0 because it will never lock with no 150 + * input clock. 151 + * 152 + * Technically we should be checking the lock later when the clock 153 + * is turned on, but for now we won't. 154 + */ 155 + if (mhz == 0) 156 + return 0; 157 + 158 + /* 159 + * After enabling analog DLL circuits docs say that we need 10.2 us if 160 + * our source clock is at 50 MHz and that lock time scales linearly 161 + * with clock speed. If we are powering on the PHY and the card clock 162 + * is super slow (like 100kHz) this could take as long as 5.1 ms as 163 + * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms 164 + * hopefully we won't be running at 100 kHz, but we should still make 165 + * sure we wait long enough. 166 + * 167 + * NOTE: There appear to be corner cases where the DLL seems to take 168 + * extra long to lock for reasons that aren't understood. In some 169 + * extreme cases we've seen it take up to over 10ms (!). We'll be 170 + * generous and give it 50ms. 171 + */ 172 + ret = regmap_read_poll_timeout(priv->syscfg, PHY_STAT, 173 + dllrdy, IS_DLLRDY(dllrdy), 174 + 0, 50 * USEC_PER_MSEC); 175 + if (ret) 176 + dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret); 177 + 178 + return ret; 179 + } 180 + 181 + static int keembay_emmc_phy_init(struct phy *phy) 182 + { 183 + struct keembay_emmc_phy *priv = phy_get_drvdata(phy); 184 + 185 + /* 186 + * We purposely get the clock here and not in probe to avoid the 187 + * circular dependency problem. We expect: 188 + * - PHY driver to probe 189 + * - SDHCI driver to start probe 190 + * - SDHCI driver to register it's clock 191 + * - SDHCI driver to get the PHY 192 + * - SDHCI driver to init the PHY 193 + * 194 + * The clock is optional, so upon any error just return it like 195 + * any other error to user. 196 + */ 197 + priv->emmcclk = clk_get_optional(&phy->dev, "emmcclk"); 198 + 199 + return PTR_ERR_OR_ZERO(priv->emmcclk); 200 + } 201 + 202 + static int keembay_emmc_phy_exit(struct phy *phy) 203 + { 204 + struct keembay_emmc_phy *priv = phy_get_drvdata(phy); 205 + 206 + clk_put(priv->emmcclk); 207 + 208 + return 0; 209 + }; 210 + 211 + static int keembay_emmc_phy_power_on(struct phy *phy) 212 + { 213 + struct keembay_emmc_phy *priv = phy_get_drvdata(phy); 214 + int ret; 215 + 216 + /* Delay chain based txclk: enable */ 217 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, SEL_DLY_TXCLK_MASK, 218 + FIELD_PREP(SEL_DLY_TXCLK_MASK, 1)); 219 + if (ret) { 220 + dev_err(&phy->dev, "ERROR: delay chain txclk set: %d\n", ret); 221 + return ret; 222 + } 223 + 224 + /* Output tap delay: enable */ 225 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, OTAP_DLY_ENA_MASK, 226 + FIELD_PREP(OTAP_DLY_ENA_MASK, 1)); 227 + if (ret) { 228 + dev_err(&phy->dev, "ERROR: output tap delay set: %d\n", ret); 229 + return ret; 230 + } 231 + 232 + /* Output tap delay */ 233 + ret = regmap_update_bits(priv->syscfg, PHY_CFG_0, OTAP_DLY_SEL_MASK, 234 + FIELD_PREP(OTAP_DLY_SEL_MASK, 2)); 235 + if (ret) { 236 + dev_err(&phy->dev, "ERROR: output tap delay select: %d\n", ret); 237 + return ret; 238 + } 239 + 240 + /* Power up eMMC phy analog blocks */ 241 + return keembay_emmc_phy_power(phy, true); 242 + } 243 + 244 + static int keembay_emmc_phy_power_off(struct phy *phy) 245 + { 246 + /* Power down eMMC phy analog blocks */ 247 + return keembay_emmc_phy_power(phy, false); 248 + } 249 + 250 + static const struct phy_ops ops = { 251 + .init = keembay_emmc_phy_init, 252 + .exit = keembay_emmc_phy_exit, 253 + .power_on = keembay_emmc_phy_power_on, 254 + .power_off = keembay_emmc_phy_power_off, 255 + .owner = THIS_MODULE, 256 + }; 257 + 258 + static int keembay_emmc_phy_probe(struct platform_device *pdev) 259 + { 260 + struct device *dev = &pdev->dev; 261 + struct device_node *np = dev->of_node; 262 + struct keembay_emmc_phy *priv; 263 + struct phy *generic_phy; 264 + struct phy_provider *phy_provider; 265 + void __iomem *base; 266 + 267 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 268 + if (!priv) 269 + return -ENOMEM; 270 + 271 + base = devm_platform_ioremap_resource(pdev, 0); 272 + if (IS_ERR(base)) 273 + return PTR_ERR(base); 274 + 275 + priv->syscfg = devm_regmap_init_mmio(dev, base, &keembay_regmap_config); 276 + if (IS_ERR(priv->syscfg)) 277 + return PTR_ERR(priv->syscfg); 278 + 279 + generic_phy = devm_phy_create(dev, np, &ops); 280 + if (IS_ERR(generic_phy)) 281 + return dev_err_probe(dev, PTR_ERR(generic_phy), 282 + "failed to create PHY\n"); 283 + 284 + phy_set_drvdata(generic_phy, priv); 285 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 286 + 287 + return PTR_ERR_OR_ZERO(phy_provider); 288 + } 289 + 290 + static const struct of_device_id keembay_emmc_phy_dt_ids[] = { 291 + { .compatible = "intel,keembay-emmc-phy" }, 292 + {} 293 + }; 294 + MODULE_DEVICE_TABLE(of, keembay_emmc_phy_dt_ids); 295 + 296 + static struct platform_driver keembay_emmc_phy_driver = { 297 + .probe = keembay_emmc_phy_probe, 298 + .driver = { 299 + .name = "keembay-emmc-phy", 300 + .of_match_table = keembay_emmc_phy_dt_ids, 301 + }, 302 + }; 303 + module_platform_driver(keembay_emmc_phy_driver); 304 + 305 + MODULE_AUTHOR("Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>"); 306 + MODULE_DESCRIPTION("Intel Keem Bay eMMC PHY driver"); 307 + MODULE_LICENSE("GPL v2");
+1 -1
drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
··· 141 141 return 0; 142 142 } 143 143 144 - static struct phy_ops ltq_rcu_usb2_phy_ops = { 144 + static const struct phy_ops ltq_rcu_usb2_phy_ops = { 145 145 .init = ltq_rcu_usb2_phy_init, 146 146 .power_on = ltq_rcu_usb2_phy_power_on, 147 147 .power_off = ltq_rcu_usb2_phy_power_off,
+1 -1
drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
··· 349 349 return 0; 350 350 } 351 351 352 - static struct phy_ops ltq_vrx200_pcie_phy_ops = { 352 + static const struct phy_ops ltq_vrx200_pcie_phy_ops = { 353 353 .init = ltq_vrx200_pcie_phy_init, 354 354 .exit = ltq_vrx200_pcie_phy_exit, 355 355 .power_on = ltq_vrx200_pcie_phy_power_on,
+20 -20
drivers/phy/marvell/phy-pxa-28nm-hsic.c
··· 12 12 #include <linux/slab.h> 13 13 #include <linux/of.h> 14 14 #include <linux/io.h> 15 + #include <linux/iopoll.h> 15 16 #include <linux/err.h> 16 17 #include <linux/clk.h> 17 18 #include <linux/module.h> ··· 45 44 struct clk *clk; 46 45 }; 47 46 48 - static bool wait_for_reg(void __iomem *reg, u32 mask, unsigned long timeout) 47 + static int wait_for_reg(void __iomem *reg, u32 mask, u32 ms) 49 48 { 50 - timeout += jiffies; 51 - while (time_is_after_eq_jiffies(timeout)) { 52 - if ((readl(reg) & mask) == mask) 53 - return true; 54 - msleep(1); 55 - } 56 - return false; 49 + u32 val; 50 + 51 + return readl_poll_timeout(reg, val, ((val & mask) == mask), 52 + 1000, 1000 * ms); 57 53 } 58 54 59 55 static int mv_hsic_phy_init(struct phy *phy) ··· 58 60 struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); 59 61 struct platform_device *pdev = mv_phy->pdev; 60 62 void __iomem *base = mv_phy->base; 63 + int ret; 61 64 62 65 clk_prepare_enable(mv_phy->clk); 63 66 ··· 74 75 base + PHY_28NM_HSIC_PLL_CTRL2); 75 76 76 77 /* Make sure PHY PLL is locked */ 77 - if (!wait_for_reg(base + PHY_28NM_HSIC_PLL_CTRL2, 78 - PHY_28NM_HSIC_H2S_PLL_LOCK, HZ / 10)) { 78 + ret = wait_for_reg(base + PHY_28NM_HSIC_PLL_CTRL2, 79 + PHY_28NM_HSIC_H2S_PLL_LOCK, 100); 80 + if (ret) { 79 81 dev_err(&pdev->dev, "HSIC PHY PLL not locked after 100mS."); 80 82 clk_disable_unprepare(mv_phy->clk); 81 - return -ETIMEDOUT; 82 83 } 83 84 84 - return 0; 85 + return ret; 85 86 } 86 87 87 88 static int mv_hsic_phy_power_on(struct phy *phy) ··· 90 91 struct platform_device *pdev = mv_phy->pdev; 91 92 void __iomem *base = mv_phy->base; 92 93 u32 reg; 94 + int ret; 93 95 94 96 reg = readl(base + PHY_28NM_HSIC_CTRL); 95 97 /* Avoid SE0 state when resume for some device will take it as reset */ ··· 108 108 */ 109 109 110 110 /* Make sure PHY Calibration is ready */ 111 - if (!wait_for_reg(base + PHY_28NM_HSIC_IMPCAL_CAL, 112 - PHY_28NM_HSIC_H2S_IMPCAL_DONE, HZ / 10)) { 111 + ret = wait_for_reg(base + PHY_28NM_HSIC_IMPCAL_CAL, 112 + PHY_28NM_HSIC_H2S_IMPCAL_DONE, 100); 113 + if (ret) { 113 114 dev_warn(&pdev->dev, "HSIC PHY READY not set after 100mS."); 114 - return -ETIMEDOUT; 115 + return ret; 115 116 } 116 117 117 118 /* Waiting for HSIC connect int*/ 118 - if (!wait_for_reg(base + PHY_28NM_HSIC_INT, 119 - PHY_28NM_HSIC_CONNECT_INT, HZ / 5)) { 119 + ret = wait_for_reg(base + PHY_28NM_HSIC_INT, 120 + PHY_28NM_HSIC_CONNECT_INT, 200); 121 + if (ret) 120 122 dev_warn(&pdev->dev, "HSIC wait for connect interrupt timeout."); 121 - return -ETIMEDOUT; 122 - } 123 123 124 - return 0; 124 + return ret; 125 125 } 126 126 127 127 static int mv_hsic_phy_power_off(struct phy *phy)
+15 -18
drivers/phy/marvell/phy-pxa-28nm-usb2.c
··· 13 13 #include <linux/of.h> 14 14 #include <linux/of_device.h> 15 15 #include <linux/io.h> 16 + #include <linux/iopoll.h> 16 17 #include <linux/err.h> 17 18 #include <linux/clk.h> 18 19 #include <linux/module.h> ··· 139 138 struct clk *clk; 140 139 }; 141 140 142 - static bool wait_for_reg(void __iomem *reg, u32 mask, unsigned long timeout) 141 + static int wait_for_reg(void __iomem *reg, u32 mask, u32 ms) 143 142 { 144 - timeout += jiffies; 145 - while (time_is_after_eq_jiffies(timeout)) { 146 - if ((readl(reg) & mask) == mask) 147 - return true; 148 - msleep(1); 149 - } 150 - return false; 143 + u32 val; 144 + 145 + return readl_poll_timeout(reg, val, ((val & mask) == mask), 146 + 1000, 1000 * ms); 151 147 } 152 148 153 149 static int mv_usb2_phy_28nm_init(struct phy *phy) ··· 206 208 */ 207 209 208 210 /* Make sure PHY Calibration is ready */ 209 - if (!wait_for_reg(base + PHY_28NM_CAL_REG, 210 - PHY_28NM_PLL_PLLCAL_DONE | PHY_28NM_PLL_IMPCAL_DONE, 211 - HZ / 10)) { 211 + ret = wait_for_reg(base + PHY_28NM_CAL_REG, 212 + PHY_28NM_PLL_PLLCAL_DONE | PHY_28NM_PLL_IMPCAL_DONE, 213 + 100); 214 + if (ret) { 212 215 dev_warn(&pdev->dev, "USB PHY PLL calibrate not done after 100mS."); 213 - ret = -ETIMEDOUT; 214 216 goto err_clk; 215 217 } 216 - if (!wait_for_reg(base + PHY_28NM_RX_REG1, 217 - PHY_28NM_RX_SQCAL_DONE, HZ / 10)) { 218 + ret = wait_for_reg(base + PHY_28NM_RX_REG1, 219 + PHY_28NM_RX_SQCAL_DONE, 100); 220 + if (ret) { 218 221 dev_warn(&pdev->dev, "USB PHY RX SQ calibrate not done after 100mS."); 219 - ret = -ETIMEDOUT; 220 222 goto err_clk; 221 223 } 222 224 /* Make sure PHY PLL is ready */ 223 - if (!wait_for_reg(base + PHY_28NM_PLL_REG0, 224 - PHY_28NM_PLL_READY, HZ / 10)) { 225 + ret = wait_for_reg(base + PHY_28NM_PLL_REG0, PHY_28NM_PLL_READY, 100); 226 + if (ret) { 225 227 dev_warn(&pdev->dev, "PLL_READY not set after 100mS."); 226 - ret = -ETIMEDOUT; 227 228 goto err_clk; 228 229 } 229 230
+284
drivers/phy/phy-lgm-usb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Intel LGM USB PHY driver 4 + * 5 + * Copyright (C) 2020 Intel Corporation. 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/delay.h> 10 + #include <linux/iopoll.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regulator/consumer.h> 15 + #include <linux/reset.h> 16 + #include <linux/usb/phy.h> 17 + #include <linux/workqueue.h> 18 + 19 + #define CTRL1_OFFSET 0x14 20 + #define SRAM_EXT_LD_DONE BIT(25) 21 + #define SRAM_INIT_DONE BIT(26) 22 + 23 + #define TCPC_OFFSET 0x1014 24 + #define TCPC_MUX_CTL GENMASK(1, 0) 25 + #define MUX_NC 0 26 + #define MUX_USB 1 27 + #define MUX_DP 2 28 + #define MUX_USBDP 3 29 + #define TCPC_FLIPPED BIT(2) 30 + #define TCPC_LOW_POWER_EN BIT(3) 31 + #define TCPC_VALID BIT(4) 32 + #define TCPC_CONN \ 33 + (TCPC_VALID | FIELD_PREP(TCPC_MUX_CTL, MUX_USB)) 34 + #define TCPC_DISCONN \ 35 + (TCPC_VALID | FIELD_PREP(TCPC_MUX_CTL, MUX_NC) | TCPC_LOW_POWER_EN) 36 + 37 + static const char *const PHY_RESETS[] = { "phy31", "phy", }; 38 + static const char *const CTL_RESETS[] = { "apb", "ctrl", }; 39 + 40 + struct tca_apb { 41 + struct reset_control *resets[ARRAY_SIZE(PHY_RESETS)]; 42 + struct regulator *vbus; 43 + struct work_struct wk; 44 + struct usb_phy phy; 45 + 46 + bool regulator_enabled; 47 + bool phy_initialized; 48 + bool connected; 49 + }; 50 + 51 + static int get_flipped(struct tca_apb *ta, bool *flipped) 52 + { 53 + union extcon_property_value property; 54 + int ret; 55 + 56 + ret = extcon_get_property(ta->phy.edev, EXTCON_USB_HOST, 57 + EXTCON_PROP_USB_TYPEC_POLARITY, &property); 58 + if (ret) { 59 + dev_err(ta->phy.dev, "no polarity property from extcon\n"); 60 + return ret; 61 + } 62 + 63 + *flipped = property.intval; 64 + 65 + return 0; 66 + } 67 + 68 + static int phy_init(struct usb_phy *phy) 69 + { 70 + struct tca_apb *ta = container_of(phy, struct tca_apb, phy); 71 + void __iomem *ctrl1 = phy->io_priv + CTRL1_OFFSET; 72 + int val, ret, i; 73 + 74 + if (ta->phy_initialized) 75 + return 0; 76 + 77 + for (i = 0; i < ARRAY_SIZE(PHY_RESETS); i++) 78 + reset_control_deassert(ta->resets[i]); 79 + 80 + ret = readl_poll_timeout(ctrl1, val, val & SRAM_INIT_DONE, 10, 10 * 1000); 81 + if (ret) { 82 + dev_err(ta->phy.dev, "SRAM init failed, 0x%x\n", val); 83 + return ret; 84 + } 85 + 86 + writel(readl(ctrl1) | SRAM_EXT_LD_DONE, ctrl1); 87 + 88 + ta->phy_initialized = true; 89 + if (!ta->phy.edev) { 90 + writel(TCPC_CONN, ta->phy.io_priv + TCPC_OFFSET); 91 + return phy->set_vbus(phy, true); 92 + } 93 + 94 + schedule_work(&ta->wk); 95 + 96 + return ret; 97 + } 98 + 99 + static void phy_shutdown(struct usb_phy *phy) 100 + { 101 + struct tca_apb *ta = container_of(phy, struct tca_apb, phy); 102 + int i; 103 + 104 + if (!ta->phy_initialized) 105 + return; 106 + 107 + ta->phy_initialized = false; 108 + flush_work(&ta->wk); 109 + ta->phy.set_vbus(&ta->phy, false); 110 + 111 + ta->connected = false; 112 + writel(TCPC_DISCONN, ta->phy.io_priv + TCPC_OFFSET); 113 + 114 + for (i = 0; i < ARRAY_SIZE(PHY_RESETS); i++) 115 + reset_control_assert(ta->resets[i]); 116 + } 117 + 118 + static int phy_set_vbus(struct usb_phy *phy, int on) 119 + { 120 + struct tca_apb *ta = container_of(phy, struct tca_apb, phy); 121 + int ret; 122 + 123 + if (!!on == ta->regulator_enabled) 124 + return 0; 125 + 126 + if (on) 127 + ret = regulator_enable(ta->vbus); 128 + else 129 + ret = regulator_disable(ta->vbus); 130 + 131 + if (!ret) 132 + ta->regulator_enabled = on; 133 + 134 + dev_dbg(ta->phy.dev, "set vbus: %d\n", on); 135 + return ret; 136 + } 137 + 138 + static void tca_work(struct work_struct *work) 139 + { 140 + struct tca_apb *ta = container_of(work, struct tca_apb, wk); 141 + bool connected; 142 + bool flipped = false; 143 + u32 val; 144 + int ret; 145 + 146 + ret = get_flipped(ta, &flipped); 147 + if (ret) 148 + return; 149 + 150 + connected = extcon_get_state(ta->phy.edev, EXTCON_USB_HOST); 151 + if (connected == ta->connected) 152 + return; 153 + 154 + ta->connected = connected; 155 + if (connected) { 156 + val = TCPC_CONN; 157 + if (flipped) 158 + val |= TCPC_FLIPPED; 159 + dev_dbg(ta->phy.dev, "connected%s\n", flipped ? " flipped" : ""); 160 + } else { 161 + val = TCPC_DISCONN; 162 + dev_dbg(ta->phy.dev, "disconnected\n"); 163 + } 164 + 165 + writel(val, ta->phy.io_priv + TCPC_OFFSET); 166 + 167 + ret = ta->phy.set_vbus(&ta->phy, connected); 168 + if (ret) 169 + dev_err(ta->phy.dev, "failed to set VBUS\n"); 170 + } 171 + 172 + static int id_notifier(struct notifier_block *nb, unsigned long event, void *ptr) 173 + { 174 + struct tca_apb *ta = container_of(nb, struct tca_apb, phy.id_nb); 175 + 176 + if (ta->phy_initialized) 177 + schedule_work(&ta->wk); 178 + 179 + return NOTIFY_DONE; 180 + } 181 + 182 + static int vbus_notifier(struct notifier_block *nb, unsigned long evnt, void *ptr) 183 + { 184 + return NOTIFY_DONE; 185 + } 186 + 187 + static int phy_probe(struct platform_device *pdev) 188 + { 189 + struct reset_control *resets[ARRAY_SIZE(CTL_RESETS)]; 190 + struct device *dev = &pdev->dev; 191 + struct usb_phy *phy; 192 + struct tca_apb *ta; 193 + int i; 194 + 195 + ta = devm_kzalloc(dev, sizeof(*ta), GFP_KERNEL); 196 + if (!ta) 197 + return -ENOMEM; 198 + 199 + platform_set_drvdata(pdev, ta); 200 + INIT_WORK(&ta->wk, tca_work); 201 + 202 + phy = &ta->phy; 203 + phy->dev = dev; 204 + phy->label = dev_name(dev); 205 + phy->type = USB_PHY_TYPE_USB3; 206 + phy->init = phy_init; 207 + phy->shutdown = phy_shutdown; 208 + phy->set_vbus = phy_set_vbus; 209 + phy->id_nb.notifier_call = id_notifier; 210 + phy->vbus_nb.notifier_call = vbus_notifier; 211 + 212 + phy->io_priv = devm_platform_ioremap_resource(pdev, 0); 213 + if (IS_ERR(phy->io_priv)) 214 + return PTR_ERR(phy->io_priv); 215 + 216 + ta->vbus = devm_regulator_get(dev, "vbus"); 217 + if (IS_ERR(ta->vbus)) 218 + return PTR_ERR(ta->vbus); 219 + 220 + for (i = 0; i < ARRAY_SIZE(CTL_RESETS); i++) { 221 + resets[i] = devm_reset_control_get_exclusive(dev, CTL_RESETS[i]); 222 + if (IS_ERR(resets[i])) { 223 + dev_err(dev, "%s reset not found\n", CTL_RESETS[i]); 224 + return PTR_ERR(resets[i]); 225 + } 226 + } 227 + 228 + for (i = 0; i < ARRAY_SIZE(PHY_RESETS); i++) { 229 + ta->resets[i] = devm_reset_control_get_exclusive(dev, PHY_RESETS[i]); 230 + if (IS_ERR(ta->resets[i])) { 231 + dev_err(dev, "%s reset not found\n", PHY_RESETS[i]); 232 + return PTR_ERR(ta->resets[i]); 233 + } 234 + } 235 + 236 + for (i = 0; i < ARRAY_SIZE(CTL_RESETS); i++) 237 + reset_control_assert(resets[i]); 238 + 239 + for (i = 0; i < ARRAY_SIZE(PHY_RESETS); i++) 240 + reset_control_assert(ta->resets[i]); 241 + /* 242 + * Out-of-band reset of the controller after PHY reset will cause 243 + * controller malfunctioning, so we should use in-band controller 244 + * reset only and leave the controller de-asserted here. 245 + */ 246 + for (i = 0; i < ARRAY_SIZE(CTL_RESETS); i++) 247 + reset_control_deassert(resets[i]); 248 + 249 + /* Need to wait at least 20us after de-assert the controller */ 250 + usleep_range(20, 100); 251 + 252 + return usb_add_phy_dev(phy); 253 + } 254 + 255 + static int phy_remove(struct platform_device *pdev) 256 + { 257 + struct tca_apb *ta = platform_get_drvdata(pdev); 258 + 259 + usb_remove_phy(&ta->phy); 260 + 261 + return 0; 262 + } 263 + 264 + static const struct of_device_id intel_usb_phy_dt_ids[] = { 265 + { .compatible = "intel,lgm-usb-phy" }, 266 + { } 267 + }; 268 + MODULE_DEVICE_TABLE(of, intel_usb_phy_dt_ids); 269 + 270 + static struct platform_driver lgm_phy_driver = { 271 + .driver = { 272 + .name = "lgm-usb-phy", 273 + .of_match_table = intel_usb_phy_dt_ids, 274 + }, 275 + .probe = phy_probe, 276 + .remove = phy_remove, 277 + }; 278 + 279 + module_platform_driver(lgm_phy_driver); 280 + 281 + MODULE_DESCRIPTION("Intel LGM USB PHY driver"); 282 + MODULE_AUTHOR("Li Yin <yin1.li@intel.com>"); 283 + MODULE_AUTHOR("Vadivel Murugan R <vadivel.muruganx.ramuthevar@linux.intel.com>"); 284 + MODULE_LICENSE("GPL v2");
+8 -13
drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
··· 4 4 */ 5 5 6 6 #include <linux/io.h> 7 + #include <linux/iopoll.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/module.h> 9 10 #include <linux/of.h> ··· 73 72 }; 74 73 75 74 /* Helper function to do poll and timeout */ 76 - static int read_poll_timeout(void __iomem *addr, u32 mask) 75 + static int poll_timeout(void __iomem *addr, u32 mask) 77 76 { 78 - unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); 77 + u32 val; 79 78 80 - do { 81 - if (readl_relaxed(addr) & mask) 82 - return 0; 83 - 84 - usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); 85 - } while (!time_after(jiffies, timeout)); 86 - 87 - return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT; 79 + return readl_relaxed_poll_timeout(addr, val, (val & mask), 80 + DELAY_INTERVAL_US, TIMEOUT_MS * 1000); 88 81 } 89 82 90 83 static int qcom_apq8064_sata_phy_init(struct phy *generic_phy) ··· 132 137 writel_relaxed(0x05, base + UNIPHY_PLL_LKDET_CFG2); 133 138 134 139 /* PLL Lock wait */ 135 - ret = read_poll_timeout(base + UNIPHY_PLL_STATUS, UNIPHY_PLL_LOCK); 140 + ret = poll_timeout(base + UNIPHY_PLL_STATUS, UNIPHY_PLL_LOCK); 136 141 if (ret) { 137 142 dev_err(phy->dev, "poll timeout UNIPHY_PLL_STATUS\n"); 138 143 return ret; 139 144 } 140 145 141 146 /* TX Calibration */ 142 - ret = read_poll_timeout(base + SATA_PHY_TX_IMCAL_STAT, SATA_PHY_TX_CAL); 147 + ret = poll_timeout(base + SATA_PHY_TX_IMCAL_STAT, SATA_PHY_TX_CAL); 143 148 if (ret) { 144 149 dev_err(phy->dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n"); 145 150 return ret; 146 151 } 147 152 148 153 /* RX Calibration */ 149 - ret = read_poll_timeout(base + SATA_PHY_RX_IMCAL_STAT, SATA_PHY_RX_CAL); 154 + ret = poll_timeout(base + SATA_PHY_RX_IMCAL_STAT, SATA_PHY_RX_CAL); 150 155 if (ret) { 151 156 dev_err(phy->dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n"); 152 157 return ret;
+2 -2
drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
··· 48 48 return 0; 49 49 } 50 50 51 - static struct phy_ops ipq4019_usb_ss_phy_ops = { 51 + static const struct phy_ops ipq4019_usb_ss_phy_ops = { 52 52 .power_on = ipq4019_ss_phy_power_on, 53 53 .power_off = ipq4019_ss_phy_power_off, 54 54 }; ··· 80 80 return 0; 81 81 } 82 82 83 - static struct phy_ops ipq4019_usb_hs_phy_ops = { 83 + static const struct phy_ops ipq4019_usb_hs_phy_ops = { 84 84 .power_on = ipq4019_hs_phy_power_on, 85 85 .power_off = ipq4019_hs_phy_power_off, 86 86 };
+891 -178
drivers/phy/qualcomm/phy-qcom-qmp.c
··· 946 946 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06), 947 947 }; 948 948 949 + static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl[] = { 950 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01), 951 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x37), 952 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02), 953 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_ENABLE1, 0x0e), 954 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE, 0x06), 955 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), 956 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x02), 957 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0x00), 958 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), 959 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), 960 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00), 961 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00), 962 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), 963 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a), 964 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00), 965 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x3f), 966 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x1f), 967 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), 968 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), 969 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), 970 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), 971 + }; 972 + 973 + static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_rbr[] = { 974 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x0c), 975 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69), 976 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80), 977 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07), 978 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x6f), 979 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x08), 980 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00), 981 + }; 982 + 983 + static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr[] = { 984 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x04), 985 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69), 986 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80), 987 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07), 988 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x0f), 989 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0e), 990 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00), 991 + }; 992 + 993 + static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr2[] = { 994 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00), 995 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x8c), 996 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x00), 997 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x0a), 998 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x1f), 999 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x1c), 1000 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x00), 1001 + }; 1002 + 1003 + static const struct qmp_phy_init_tbl qmp_v3_dp_serdes_tbl_hbr3[] = { 1004 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x03), 1005 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x69), 1006 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0x80), 1007 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x07), 1008 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x2f), 1009 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x2a), 1010 + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x08), 1011 + }; 1012 + 1013 + static const struct qmp_phy_init_tbl qmp_v3_dp_tx_tbl[] = { 1014 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a), 1015 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40), 1016 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30), 1017 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d), 1018 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f), 1019 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03), 1020 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03), 1021 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), 1022 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00), 1023 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4), 1024 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_POL_INV, 0x0a), 1025 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x38), 1026 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x20), 1027 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x06), 1028 + QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07), 1029 + }; 1030 + 949 1031 static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = { 950 1032 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), 951 1033 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), ··· 1843 1761 const struct qmp_phy_init_tbl *pcs_misc_tbl; 1844 1762 int pcs_misc_tbl_num; 1845 1763 1764 + /* Init sequence for DP PHY block link rates */ 1765 + const struct qmp_phy_init_tbl *serdes_tbl_rbr; 1766 + int serdes_tbl_rbr_num; 1767 + const struct qmp_phy_init_tbl *serdes_tbl_hbr; 1768 + int serdes_tbl_hbr_num; 1769 + const struct qmp_phy_init_tbl *serdes_tbl_hbr2; 1770 + int serdes_tbl_hbr2_num; 1771 + const struct qmp_phy_init_tbl *serdes_tbl_hbr3; 1772 + int serdes_tbl_hbr3_num; 1773 + 1846 1774 /* clock ids to be requested */ 1847 1775 const char * const *clk_list; 1848 1776 int num_clks; ··· 1889 1797 bool no_pcs_sw_reset; 1890 1798 }; 1891 1799 1800 + struct qmp_phy_combo_cfg { 1801 + const struct qmp_phy_cfg *usb_cfg; 1802 + const struct qmp_phy_cfg *dp_cfg; 1803 + }; 1804 + 1892 1805 /** 1893 1806 * struct qmp_phy - per-lane phy descriptor 1894 1807 * 1895 1808 * @phy: generic phy 1809 + * @cfg: phy specific configuration 1810 + * @serdes: iomapped memory space for phy's serdes (i.e. PLL) 1896 1811 * @tx: iomapped memory space for lane's tx 1897 1812 * @rx: iomapped memory space for lane's rx 1898 1813 * @pcs: iomapped memory space for lane's pcs ··· 1910 1811 * @index: lane index 1911 1812 * @qmp: QMP phy to which this lane belongs 1912 1813 * @lane_rst: lane's reset controller 1814 + * @mode: current PHY mode 1913 1815 */ 1914 1816 struct qmp_phy { 1915 1817 struct phy *phy; 1818 + const struct qmp_phy_cfg *cfg; 1819 + void __iomem *serdes; 1916 1820 void __iomem *tx; 1917 1821 void __iomem *rx; 1918 1822 void __iomem *pcs; ··· 1926 1824 unsigned int index; 1927 1825 struct qcom_qmp *qmp; 1928 1826 struct reset_control *lane_rst; 1827 + enum phy_mode mode; 1828 + unsigned int dp_aux_cfg; 1829 + struct phy_configure_opts_dp dp_opts; 1830 + struct qmp_phy_dp_clks *dp_clks; 1831 + }; 1832 + 1833 + struct qmp_phy_dp_clks { 1834 + struct qmp_phy *qphy; 1835 + struct clk_hw dp_link_hw; 1836 + struct clk_hw dp_pixel_hw; 1929 1837 }; 1930 1838 1931 1839 /** 1932 1840 * struct qcom_qmp - structure holding QMP phy block attributes 1933 1841 * 1934 1842 * @dev: device 1935 - * @serdes: iomapped memory space for phy's serdes 1936 1843 * @dp_com: iomapped memory space for phy's dp_com control block 1937 1844 * 1938 1845 * @clks: array of clocks required by phy 1939 1846 * @resets: array of resets required by phy 1940 1847 * @vregs: regulator supplies bulk data 1941 1848 * 1942 - * @cfg: phy specific configuration 1943 1849 * @phys: array of per-lane phy descriptors 1944 1850 * @phy_mutex: mutex lock for PHY common block initialization 1945 1851 * @init_count: phy common block initialization count 1946 - * @phy_initialized: indicate if PHY has been initialized 1947 - * @mode: current PHY mode 1948 1852 * @ufs_reset: optional UFS PHY reset handle 1949 1853 */ 1950 1854 struct qcom_qmp { 1951 1855 struct device *dev; 1952 - void __iomem *serdes; 1953 1856 void __iomem *dp_com; 1954 1857 1955 1858 struct clk_bulk_data *clks; 1956 1859 struct reset_control **resets; 1957 1860 struct regulator_bulk_data *vregs; 1958 1861 1959 - const struct qmp_phy_cfg *cfg; 1960 1862 struct qmp_phy **phys; 1961 1863 1962 1864 struct mutex phy_mutex; 1963 1865 int init_count; 1964 - bool phy_initialized; 1965 - enum phy_mode mode; 1966 1866 1967 1867 struct reset_control *ufs_reset; 1968 1868 }; ··· 2307 2203 .is_dual_lane_phy = true, 2308 2204 }; 2309 2205 2206 + static const struct qmp_phy_cfg sc7180_dpphy_cfg = { 2207 + .type = PHY_TYPE_DP, 2208 + .nlanes = 1, 2209 + 2210 + .serdes_tbl = qmp_v3_dp_serdes_tbl, 2211 + .serdes_tbl_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl), 2212 + .tx_tbl = qmp_v3_dp_tx_tbl, 2213 + .tx_tbl_num = ARRAY_SIZE(qmp_v3_dp_tx_tbl), 2214 + 2215 + .serdes_tbl_rbr = qmp_v3_dp_serdes_tbl_rbr, 2216 + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_rbr), 2217 + .serdes_tbl_hbr = qmp_v3_dp_serdes_tbl_hbr, 2218 + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr), 2219 + .serdes_tbl_hbr2 = qmp_v3_dp_serdes_tbl_hbr2, 2220 + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr2), 2221 + .serdes_tbl_hbr3 = qmp_v3_dp_serdes_tbl_hbr3, 2222 + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v3_dp_serdes_tbl_hbr3), 2223 + 2224 + .clk_list = qmp_v3_phy_clk_l, 2225 + .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l), 2226 + .reset_list = sc7180_usb3phy_reset_l, 2227 + .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l), 2228 + .vreg_list = qmp_phy_vreg_l, 2229 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 2230 + .regs = qmp_v3_usb3phy_regs_layout, 2231 + 2232 + .has_phy_dp_com_ctrl = true, 2233 + .is_dual_lane_phy = true, 2234 + }; 2235 + 2236 + static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = { 2237 + .usb_cfg = &sc7180_usb3phy_cfg, 2238 + .dp_cfg = &sc7180_dpphy_cfg, 2239 + }; 2240 + 2310 2241 static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { 2311 2242 .type = PHY_TYPE_USB3, 2312 2243 .nlanes = 1, ··· 2618 2479 qcom_qmp_phy_configure_lane(base, regs, tbl, num, 0xff); 2619 2480 } 2620 2481 2482 + static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy) 2483 + { 2484 + struct qcom_qmp *qmp = qphy->qmp; 2485 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2486 + void __iomem *serdes = qphy->serdes; 2487 + const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts; 2488 + const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl; 2489 + int serdes_tbl_num = cfg->serdes_tbl_num; 2490 + int ret; 2491 + 2492 + qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num); 2493 + 2494 + if (cfg->type == PHY_TYPE_DP) { 2495 + switch (dp_opts->link_rate) { 2496 + case 1620: 2497 + qcom_qmp_phy_configure(serdes, cfg->regs, 2498 + cfg->serdes_tbl_rbr, 2499 + cfg->serdes_tbl_rbr_num); 2500 + break; 2501 + case 2700: 2502 + qcom_qmp_phy_configure(serdes, cfg->regs, 2503 + cfg->serdes_tbl_hbr, 2504 + cfg->serdes_tbl_hbr_num); 2505 + break; 2506 + case 5400: 2507 + qcom_qmp_phy_configure(serdes, cfg->regs, 2508 + cfg->serdes_tbl_hbr2, 2509 + cfg->serdes_tbl_hbr2_num); 2510 + break; 2511 + case 8100: 2512 + qcom_qmp_phy_configure(serdes, cfg->regs, 2513 + cfg->serdes_tbl_hbr3, 2514 + cfg->serdes_tbl_hbr3_num); 2515 + break; 2516 + default: 2517 + /* Other link rates aren't supported */ 2518 + return -EINVAL; 2519 + } 2520 + } 2521 + 2522 + 2523 + if (cfg->has_phy_com_ctrl) { 2524 + void __iomem *status; 2525 + unsigned int mask, val; 2526 + 2527 + qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET); 2528 + qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL], 2529 + SERDES_START | PCS_START); 2530 + 2531 + status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS]; 2532 + mask = cfg->mask_com_pcs_ready; 2533 + 2534 + ret = readl_poll_timeout(status, val, (val & mask), 10, 2535 + PHY_INIT_COMPLETE_TIMEOUT); 2536 + if (ret) { 2537 + dev_err(qmp->dev, 2538 + "phy common block init timed-out\n"); 2539 + return ret; 2540 + } 2541 + } 2542 + 2543 + return 0; 2544 + } 2545 + 2546 + static void qcom_qmp_phy_dp_aux_init(struct qmp_phy *qphy) 2547 + { 2548 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 2549 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 2550 + qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL); 2551 + 2552 + /* Turn on BIAS current for PHY/PLL */ 2553 + writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX | 2554 + QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL, 2555 + qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN); 2556 + 2557 + writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL); 2558 + 2559 + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 2560 + DP_PHY_PD_CTL_LANE_0_1_PWRDN | 2561 + DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN | 2562 + DP_PHY_PD_CTL_DP_CLAMP_EN, 2563 + qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL); 2564 + 2565 + writel(QSERDES_V3_COM_BIAS_EN | 2566 + QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN | 2567 + QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL | 2568 + QSERDES_V3_COM_CLKBUF_RX_DRIVE_L, 2569 + qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN); 2570 + 2571 + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0); 2572 + writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1); 2573 + writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2); 2574 + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3); 2575 + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4); 2576 + writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5); 2577 + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6); 2578 + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7); 2579 + writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8); 2580 + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9); 2581 + qphy->dp_aux_cfg = 0; 2582 + 2583 + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 2584 + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 2585 + PHY_AUX_REQ_ERR_MASK, 2586 + qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK); 2587 + } 2588 + 2589 + static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = { 2590 + { 0x00, 0x0c, 0x14, 0x19 }, 2591 + { 0x00, 0x0b, 0x12, 0xff }, 2592 + { 0x00, 0x0b, 0xff, 0xff }, 2593 + { 0x04, 0xff, 0xff, 0xff } 2594 + }; 2595 + 2596 + static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = { 2597 + { 0x08, 0x0f, 0x16, 0x1f }, 2598 + { 0x11, 0x1e, 0x1f, 0xff }, 2599 + { 0x19, 0x1f, 0xff, 0xff }, 2600 + { 0x1f, 0xff, 0xff, 0xff } 2601 + }; 2602 + 2603 + static void qcom_qmp_phy_configure_dp_tx(struct qmp_phy *qphy) 2604 + { 2605 + const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts; 2606 + unsigned int v_level = 0, p_level = 0; 2607 + u32 bias_en, drvr_en; 2608 + u8 voltage_swing_cfg, pre_emphasis_cfg; 2609 + int i; 2610 + 2611 + for (i = 0; i < dp_opts->lanes; i++) { 2612 + v_level = max(v_level, dp_opts->voltage[i]); 2613 + p_level = max(p_level, dp_opts->pre[i]); 2614 + } 2615 + 2616 + if (dp_opts->lanes == 1) { 2617 + bias_en = 0x3e; 2618 + drvr_en = 0x13; 2619 + } else { 2620 + bias_en = 0x3f; 2621 + drvr_en = 0x10; 2622 + } 2623 + 2624 + voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level]; 2625 + pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level]; 2626 + 2627 + /* TODO: Move check to config check */ 2628 + if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF) 2629 + return; 2630 + 2631 + /* Enable MUX to use Cursor values from these registers */ 2632 + voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN; 2633 + pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN; 2634 + 2635 + writel(voltage_swing_cfg, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL); 2636 + writel(pre_emphasis_cfg, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL); 2637 + writel(voltage_swing_cfg, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL); 2638 + writel(pre_emphasis_cfg, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL); 2639 + 2640 + writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN); 2641 + writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN); 2642 + writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN); 2643 + writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN); 2644 + } 2645 + 2646 + static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts) 2647 + { 2648 + const struct phy_configure_opts_dp *dp_opts = &opts->dp; 2649 + struct qmp_phy *qphy = phy_get_drvdata(phy); 2650 + 2651 + memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts)); 2652 + if (qphy->dp_opts.set_voltages) { 2653 + qcom_qmp_phy_configure_dp_tx(qphy); 2654 + qphy->dp_opts.set_voltages = 0; 2655 + } 2656 + 2657 + return 0; 2658 + } 2659 + 2660 + static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy) 2661 + { 2662 + const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks; 2663 + const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts; 2664 + u32 val, phy_vco_div, status; 2665 + unsigned long pixel_freq; 2666 + 2667 + val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 2668 + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN; 2669 + 2670 + /* 2671 + * TODO: Assume orientation is CC1 for now and two lanes, need to 2672 + * use type-c connector to understand orientation and lanes. 2673 + * 2674 + * Otherwise val changes to be like below if this code understood 2675 + * the orientation of the type-c cable. 2676 + * 2677 + * if (lane_cnt == 4 || orientation == ORIENTATION_CC2) 2678 + * val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN; 2679 + * if (lane_cnt == 4 || orientation == ORIENTATION_CC1) 2680 + * val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN; 2681 + * if (orientation == ORIENTATION_CC2) 2682 + * writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE); 2683 + */ 2684 + val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN; 2685 + writel(val, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL); 2686 + 2687 + writel(0x5c, qphy->pcs + QSERDES_V3_DP_PHY_MODE); 2688 + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL); 2689 + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL); 2690 + 2691 + switch (dp_opts->link_rate) { 2692 + case 1620: 2693 + phy_vco_div = 0x1; 2694 + pixel_freq = 1620000000UL / 2; 2695 + break; 2696 + case 2700: 2697 + phy_vco_div = 0x1; 2698 + pixel_freq = 2700000000UL / 2; 2699 + break; 2700 + case 5400: 2701 + phy_vco_div = 0x2; 2702 + pixel_freq = 5400000000UL / 4; 2703 + break; 2704 + case 8100: 2705 + phy_vco_div = 0x0; 2706 + pixel_freq = 8100000000UL / 6; 2707 + break; 2708 + default: 2709 + /* Other link rates aren't supported */ 2710 + return -EINVAL; 2711 + } 2712 + writel(phy_vco_div, qphy->pcs + QSERDES_V3_DP_PHY_VCO_DIV); 2713 + 2714 + clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000); 2715 + clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq); 2716 + 2717 + writel(0x04, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2); 2718 + writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2719 + writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2720 + writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2721 + writel(0x09, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2722 + 2723 + writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL); 2724 + 2725 + if (readl_poll_timeout(qphy->serdes + QSERDES_V3_COM_C_READY_STATUS, 2726 + status, 2727 + ((status & BIT(0)) > 0), 2728 + 500, 2729 + 10000)) 2730 + return -ETIMEDOUT; 2731 + 2732 + writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2733 + 2734 + if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS, 2735 + status, 2736 + ((status & BIT(1)) > 0), 2737 + 500, 2738 + 10000)) 2739 + return -ETIMEDOUT; 2740 + 2741 + writel(0x18, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2742 + udelay(2000); 2743 + writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG); 2744 + 2745 + return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS, 2746 + status, 2747 + ((status & BIT(1)) > 0), 2748 + 500, 2749 + 10000); 2750 + } 2751 + 2752 + /* 2753 + * We need to calibrate the aux setting here as many times 2754 + * as the caller tries 2755 + */ 2756 + static int qcom_qmp_dp_phy_calibrate(struct phy *phy) 2757 + { 2758 + struct qmp_phy *qphy = phy_get_drvdata(phy); 2759 + const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d }; 2760 + u8 val; 2761 + 2762 + qphy->dp_aux_cfg++; 2763 + qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); 2764 + val = cfg1_settings[qphy->dp_aux_cfg]; 2765 + 2766 + writel(val, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1); 2767 + 2768 + return 0; 2769 + } 2770 + 2621 2771 static int qcom_qmp_phy_com_init(struct qmp_phy *qphy) 2622 2772 { 2623 2773 struct qcom_qmp *qmp = qphy->qmp; 2624 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2625 - void __iomem *serdes = qmp->serdes; 2774 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2775 + void __iomem *serdes = qphy->serdes; 2626 2776 void __iomem *pcs = qphy->pcs; 2627 2777 void __iomem *dp_com = qmp->dp_com; 2628 2778 int ret, i; ··· 2942 2514 ret = reset_control_deassert(qmp->resets[i]); 2943 2515 if (ret) { 2944 2516 dev_err(qmp->dev, "%s reset deassert failed\n", 2945 - qmp->cfg->reset_list[i]); 2517 + qphy->cfg->reset_list[i]); 2946 2518 goto err_rst; 2947 2519 } 2948 2520 } ··· 2961 2533 SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | 2962 2534 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 2963 2535 2536 + /* Default type-c orientation, i.e CC1 */ 2537 + qphy_setbits(dp_com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02); 2538 + 2964 2539 qphy_setbits(dp_com, QPHY_V3_DP_COM_PHY_MODE_CTRL, 2965 2540 USB3_MODE | DP_MODE); 2966 2541 ··· 2971 2540 qphy_clrbits(dp_com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, 2972 2541 SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | 2973 2542 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 2543 + 2544 + qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03); 2545 + qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); 2974 2546 } 2975 2547 2976 2548 if (cfg->has_phy_com_ctrl) { ··· 2989 2555 cfg->pwrdn_ctrl); 2990 2556 } 2991 2557 2992 - /* Serdes configuration */ 2993 - qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl, 2994 - cfg->serdes_tbl_num); 2995 - 2996 - if (cfg->has_phy_com_ctrl) { 2997 - void __iomem *status; 2998 - unsigned int mask, val; 2999 - 3000 - qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET); 3001 - qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL], 3002 - SERDES_START | PCS_START); 3003 - 3004 - status = serdes + cfg->regs[QPHY_COM_PCS_READY_STATUS]; 3005 - mask = cfg->mask_com_pcs_ready; 3006 - 3007 - ret = readl_poll_timeout(status, val, (val & mask), 10, 3008 - PHY_INIT_COMPLETE_TIMEOUT); 3009 - if (ret) { 3010 - dev_err(qmp->dev, 3011 - "phy common block init timed-out\n"); 3012 - goto err_com_init; 3013 - } 3014 - } 3015 - 3016 2558 mutex_unlock(&qmp->phy_mutex); 3017 2559 3018 2560 return 0; 3019 2561 3020 - err_com_init: 3021 - clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); 3022 2562 err_rst: 3023 2563 while (++i < cfg->num_resets) 3024 2564 reset_control_assert(qmp->resets[i]); ··· 3004 2596 return ret; 3005 2597 } 3006 2598 3007 - static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp) 2599 + static int qcom_qmp_phy_com_exit(struct qmp_phy *qphy) 3008 2600 { 3009 - const struct qmp_phy_cfg *cfg = qmp->cfg; 3010 - void __iomem *serdes = qmp->serdes; 2601 + struct qcom_qmp *qmp = qphy->qmp; 2602 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2603 + void __iomem *serdes = qphy->serdes; 3011 2604 int i = cfg->num_resets; 3012 2605 3013 2606 mutex_lock(&qmp->phy_mutex); ··· 3039 2630 return 0; 3040 2631 } 3041 2632 3042 - static int qcom_qmp_phy_enable(struct phy *phy) 2633 + static int qcom_qmp_phy_init(struct phy *phy) 3043 2634 { 3044 2635 struct qmp_phy *qphy = phy_get_drvdata(phy); 3045 2636 struct qcom_qmp *qmp = qphy->qmp; 3046 - const struct qmp_phy_cfg *cfg = qmp->cfg; 3047 - void __iomem *tx = qphy->tx; 3048 - void __iomem *rx = qphy->rx; 3049 - void __iomem *pcs = qphy->pcs; 3050 - void __iomem *pcs_misc = qphy->pcs_misc; 3051 - void __iomem *dp_com = qmp->dp_com; 3052 - void __iomem *status; 3053 - unsigned int mask, val, ready; 2637 + const struct qmp_phy_cfg *cfg = qphy->cfg; 3054 2638 int ret; 3055 - 3056 2639 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); 3057 2640 3058 2641 if (cfg->no_pcs_sw_reset) { ··· 3071 2670 3072 2671 ret = reset_control_assert(qmp->ufs_reset); 3073 2672 if (ret) 3074 - goto err_lane_rst; 2673 + return ret; 3075 2674 } 3076 2675 3077 2676 ret = qcom_qmp_phy_com_init(qphy); 3078 2677 if (ret) 3079 2678 return ret; 2679 + 2680 + if (cfg->type == PHY_TYPE_DP) 2681 + qcom_qmp_phy_dp_aux_init(qphy); 2682 + 2683 + return 0; 2684 + } 2685 + 2686 + static int qcom_qmp_phy_power_on(struct phy *phy) 2687 + { 2688 + struct qmp_phy *qphy = phy_get_drvdata(phy); 2689 + struct qcom_qmp *qmp = qphy->qmp; 2690 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2691 + void __iomem *tx = qphy->tx; 2692 + void __iomem *rx = qphy->rx; 2693 + void __iomem *pcs = qphy->pcs; 2694 + void __iomem *pcs_misc = qphy->pcs_misc; 2695 + void __iomem *status; 2696 + unsigned int mask, val, ready; 2697 + int ret; 2698 + 2699 + qcom_qmp_phy_serdes_init(qphy); 3080 2700 3081 2701 if (cfg->has_lane_rst) { 3082 2702 ret = reset_control_deassert(qphy->lane_rst); ··· 3122 2700 qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs, 3123 2701 cfg->tx_tbl, cfg->tx_tbl_num, 2); 3124 2702 2703 + /* Configure special DP tx tunings */ 2704 + if (cfg->type == PHY_TYPE_DP) 2705 + qcom_qmp_phy_configure_dp_tx(qphy); 2706 + 3125 2707 qcom_qmp_phy_configure_lane(rx, cfg->regs, 3126 2708 cfg->rx_tbl, cfg->rx_tbl_num, 1); 2709 + 3127 2710 if (cfg->is_dual_lane_phy) 3128 2711 qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs, 3129 2712 cfg->rx_tbl, cfg->rx_tbl_num, 2); 3130 2713 3131 - qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); 2714 + /* Configure link rate, swing, etc. */ 2715 + if (cfg->type == PHY_TYPE_DP) 2716 + qcom_qmp_phy_configure_dp_phy(qphy); 2717 + else 2718 + qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); 2719 + 3132 2720 ret = reset_control_deassert(qmp->ufs_reset); 3133 2721 if (ret) 3134 2722 goto err_lane_rst; ··· 3156 2724 if (cfg->has_pwrdn_delay) 3157 2725 usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max); 3158 2726 3159 - /* Pull PHY out of reset state */ 3160 - if (!cfg->no_pcs_sw_reset) 3161 - qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 2727 + if (cfg->type != PHY_TYPE_DP) { 2728 + /* Pull PHY out of reset state */ 2729 + if (!cfg->no_pcs_sw_reset) 2730 + qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 2731 + /* start SerDes and Phy-Coding-Sublayer */ 2732 + qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); 3162 2733 3163 - if (cfg->has_phy_dp_com_ctrl) 3164 - qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); 2734 + if (cfg->type == PHY_TYPE_UFS) { 2735 + status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; 2736 + mask = PCS_READY; 2737 + ready = PCS_READY; 2738 + } else { 2739 + status = pcs + cfg->regs[QPHY_PCS_STATUS]; 2740 + mask = PHYSTATUS; 2741 + ready = 0; 2742 + } 3165 2743 3166 - /* start SerDes and Phy-Coding-Sublayer */ 3167 - qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); 3168 - 3169 - if (cfg->type == PHY_TYPE_UFS) { 3170 - status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; 3171 - mask = PCS_READY; 3172 - ready = PCS_READY; 3173 - } else { 3174 - status = pcs + cfg->regs[QPHY_PCS_STATUS]; 3175 - mask = PHYSTATUS; 3176 - ready = 0; 2744 + ret = readl_poll_timeout(status, val, (val & mask) == ready, 10, 2745 + PHY_INIT_COMPLETE_TIMEOUT); 2746 + if (ret) { 2747 + dev_err(qmp->dev, "phy initialization timed-out\n"); 2748 + goto err_pcs_ready; 2749 + } 3177 2750 } 3178 - 3179 - ret = readl_poll_timeout(status, val, (val & mask) == ready, 10, 3180 - PHY_INIT_COMPLETE_TIMEOUT); 3181 - if (ret) { 3182 - dev_err(qmp->dev, "phy initialization timed-out\n"); 3183 - goto err_pcs_ready; 3184 - } 3185 - qmp->phy_initialized = true; 3186 2751 return 0; 3187 2752 3188 2753 err_pcs_ready: 3189 - reset_control_assert(qmp->ufs_reset); 3190 2754 clk_disable_unprepare(qphy->pipe_clk); 3191 2755 err_clk_enable: 3192 2756 if (cfg->has_lane_rst) 3193 2757 reset_control_assert(qphy->lane_rst); 3194 2758 err_lane_rst: 3195 - qcom_qmp_phy_com_exit(qmp); 2759 + return ret; 2760 + } 2761 + 2762 + static int qcom_qmp_phy_power_off(struct phy *phy) 2763 + { 2764 + struct qmp_phy *qphy = phy_get_drvdata(phy); 2765 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2766 + 2767 + clk_disable_unprepare(qphy->pipe_clk); 2768 + 2769 + if (cfg->type == PHY_TYPE_DP) { 2770 + /* Assert DP PHY power down */ 2771 + writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL); 2772 + } else { 2773 + /* PHY reset */ 2774 + if (!cfg->no_pcs_sw_reset) 2775 + qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 2776 + 2777 + /* stop SerDes and Phy-Coding-Sublayer */ 2778 + qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); 2779 + 2780 + /* Put PHY into POWER DOWN state: active low */ 2781 + if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) { 2782 + qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 2783 + cfg->pwrdn_ctrl); 2784 + } else { 2785 + qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL, 2786 + cfg->pwrdn_ctrl); 2787 + } 2788 + } 2789 + 2790 + return 0; 2791 + } 2792 + 2793 + static int qcom_qmp_phy_exit(struct phy *phy) 2794 + { 2795 + struct qmp_phy *qphy = phy_get_drvdata(phy); 2796 + const struct qmp_phy_cfg *cfg = qphy->cfg; 2797 + 2798 + if (cfg->has_lane_rst) 2799 + reset_control_assert(qphy->lane_rst); 2800 + 2801 + qcom_qmp_phy_com_exit(qphy); 2802 + 2803 + return 0; 2804 + } 2805 + 2806 + static int qcom_qmp_phy_enable(struct phy *phy) 2807 + { 2808 + int ret; 2809 + 2810 + ret = qcom_qmp_phy_init(phy); 2811 + if (ret) 2812 + return ret; 2813 + 2814 + ret = qcom_qmp_phy_power_on(phy); 2815 + if (ret) 2816 + qcom_qmp_phy_exit(phy); 3196 2817 3197 2818 return ret; 3198 2819 } 3199 2820 3200 2821 static int qcom_qmp_phy_disable(struct phy *phy) 3201 2822 { 3202 - struct qmp_phy *qphy = phy_get_drvdata(phy); 3203 - struct qcom_qmp *qmp = qphy->qmp; 3204 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2823 + int ret; 3205 2824 3206 - clk_disable_unprepare(qphy->pipe_clk); 3207 - 3208 - /* PHY reset */ 3209 - if (!cfg->no_pcs_sw_reset) 3210 - qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); 3211 - 3212 - /* stop SerDes and Phy-Coding-Sublayer */ 3213 - qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); 3214 - 3215 - /* Put PHY into POWER DOWN state: active low */ 3216 - if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) { 3217 - qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 3218 - cfg->pwrdn_ctrl); 3219 - } else { 3220 - qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL, 3221 - cfg->pwrdn_ctrl); 3222 - } 3223 - 3224 - if (cfg->has_lane_rst) 3225 - reset_control_assert(qphy->lane_rst); 3226 - 3227 - qcom_qmp_phy_com_exit(qmp); 3228 - 3229 - qmp->phy_initialized = false; 3230 - 3231 - return 0; 2825 + ret = qcom_qmp_phy_power_off(phy); 2826 + if (ret) 2827 + return ret; 2828 + return qcom_qmp_phy_exit(phy); 3232 2829 } 3233 2830 3234 2831 static int qcom_qmp_phy_set_mode(struct phy *phy, 3235 2832 enum phy_mode mode, int submode) 3236 2833 { 3237 2834 struct qmp_phy *qphy = phy_get_drvdata(phy); 3238 - struct qcom_qmp *qmp = qphy->qmp; 3239 2835 3240 - qmp->mode = mode; 2836 + qphy->mode = mode; 3241 2837 3242 2838 return 0; 3243 2839 } 3244 2840 3245 2841 static void qcom_qmp_phy_enable_autonomous_mode(struct qmp_phy *qphy) 3246 2842 { 3247 - struct qcom_qmp *qmp = qphy->qmp; 3248 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2843 + const struct qmp_phy_cfg *cfg = qphy->cfg; 3249 2844 void __iomem *pcs = qphy->pcs; 3250 2845 void __iomem *pcs_misc = qphy->pcs_misc; 3251 2846 u32 intr_mask; 3252 2847 3253 - if (qmp->mode == PHY_MODE_USB_HOST_SS || 3254 - qmp->mode == PHY_MODE_USB_DEVICE_SS) 2848 + if (qphy->mode == PHY_MODE_USB_HOST_SS || 2849 + qphy->mode == PHY_MODE_USB_DEVICE_SS) 3255 2850 intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; 3256 2851 else 3257 2852 intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; ··· 3301 2842 3302 2843 static void qcom_qmp_phy_disable_autonomous_mode(struct qmp_phy *qphy) 3303 2844 { 3304 - struct qcom_qmp *qmp = qphy->qmp; 3305 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2845 + const struct qmp_phy_cfg *cfg = qphy->cfg; 3306 2846 void __iomem *pcs = qphy->pcs; 3307 2847 void __iomem *pcs_misc = qphy->pcs_misc; 3308 2848 ··· 3321 2863 { 3322 2864 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3323 2865 struct qmp_phy *qphy = qmp->phys[0]; 3324 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2866 + const struct qmp_phy_cfg *cfg = qphy->cfg; 3325 2867 3326 - dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); 2868 + dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode); 3327 2869 3328 - /* Supported only for USB3 PHY */ 2870 + /* Supported only for USB3 PHY and luckily USB3 is the first phy */ 3329 2871 if (cfg->type != PHY_TYPE_USB3) 3330 2872 return 0; 3331 2873 3332 - if (!qmp->phy_initialized) { 2874 + if (!qmp->init_count) { 3333 2875 dev_vdbg(dev, "PHY not initialized, bailing out\n"); 3334 2876 return 0; 3335 2877 } ··· 3346 2888 { 3347 2889 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3348 2890 struct qmp_phy *qphy = qmp->phys[0]; 3349 - const struct qmp_phy_cfg *cfg = qmp->cfg; 2891 + const struct qmp_phy_cfg *cfg = qphy->cfg; 3350 2892 int ret = 0; 3351 2893 3352 - dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); 2894 + dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode); 3353 2895 3354 - /* Supported only for USB3 PHY */ 2896 + /* Supported only for USB3 PHY and luckily USB3 is the first phy */ 3355 2897 if (cfg->type != PHY_TYPE_USB3) 3356 2898 return 0; 3357 2899 3358 - if (!qmp->phy_initialized) { 2900 + if (!qmp->init_count) { 3359 2901 dev_vdbg(dev, "PHY not initialized, bailing out\n"); 3360 2902 return 0; 3361 2903 } ··· 3378 2920 return 0; 3379 2921 } 3380 2922 3381 - static int qcom_qmp_phy_vreg_init(struct device *dev) 2923 + static int qcom_qmp_phy_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg) 3382 2924 { 3383 2925 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3384 - int num = qmp->cfg->num_vregs; 2926 + int num = cfg->num_vregs; 3385 2927 int i; 3386 2928 3387 2929 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); ··· 3389 2931 return -ENOMEM; 3390 2932 3391 2933 for (i = 0; i < num; i++) 3392 - qmp->vregs[i].supply = qmp->cfg->vreg_list[i]; 2934 + qmp->vregs[i].supply = cfg->vreg_list[i]; 3393 2935 3394 2936 return devm_regulator_bulk_get(dev, num, qmp->vregs); 3395 2937 } 3396 2938 3397 - static int qcom_qmp_phy_reset_init(struct device *dev) 2939 + static int qcom_qmp_phy_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg) 3398 2940 { 3399 2941 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3400 2942 int i; 3401 2943 3402 - qmp->resets = devm_kcalloc(dev, qmp->cfg->num_resets, 2944 + qmp->resets = devm_kcalloc(dev, cfg->num_resets, 3403 2945 sizeof(*qmp->resets), GFP_KERNEL); 3404 2946 if (!qmp->resets) 3405 2947 return -ENOMEM; 3406 2948 3407 - for (i = 0; i < qmp->cfg->num_resets; i++) { 2949 + for (i = 0; i < cfg->num_resets; i++) { 3408 2950 struct reset_control *rst; 3409 - const char *name = qmp->cfg->reset_list[i]; 2951 + const char *name = cfg->reset_list[i]; 3410 2952 3411 2953 rst = devm_reset_control_get(dev, name); 3412 2954 if (IS_ERR(rst)) { ··· 3419 2961 return 0; 3420 2962 } 3421 2963 3422 - static int qcom_qmp_phy_clk_init(struct device *dev) 2964 + static int qcom_qmp_phy_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg) 3423 2965 { 3424 2966 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3425 - int num = qmp->cfg->num_clks; 2967 + int num = cfg->num_clks; 3426 2968 int i; 3427 2969 3428 2970 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); ··· 3430 2972 return -ENOMEM; 3431 2973 3432 2974 for (i = 0; i < num; i++) 3433 - qmp->clks[i].id = qmp->cfg->clk_list[i]; 2975 + qmp->clks[i].id = cfg->clk_list[i]; 3434 2976 3435 2977 return devm_clk_bulk_get(dev, num, qmp->clks); 3436 2978 } 3437 2979 3438 - static void phy_pipe_clk_release_provider(void *res) 2980 + static void phy_clk_release_provider(void *res) 3439 2981 { 3440 2982 of_clk_del_provider(res); 3441 2983 } ··· 3463 3005 struct clk_fixed_rate *fixed; 3464 3006 struct clk_init_data init = { }; 3465 3007 int ret; 3466 - 3467 - if ((qmp->cfg->type != PHY_TYPE_USB3) && 3468 - (qmp->cfg->type != PHY_TYPE_PCIE)) { 3469 - /* not all phys register pipe clocks, so return success */ 3470 - return 0; 3471 - } 3472 3008 3473 3009 ret = of_property_read_string(np, "clock-output-names", &init.name); 3474 3010 if (ret) { ··· 3492 3040 * Roll a devm action because the clock provider is the child node, but 3493 3041 * the child node is not actually a device. 3494 3042 */ 3495 - ret = devm_add_action(qmp->dev, phy_pipe_clk_release_provider, np); 3043 + ret = devm_add_action(qmp->dev, phy_clk_release_provider, np); 3496 3044 if (ret) 3497 - phy_pipe_clk_release_provider(np); 3045 + phy_clk_release_provider(np); 3046 + 3047 + return ret; 3048 + } 3049 + 3050 + /* 3051 + * Display Port PLL driver block diagram for branch clocks 3052 + * 3053 + * +------------------------------+ 3054 + * | DP_VCO_CLK | 3055 + * | | 3056 + * | +-------------------+ | 3057 + * | | (DP PLL/VCO) | | 3058 + * | +---------+---------+ | 3059 + * | v | 3060 + * | +----------+-----------+ | 3061 + * | | hsclk_divsel_clk_src | | 3062 + * | +----------+-----------+ | 3063 + * +------------------------------+ 3064 + * | 3065 + * +---------<---------v------------>----------+ 3066 + * | | 3067 + * +--------v----------------+ | 3068 + * | dp_phy_pll_link_clk | | 3069 + * | link_clk | | 3070 + * +--------+----------------+ | 3071 + * | | 3072 + * | | 3073 + * v v 3074 + * Input to DISPCC block | 3075 + * for link clk, crypto clk | 3076 + * and interface clock | 3077 + * | 3078 + * | 3079 + * +--------<------------+-----------------+---<---+ 3080 + * | | | 3081 + * +----v---------+ +--------v-----+ +--------v------+ 3082 + * | vco_divided | | vco_divided | | vco_divided | 3083 + * | _clk_src | | _clk_src | | _clk_src | 3084 + * | | | | | | 3085 + * |divsel_six | | divsel_two | | divsel_four | 3086 + * +-------+------+ +-----+--------+ +--------+------+ 3087 + * | | | 3088 + * v---->----------v-------------<------v 3089 + * | 3090 + * +----------+-----------------+ 3091 + * | dp_phy_pll_vco_div_clk | 3092 + * +---------+------------------+ 3093 + * | 3094 + * v 3095 + * Input to DISPCC block 3096 + * for DP pixel clock 3097 + * 3098 + */ 3099 + static int qcom_qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, 3100 + struct clk_rate_request *req) 3101 + { 3102 + switch (req->rate) { 3103 + case 1620000000UL / 2: 3104 + case 2700000000UL / 2: 3105 + /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */ 3106 + return 0; 3107 + default: 3108 + return -EINVAL; 3109 + } 3110 + } 3111 + 3112 + static unsigned long 3113 + qcom_qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 3114 + { 3115 + const struct qmp_phy_dp_clks *dp_clks; 3116 + const struct qmp_phy *qphy; 3117 + const struct phy_configure_opts_dp *dp_opts; 3118 + 3119 + dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_pixel_hw); 3120 + qphy = dp_clks->qphy; 3121 + dp_opts = &qphy->dp_opts; 3122 + 3123 + switch (dp_opts->link_rate) { 3124 + case 1620: 3125 + return 1620000000UL / 2; 3126 + case 2700: 3127 + return 2700000000UL / 2; 3128 + case 5400: 3129 + return 5400000000UL / 4; 3130 + case 8100: 3131 + return 8100000000UL / 6; 3132 + default: 3133 + return 0; 3134 + } 3135 + } 3136 + 3137 + static const struct clk_ops qcom_qmp_dp_pixel_clk_ops = { 3138 + .determine_rate = qcom_qmp_dp_pixel_clk_determine_rate, 3139 + .recalc_rate = qcom_qmp_dp_pixel_clk_recalc_rate, 3140 + }; 3141 + 3142 + static int qcom_qmp_dp_link_clk_determine_rate(struct clk_hw *hw, 3143 + struct clk_rate_request *req) 3144 + { 3145 + switch (req->rate) { 3146 + case 162000000: 3147 + case 270000000: 3148 + case 540000000: 3149 + case 810000000: 3150 + return 0; 3151 + default: 3152 + return -EINVAL; 3153 + } 3154 + } 3155 + 3156 + static unsigned long 3157 + qcom_qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 3158 + { 3159 + const struct qmp_phy_dp_clks *dp_clks; 3160 + const struct qmp_phy *qphy; 3161 + const struct phy_configure_opts_dp *dp_opts; 3162 + 3163 + dp_clks = container_of(hw, struct qmp_phy_dp_clks, dp_link_hw); 3164 + qphy = dp_clks->qphy; 3165 + dp_opts = &qphy->dp_opts; 3166 + 3167 + switch (dp_opts->link_rate) { 3168 + case 1620: 3169 + case 2700: 3170 + case 5400: 3171 + case 8100: 3172 + return dp_opts->link_rate * 100000; 3173 + default: 3174 + return 0; 3175 + } 3176 + } 3177 + 3178 + static const struct clk_ops qcom_qmp_dp_link_clk_ops = { 3179 + .determine_rate = qcom_qmp_dp_link_clk_determine_rate, 3180 + .recalc_rate = qcom_qmp_dp_link_clk_recalc_rate, 3181 + }; 3182 + 3183 + static struct clk_hw * 3184 + qcom_qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data) 3185 + { 3186 + struct qmp_phy_dp_clks *dp_clks = data; 3187 + unsigned int idx = clkspec->args[0]; 3188 + 3189 + if (idx >= 2) { 3190 + pr_err("%s: invalid index %u\n", __func__, idx); 3191 + return ERR_PTR(-EINVAL); 3192 + } 3193 + 3194 + if (idx == 0) 3195 + return &dp_clks->dp_link_hw; 3196 + 3197 + return &dp_clks->dp_pixel_hw; 3198 + } 3199 + 3200 + static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy, 3201 + struct device_node *np) 3202 + { 3203 + struct clk_init_data init = { }; 3204 + struct qmp_phy_dp_clks *dp_clks; 3205 + int ret; 3206 + 3207 + dp_clks = devm_kzalloc(qmp->dev, sizeof(*dp_clks), GFP_KERNEL); 3208 + if (!dp_clks) 3209 + return -ENOMEM; 3210 + 3211 + dp_clks->qphy = qphy; 3212 + qphy->dp_clks = dp_clks; 3213 + 3214 + init.ops = &qcom_qmp_dp_link_clk_ops; 3215 + init.name = "qmp_dp_phy_pll_link_clk"; 3216 + dp_clks->dp_link_hw.init = &init; 3217 + ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_link_hw); 3218 + if (ret) 3219 + return ret; 3220 + 3221 + init.ops = &qcom_qmp_dp_pixel_clk_ops; 3222 + init.name = "qmp_dp_phy_pll_vco_div_clk"; 3223 + dp_clks->dp_pixel_hw.init = &init; 3224 + ret = devm_clk_hw_register(qmp->dev, &dp_clks->dp_pixel_hw); 3225 + if (ret) 3226 + return ret; 3227 + 3228 + ret = of_clk_add_hw_provider(np, qcom_qmp_dp_clks_hw_get, dp_clks); 3229 + if (ret) 3230 + return ret; 3231 + 3232 + /* 3233 + * Roll a devm action because the clock provider is the child node, but 3234 + * the child node is not actually a device. 3235 + */ 3236 + ret = devm_add_action(qmp->dev, phy_clk_release_provider, np); 3237 + if (ret) 3238 + phy_clk_release_provider(np); 3498 3239 3499 3240 return ret; 3500 3241 } ··· 3695 3050 static const struct phy_ops qcom_qmp_phy_gen_ops = { 3696 3051 .init = qcom_qmp_phy_enable, 3697 3052 .exit = qcom_qmp_phy_disable, 3053 + .set_mode = qcom_qmp_phy_set_mode, 3054 + .owner = THIS_MODULE, 3055 + }; 3056 + 3057 + static const struct phy_ops qcom_qmp_phy_dp_ops = { 3058 + .init = qcom_qmp_phy_init, 3059 + .configure = qcom_qmp_dp_phy_configure, 3060 + .power_on = qcom_qmp_phy_power_on, 3061 + .calibrate = qcom_qmp_dp_phy_calibrate, 3062 + .power_off = qcom_qmp_phy_power_off, 3063 + .exit = qcom_qmp_phy_exit, 3698 3064 .set_mode = qcom_qmp_phy_set_mode, 3699 3065 .owner = THIS_MODULE, 3700 3066 }; ··· 3718 3062 }; 3719 3063 3720 3064 static 3721 - int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) 3065 + int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id, 3066 + void __iomem *serdes, const struct qmp_phy_cfg *cfg) 3722 3067 { 3723 3068 struct qcom_qmp *qmp = dev_get_drvdata(dev); 3724 3069 struct phy *generic_phy; 3725 3070 struct qmp_phy *qphy; 3726 - const struct phy_ops *ops = &qcom_qmp_phy_gen_ops; 3071 + const struct phy_ops *ops; 3727 3072 char prop_name[MAX_PROP_NAME]; 3728 3073 int ret; 3729 3074 ··· 3732 3075 if (!qphy) 3733 3076 return -ENOMEM; 3734 3077 3078 + qphy->cfg = cfg; 3079 + qphy->serdes = serdes; 3735 3080 /* 3736 3081 * Get memory resources for each phy lane: 3737 3082 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. ··· 3758 3099 * back to old legacy behavior of assuming they can be reached at an 3759 3100 * offset from the first lane. 3760 3101 */ 3761 - if (qmp->cfg->is_dual_lane_phy) { 3102 + if (cfg->is_dual_lane_phy) { 3762 3103 qphy->tx2 = of_iomap(np, 3); 3763 3104 qphy->rx2 = of_iomap(np, 4); 3764 3105 if (!qphy->tx2 || !qphy->rx2) { ··· 3791 3132 snprintf(prop_name, sizeof(prop_name), "pipe%d", id); 3792 3133 qphy->pipe_clk = of_clk_get_by_name(np, prop_name); 3793 3134 if (IS_ERR(qphy->pipe_clk)) { 3794 - if (qmp->cfg->type == PHY_TYPE_PCIE || 3795 - qmp->cfg->type == PHY_TYPE_USB3) { 3135 + if (cfg->type == PHY_TYPE_PCIE || 3136 + cfg->type == PHY_TYPE_USB3) { 3796 3137 ret = PTR_ERR(qphy->pipe_clk); 3797 3138 if (ret != -EPROBE_DEFER) 3798 3139 dev_err(dev, ··· 3804 3145 } 3805 3146 3806 3147 /* Get lane reset, if any */ 3807 - if (qmp->cfg->has_lane_rst) { 3148 + if (cfg->has_lane_rst) { 3808 3149 snprintf(prop_name, sizeof(prop_name), "lane%d", id); 3809 3150 qphy->lane_rst = of_reset_control_get(np, prop_name); 3810 3151 if (IS_ERR(qphy->lane_rst)) { ··· 3813 3154 } 3814 3155 } 3815 3156 3816 - if (qmp->cfg->type == PHY_TYPE_UFS || qmp->cfg->type == PHY_TYPE_PCIE) 3157 + if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE) 3817 3158 ops = &qcom_qmp_pcie_ufs_ops; 3159 + else if (cfg->type == PHY_TYPE_DP) 3160 + ops = &qcom_qmp_phy_dp_ops; 3161 + else 3162 + ops = &qcom_qmp_phy_gen_ops; 3818 3163 3819 3164 generic_phy = devm_phy_create(dev, np, ops); 3820 3165 if (IS_ERR(generic_phy)) { ··· 3862 3199 .compatible = "qcom,sc7180-qmp-usb3-phy", 3863 3200 .data = &sc7180_usb3phy_cfg, 3864 3201 }, { 3202 + .compatible = "qcom,sc7180-qmp-usb3-dp-phy", 3203 + /* It's a combo phy */ 3204 + }, { 3865 3205 .compatible = "qcom,sdm845-qhp-pcie-phy", 3866 3206 .data = &sdm845_qhp_pciephy_cfg, 3867 3207 }, { ··· 3905 3239 }; 3906 3240 MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table); 3907 3241 3242 + static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = { 3243 + { 3244 + .compatible = "qcom,sc7180-qmp-usb3-dp-phy", 3245 + .data = &sc7180_usb3dpphy_cfg, 3246 + }, 3247 + { } 3248 + }; 3249 + 3908 3250 static const struct dev_pm_ops qcom_qmp_phy_pm_ops = { 3909 3251 SET_RUNTIME_PM_OPS(qcom_qmp_phy_runtime_suspend, 3910 3252 qcom_qmp_phy_runtime_resume, NULL) ··· 3922 3248 { 3923 3249 struct qcom_qmp *qmp; 3924 3250 struct device *dev = &pdev->dev; 3925 - struct resource *res; 3926 3251 struct device_node *child; 3927 3252 struct phy_provider *phy_provider; 3928 - void __iomem *base; 3929 - int num, id; 3253 + void __iomem *serdes; 3254 + void __iomem *usb_serdes; 3255 + void __iomem *dp_serdes; 3256 + const struct qmp_phy_combo_cfg *combo_cfg = NULL; 3257 + const struct qmp_phy_cfg *cfg = NULL; 3258 + const struct qmp_phy_cfg *usb_cfg = NULL; 3259 + const struct qmp_phy_cfg *dp_cfg = NULL; 3260 + int num, id, expected_phys; 3930 3261 int ret; 3931 3262 3932 3263 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL); ··· 3942 3263 dev_set_drvdata(dev, qmp); 3943 3264 3944 3265 /* Get the specific init parameters of QMP phy */ 3945 - qmp->cfg = of_device_get_match_data(dev); 3946 - if (!qmp->cfg) 3947 - return -EINVAL; 3266 + cfg = of_device_get_match_data(dev); 3267 + if (!cfg) { 3268 + const struct of_device_id *match; 3948 3269 3949 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 3950 - base = devm_ioremap_resource(dev, res); 3951 - if (IS_ERR(base)) 3952 - return PTR_ERR(base); 3270 + match = of_match_device(qcom_qmp_combo_phy_of_match_table, dev); 3271 + if (!match) 3272 + return -EINVAL; 3273 + 3274 + combo_cfg = match->data; 3275 + if (!combo_cfg) 3276 + return -EINVAL; 3277 + 3278 + usb_cfg = combo_cfg->usb_cfg; 3279 + cfg = usb_cfg; /* Setup clks and regulators */ 3280 + } 3953 3281 3954 3282 /* per PHY serdes; usually located at base address */ 3955 - qmp->serdes = base; 3283 + usb_serdes = serdes = devm_platform_ioremap_resource(pdev, 0); 3284 + if (IS_ERR(serdes)) 3285 + return PTR_ERR(serdes); 3956 3286 3957 3287 /* per PHY dp_com; if PHY has dp_com control block */ 3958 - if (qmp->cfg->has_phy_dp_com_ctrl) { 3959 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 3960 - "dp_com"); 3961 - base = devm_ioremap_resource(dev, res); 3962 - if (IS_ERR(base)) 3963 - return PTR_ERR(base); 3288 + if (combo_cfg || cfg->has_phy_dp_com_ctrl) { 3289 + qmp->dp_com = devm_platform_ioremap_resource(pdev, 1); 3290 + if (IS_ERR(qmp->dp_com)) 3291 + return PTR_ERR(qmp->dp_com); 3292 + } 3964 3293 3965 - qmp->dp_com = base; 3294 + if (combo_cfg) { 3295 + /* Only two serdes for combo PHY */ 3296 + dp_serdes = devm_platform_ioremap_resource(pdev, 2); 3297 + if (IS_ERR(dp_serdes)) 3298 + return PTR_ERR(dp_serdes); 3299 + 3300 + dp_cfg = combo_cfg->dp_cfg; 3301 + expected_phys = 2; 3302 + } else { 3303 + expected_phys = cfg->nlanes; 3966 3304 } 3967 3305 3968 3306 mutex_init(&qmp->phy_mutex); 3969 3307 3970 - ret = qcom_qmp_phy_clk_init(dev); 3308 + ret = qcom_qmp_phy_clk_init(dev, cfg); 3971 3309 if (ret) 3972 3310 return ret; 3973 3311 3974 - ret = qcom_qmp_phy_reset_init(dev); 3312 + ret = qcom_qmp_phy_reset_init(dev, cfg); 3975 3313 if (ret) 3976 3314 return ret; 3977 3315 3978 - ret = qcom_qmp_phy_vreg_init(dev); 3316 + ret = qcom_qmp_phy_vreg_init(dev, cfg); 3979 3317 if (ret) { 3980 3318 if (ret != -EPROBE_DEFER) 3981 3319 dev_err(dev, "failed to get regulator supplies: %d\n", ··· 4002 3306 4003 3307 num = of_get_available_child_count(dev->of_node); 4004 3308 /* do we have a rogue child node ? */ 4005 - if (num > qmp->cfg->nlanes) 3309 + if (num > expected_phys) 4006 3310 return -EINVAL; 4007 3311 4008 3312 qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL); 4009 3313 if (!qmp->phys) 4010 3314 return -ENOMEM; 4011 3315 4012 - id = 0; 4013 3316 pm_runtime_set_active(dev); 4014 3317 pm_runtime_enable(dev); 4015 3318 /* ··· 4017 3322 */ 4018 3323 pm_runtime_forbid(dev); 4019 3324 3325 + id = 0; 4020 3326 for_each_available_child_of_node(dev->of_node, child) { 3327 + if (of_node_name_eq(child, "dp-phy")) { 3328 + cfg = dp_cfg; 3329 + serdes = dp_serdes; 3330 + } else if (of_node_name_eq(child, "usb3-phy")) { 3331 + cfg = usb_cfg; 3332 + serdes = usb_serdes; 3333 + } 3334 + 4021 3335 /* Create per-lane phy */ 4022 - ret = qcom_qmp_phy_create(dev, child, id); 3336 + ret = qcom_qmp_phy_create(dev, child, id, serdes, cfg); 4023 3337 if (ret) { 4024 3338 dev_err(dev, "failed to create lane%d phy, %d\n", 4025 3339 id, ret); ··· 4039 3335 * Register the pipe clock provided by phy. 4040 3336 * See function description to see details of this pipe clock. 4041 3337 */ 4042 - ret = phy_pipe_clk_register(qmp, child); 4043 - if (ret) { 4044 - dev_err(qmp->dev, 4045 - "failed to register pipe clock source\n"); 4046 - goto err_node_put; 3338 + if (cfg->type == PHY_TYPE_USB3 || cfg->type == PHY_TYPE_PCIE) { 3339 + ret = phy_pipe_clk_register(qmp, child); 3340 + if (ret) { 3341 + dev_err(qmp->dev, 3342 + "failed to register pipe clock source\n"); 3343 + goto err_node_put; 3344 + } 3345 + } else if (cfg->type == PHY_TYPE_DP) { 3346 + ret = phy_dp_clks_register(qmp, qmp->phys[id], child); 3347 + if (ret) { 3348 + dev_err(qmp->dev, 3349 + "failed to register DP clock source\n"); 3350 + goto err_node_put; 3351 + } 4047 3352 } 4048 3353 id++; 4049 3354 }
+80
drivers/phy/qualcomm/phy-qcom-qmp.h
··· 137 137 #define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c 138 138 139 139 /* Only for QMP V3 PHY - QSERDES COM registers */ 140 + #define QSERDES_V3_COM_ATB_SEL1 0x000 141 + #define QSERDES_V3_COM_ATB_SEL2 0x004 142 + #define QSERDES_V3_COM_FREQ_UPDATE 0x008 140 143 #define QSERDES_V3_COM_BG_TIMER 0x00c 141 144 #define QSERDES_V3_COM_SSC_EN_CENTER 0x010 142 145 #define QSERDES_V3_COM_SSC_ADJ_PER1 0x014 ··· 149 146 #define QSERDES_V3_COM_SSC_STEP_SIZE1 0x024 150 147 #define QSERDES_V3_COM_SSC_STEP_SIZE2 0x028 151 148 #define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN 0x034 149 + # define QSERDES_V3_COM_BIAS_EN 0x0001 150 + # define QSERDES_V3_COM_BIAS_EN_MUX 0x0002 151 + # define QSERDES_V3_COM_CLKBUF_R_EN 0x0004 152 + # define QSERDES_V3_COM_CLKBUF_L_EN 0x0008 153 + # define QSERDES_V3_COM_EN_SYSCLK_TX_SEL 0x0010 154 + # define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L 0x0020 155 + # define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R 0x0040 152 156 #define QSERDES_V3_COM_CLK_ENABLE1 0x038 153 157 #define QSERDES_V3_COM_SYS_CLK_CTRL 0x03c 154 158 #define QSERDES_V3_COM_SYSCLK_BUF_ENABLE 0x040 ··· 217 207 #define QSERDES_V3_COM_CMN_MODE 0x184 218 208 219 209 /* Only for QMP V3 PHY - TX registers */ 210 + #define QSERDES_V3_TX_BIST_MODE_LANENO 0x000 211 + #define QSERDES_V3_TX_CLKBUF_ENABLE 0x008 212 + #define QSERDES_V3_TX_TX_EMP_POST1_LVL 0x00c 213 + # define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK 0x001f 214 + # define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN 0x0020 215 + 216 + #define QSERDES_V3_TX_TX_DRV_LVL 0x01c 217 + # define DP_PHY_TXn_TX_DRV_LVL_MASK 0x001f 218 + # define DP_PHY_TXn_TX_DRV_LVL_MUX_EN 0x0020 219 + 220 + #define QSERDES_V3_TX_RESET_TSYNC_EN 0x024 221 + #define QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN 0x028 222 + 223 + #define QSERDES_V3_TX_TX_BAND 0x02c 224 + #define QSERDES_V3_TX_SLEW_CNTL 0x030 225 + #define QSERDES_V3_TX_INTERFACE_SELECT 0x034 226 + #define QSERDES_V3_TX_RES_CODE_LANE_TX 0x03c 227 + #define QSERDES_V3_TX_RES_CODE_LANE_RX 0x040 220 228 #define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX 0x044 221 229 #define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX 0x048 222 230 #define QSERDES_V3_TX_DEBUG_BUS_SEL 0x058 231 + #define QSERDES_V3_TX_TRANSCEIVER_BIAS_EN 0x05c 223 232 #define QSERDES_V3_TX_HIGHZ_DRVR_EN 0x060 233 + #define QSERDES_V3_TX_TX_POL_INV 0x064 234 + #define QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN 0x068 224 235 #define QSERDES_V3_TX_LANE_MODE_1 0x08c 225 236 #define QSERDES_V3_TX_RCV_DETECT_LVL_2 0x0a4 237 + #define QSERDES_V3_TX_TRAN_DRVR_EMP_EN 0x0c0 238 + #define QSERDES_V3_TX_TX_INTERFACE_MODE 0x0c4 239 + #define QSERDES_V3_TX_VMODE_CTRL1 0x0f0 226 240 227 241 /* Only for QMP V3 PHY - RX registers */ 228 242 #define QSERDES_V3_RX_UCDR_FO_GAIN 0x008 ··· 348 314 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG2 0x54 349 315 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4 0x5c 350 316 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5 0x60 317 + 318 + /* Only for QMP V3 PHY - DP PHY registers */ 319 + #define QSERDES_V3_DP_PHY_REVISION_ID0 0x000 320 + #define QSERDES_V3_DP_PHY_REVISION_ID1 0x004 321 + #define QSERDES_V3_DP_PHY_REVISION_ID2 0x008 322 + #define QSERDES_V3_DP_PHY_REVISION_ID3 0x00c 323 + #define QSERDES_V3_DP_PHY_CFG 0x010 324 + #define QSERDES_V3_DP_PHY_PD_CTL 0x018 325 + # define DP_PHY_PD_CTL_PWRDN 0x001 326 + # define DP_PHY_PD_CTL_PSR_PWRDN 0x002 327 + # define DP_PHY_PD_CTL_AUX_PWRDN 0x004 328 + # define DP_PHY_PD_CTL_LANE_0_1_PWRDN 0x008 329 + # define DP_PHY_PD_CTL_LANE_2_3_PWRDN 0x010 330 + # define DP_PHY_PD_CTL_PLL_PWRDN 0x020 331 + # define DP_PHY_PD_CTL_DP_CLAMP_EN 0x040 332 + #define QSERDES_V3_DP_PHY_MODE 0x01c 333 + #define QSERDES_V3_DP_PHY_AUX_CFG0 0x020 334 + #define QSERDES_V3_DP_PHY_AUX_CFG1 0x024 335 + #define QSERDES_V3_DP_PHY_AUX_CFG2 0x028 336 + #define QSERDES_V3_DP_PHY_AUX_CFG3 0x02c 337 + #define QSERDES_V3_DP_PHY_AUX_CFG4 0x030 338 + #define QSERDES_V3_DP_PHY_AUX_CFG5 0x034 339 + #define QSERDES_V3_DP_PHY_AUX_CFG6 0x038 340 + #define QSERDES_V3_DP_PHY_AUX_CFG7 0x03c 341 + #define QSERDES_V3_DP_PHY_AUX_CFG8 0x040 342 + #define QSERDES_V3_DP_PHY_AUX_CFG9 0x044 343 + 344 + #define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK 0x048 345 + # define PHY_AUX_STOP_ERR_MASK 0x01 346 + # define PHY_AUX_DEC_ERR_MASK 0x02 347 + # define PHY_AUX_SYNC_ERR_MASK 0x04 348 + # define PHY_AUX_ALIGN_ERR_MASK 0x08 349 + # define PHY_AUX_REQ_ERR_MASK 0x10 350 + 351 + #define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c 352 + #define QSERDES_V3_DP_PHY_AUX_BIST_CFG 0x050 353 + 354 + #define QSERDES_V3_DP_PHY_VCO_DIV 0x064 355 + #define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL 0x06c 356 + #define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL 0x088 357 + 358 + #define QSERDES_V3_DP_PHY_SPARE0 0x0ac 359 + #define DP_PHY_SPARE0_MASK 0x0f 360 + #define DP_PHY_SPARE0_ORIENTATION_INFO_SHIFT 0x04(0x0004) 361 + 362 + #define QSERDES_V3_DP_PHY_STATUS 0x0c0 351 363 352 364 /* Only for QMP V4 PHY - QSERDES COM registers */ 353 365 #define QSERDES_V4_COM_SSC_EN_CENTER 0x010
+12
drivers/phy/rockchip/Kconfig
··· 9 9 help 10 10 Enable this to support the Rockchip Display Port PHY. 11 11 12 + config PHY_ROCKCHIP_DPHY_RX0 13 + tristate "Rockchip MIPI Synopsys DPHY RX0 driver" 14 + depends on ARCH_ROCKCHIP || COMPILE_TEST 15 + select GENERIC_PHY_MIPI_DPHY 16 + select GENERIC_PHY 17 + help 18 + Enable this to support the Rockchip MIPI Synopsys DPHY RX0 19 + associated to the Rockchip ISP module present in RK3399 SoCs. 20 + 21 + To compile this driver as a module, choose M here: the module 22 + will be called phy-rockchip-dphy-rx0. 23 + 12 24 config PHY_ROCKCHIP_EMMC 13 25 tristate "Rockchip EMMC PHY Driver" 14 26 depends on ARCH_ROCKCHIP && OF
+1
drivers/phy/rockchip/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o 3 + obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0.o 3 4 obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o 4 5 obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o 5 6 obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
+12 -27
drivers/phy/samsung/phy-exynos5-usbdrd.c
··· 16 16 #include <linux/of.h> 17 17 #include <linux/of_address.h> 18 18 #include <linux/of_device.h> 19 + #include <linux/iopoll.h> 19 20 #include <linux/phy/phy.h> 20 21 #include <linux/platform_device.h> 21 22 #include <linux/mutex.h> ··· 557 556 static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd, 558 557 u32 val, u32 cmd) 559 558 { 560 - u32 usec = 100; 561 559 unsigned int result; 560 + int err; 562 561 563 562 writel(val | cmd, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 564 563 565 - do { 566 - result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1); 567 - if (result & PHYREG1_CR_ACK) 568 - break; 569 - 570 - udelay(1); 571 - } while (usec-- > 0); 572 - 573 - if (!usec) { 574 - dev_err(phy_drd->dev, 575 - "CRPORT handshake timeout1 (0x%08x)\n", val); 576 - return -ETIME; 564 + err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, 565 + result, (result & PHYREG1_CR_ACK), 1, 100); 566 + if (err == -ETIMEDOUT) { 567 + dev_err(phy_drd->dev, "CRPORT handshake timeout1 (0x%08x)\n", val); 568 + return err; 577 569 } 578 - 579 - usec = 100; 580 570 581 571 writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); 582 572 583 - do { 584 - result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1); 585 - if (!(result & PHYREG1_CR_ACK)) 586 - break; 587 - 588 - udelay(1); 589 - } while (usec-- > 0); 590 - 591 - if (!usec) { 592 - dev_err(phy_drd->dev, 593 - "CRPORT handshake timeout2 (0x%08x)\n", val); 594 - return -ETIME; 573 + err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, 574 + result, !(result & PHYREG1_CR_ACK), 1, 100); 575 + if (err == -ETIMEDOUT) { 576 + dev_err(phy_drd->dev, "CRPORT handshake timeout2 (0x%08x)\n", val); 577 + return err; 595 578 } 596 579 597 580 return 0;
+1 -1
drivers/phy/samsung/phy-samsung-ufs.c
··· 268 268 return 0; 269 269 } 270 270 271 - static struct phy_ops samsung_ufs_phy_ops = { 271 + static const struct phy_ops samsung_ufs_phy_ops = { 272 272 .init = samsung_ufs_phy_init, 273 273 .exit = samsung_ufs_phy_exit, 274 274 .power_on = samsung_ufs_phy_power_on,
+10
drivers/phy/socionext/Kconfig
··· 34 34 help 35 35 Enable this to support PHY implemented in PCIe controller 36 36 on UniPhier SoCs. This driver supports LD20 and PXs3 SoCs. 37 + 38 + config PHY_UNIPHIER_AHCI 39 + tristate "UniPhier AHCI PHY driver" 40 + depends on ARCH_UNIPHIER || COMPILE_TEST 41 + depends on OF && HAS_IOMEM 42 + default SATA_AHCI_PLATFORM 43 + select GENERIC_PHY 44 + help 45 + Enable this to support PHY implemented in AHCI controller 46 + on UniPhier SoCs. This driver supports PXs2 and PXs3 SoCs.
+1
drivers/phy/socionext/Makefile
··· 6 6 obj-$(CONFIG_PHY_UNIPHIER_USB2) += phy-uniphier-usb2.o 7 7 obj-$(CONFIG_PHY_UNIPHIER_USB3) += phy-uniphier-usb3hs.o phy-uniphier-usb3ss.o 8 8 obj-$(CONFIG_PHY_UNIPHIER_PCIE) += phy-uniphier-pcie.o 9 + obj-$(CONFIG_PHY_UNIPHIER_AHCI) += phy-uniphier-ahci.o
+321
drivers/phy/socionext/phy-uniphier-ahci.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * phy-uniphier-ahci.c - PHY driver for UniPhier AHCI controller 4 + * Copyright 2016-2020, Socionext Inc. 5 + * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/bitops.h> 10 + #include <linux/clk.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/of_platform.h> 15 + #include <linux/phy/phy.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/reset.h> 18 + 19 + struct uniphier_ahciphy_priv { 20 + struct device *dev; 21 + void __iomem *base; 22 + struct clk *clk, *clk_parent; 23 + struct reset_control *rst, *rst_parent; 24 + const struct uniphier_ahciphy_soc_data *data; 25 + }; 26 + 27 + struct uniphier_ahciphy_soc_data { 28 + int (*init)(struct uniphier_ahciphy_priv *priv); 29 + int (*power_on)(struct uniphier_ahciphy_priv *priv); 30 + int (*power_off)(struct uniphier_ahciphy_priv *priv); 31 + bool is_ready_high; 32 + bool is_phy_clk; 33 + }; 34 + 35 + /* for PXs2/PXs3 */ 36 + #define CKCTRL 0x0 37 + #define CKCTRL_P0_READY BIT(15) 38 + #define CKCTRL_P0_RESET BIT(10) 39 + #define CKCTRL_REF_SSP_EN BIT(9) 40 + #define TXCTRL0 0x4 41 + #define TXCTRL0_AMP_G3_MASK GENMASK(22, 16) 42 + #define TXCTRL0_AMP_G2_MASK GENMASK(14, 8) 43 + #define TXCTRL0_AMP_G1_MASK GENMASK(6, 0) 44 + #define TXCTRL1 0x8 45 + #define TXCTRL1_DEEMPH_G3_MASK GENMASK(21, 16) 46 + #define TXCTRL1_DEEMPH_G2_MASK GENMASK(13, 8) 47 + #define TXCTRL1_DEEMPH_G1_MASK GENMASK(5, 0) 48 + #define RXCTRL 0xc 49 + #define RXCTRL_LOS_LVL_MASK GENMASK(20, 16) 50 + #define RXCTRL_LOS_BIAS_MASK GENMASK(10, 8) 51 + #define RXCTRL_RX_EQ_MASK GENMASK(2, 0) 52 + 53 + static void uniphier_ahciphy_pxs2_enable(struct uniphier_ahciphy_priv *priv, 54 + bool enable) 55 + { 56 + u32 val; 57 + 58 + val = readl(priv->base + CKCTRL); 59 + 60 + if (enable) { 61 + val |= CKCTRL_REF_SSP_EN; 62 + writel(val, priv->base + CKCTRL); 63 + val &= ~CKCTRL_P0_RESET; 64 + writel(val, priv->base + CKCTRL); 65 + } else { 66 + val |= CKCTRL_P0_RESET; 67 + writel(val, priv->base + CKCTRL); 68 + val &= ~CKCTRL_REF_SSP_EN; 69 + writel(val, priv->base + CKCTRL); 70 + } 71 + } 72 + 73 + static int uniphier_ahciphy_pxs2_power_on(struct uniphier_ahciphy_priv *priv) 74 + { 75 + int ret; 76 + u32 val; 77 + 78 + uniphier_ahciphy_pxs2_enable(priv, true); 79 + 80 + /* wait until PLL is ready */ 81 + if (priv->data->is_ready_high) 82 + ret = readl_poll_timeout(priv->base + CKCTRL, val, 83 + (val & CKCTRL_P0_READY), 200, 400); 84 + else 85 + ret = readl_poll_timeout(priv->base + CKCTRL, val, 86 + !(val & CKCTRL_P0_READY), 200, 400); 87 + if (ret) { 88 + dev_err(priv->dev, "Failed to check whether PHY PLL is ready\n"); 89 + uniphier_ahciphy_pxs2_enable(priv, false); 90 + } 91 + 92 + return ret; 93 + } 94 + 95 + static int uniphier_ahciphy_pxs2_power_off(struct uniphier_ahciphy_priv *priv) 96 + { 97 + uniphier_ahciphy_pxs2_enable(priv, false); 98 + 99 + return 0; 100 + } 101 + 102 + static int uniphier_ahciphy_pxs3_init(struct uniphier_ahciphy_priv *priv) 103 + { 104 + int i; 105 + u32 val; 106 + 107 + /* setup port parameter */ 108 + val = readl(priv->base + TXCTRL0); 109 + val &= ~TXCTRL0_AMP_G3_MASK; 110 + val |= FIELD_PREP(TXCTRL0_AMP_G3_MASK, 0x73); 111 + val &= ~TXCTRL0_AMP_G2_MASK; 112 + val |= FIELD_PREP(TXCTRL0_AMP_G2_MASK, 0x46); 113 + val &= ~TXCTRL0_AMP_G1_MASK; 114 + val |= FIELD_PREP(TXCTRL0_AMP_G1_MASK, 0x42); 115 + writel(val, priv->base + TXCTRL0); 116 + 117 + val = readl(priv->base + TXCTRL1); 118 + val &= ~TXCTRL1_DEEMPH_G3_MASK; 119 + val |= FIELD_PREP(TXCTRL1_DEEMPH_G3_MASK, 0x23); 120 + val &= ~TXCTRL1_DEEMPH_G2_MASK; 121 + val |= FIELD_PREP(TXCTRL1_DEEMPH_G2_MASK, 0x05); 122 + val &= ~TXCTRL1_DEEMPH_G1_MASK; 123 + val |= FIELD_PREP(TXCTRL1_DEEMPH_G1_MASK, 0x05); 124 + 125 + val = readl(priv->base + RXCTRL); 126 + val &= ~RXCTRL_LOS_LVL_MASK; 127 + val |= FIELD_PREP(RXCTRL_LOS_LVL_MASK, 0x9); 128 + val &= ~RXCTRL_LOS_BIAS_MASK; 129 + val |= FIELD_PREP(RXCTRL_LOS_BIAS_MASK, 0x2); 130 + val &= ~RXCTRL_RX_EQ_MASK; 131 + val |= FIELD_PREP(RXCTRL_RX_EQ_MASK, 0x1); 132 + 133 + /* dummy read 25 times to make a wait time for the phy to stabilize */ 134 + for (i = 0; i < 25; i++) 135 + readl(priv->base + CKCTRL); 136 + 137 + return 0; 138 + } 139 + 140 + static int uniphier_ahciphy_init(struct phy *phy) 141 + { 142 + struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); 143 + int ret; 144 + 145 + ret = clk_prepare_enable(priv->clk_parent); 146 + if (ret) 147 + return ret; 148 + 149 + ret = reset_control_deassert(priv->rst_parent); 150 + if (ret) 151 + goto out_clk_disable; 152 + 153 + if (priv->data->init) { 154 + ret = priv->data->init(priv); 155 + if (ret) 156 + goto out_rst_assert; 157 + } 158 + 159 + return 0; 160 + 161 + out_rst_assert: 162 + reset_control_assert(priv->rst_parent); 163 + out_clk_disable: 164 + clk_disable_unprepare(priv->clk_parent); 165 + 166 + return ret; 167 + } 168 + 169 + static int uniphier_ahciphy_exit(struct phy *phy) 170 + { 171 + struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); 172 + 173 + reset_control_assert(priv->rst_parent); 174 + clk_disable_unprepare(priv->clk_parent); 175 + 176 + return 0; 177 + } 178 + 179 + static int uniphier_ahciphy_power_on(struct phy *phy) 180 + { 181 + struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); 182 + int ret = 0; 183 + 184 + ret = clk_prepare_enable(priv->clk); 185 + if (ret) 186 + return ret; 187 + 188 + ret = reset_control_deassert(priv->rst); 189 + if (ret) 190 + goto out_clk_disable; 191 + 192 + if (priv->data->power_on) { 193 + ret = priv->data->power_on(priv); 194 + if (ret) 195 + goto out_reset_assert; 196 + } 197 + 198 + return 0; 199 + 200 + out_reset_assert: 201 + reset_control_assert(priv->rst); 202 + out_clk_disable: 203 + clk_disable_unprepare(priv->clk); 204 + 205 + return ret; 206 + } 207 + 208 + static int uniphier_ahciphy_power_off(struct phy *phy) 209 + { 210 + struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy); 211 + int ret = 0; 212 + 213 + if (priv->data->power_off) 214 + ret = priv->data->power_off(priv); 215 + 216 + reset_control_assert(priv->rst); 217 + clk_disable_unprepare(priv->clk); 218 + 219 + return ret; 220 + } 221 + 222 + static const struct phy_ops uniphier_ahciphy_ops = { 223 + .init = uniphier_ahciphy_init, 224 + .exit = uniphier_ahciphy_exit, 225 + .power_on = uniphier_ahciphy_power_on, 226 + .power_off = uniphier_ahciphy_power_off, 227 + .owner = THIS_MODULE, 228 + }; 229 + 230 + static int uniphier_ahciphy_probe(struct platform_device *pdev) 231 + { 232 + struct device *dev = &pdev->dev; 233 + struct uniphier_ahciphy_priv *priv; 234 + struct phy *phy; 235 + struct phy_provider *phy_provider; 236 + 237 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 238 + if (!priv) 239 + return -ENOMEM; 240 + 241 + priv->dev = dev; 242 + priv->data = of_device_get_match_data(dev); 243 + if (WARN_ON(!priv->data)) 244 + return -EINVAL; 245 + 246 + priv->base = devm_platform_ioremap_resource(pdev, 0); 247 + if (IS_ERR(priv->base)) 248 + return PTR_ERR(priv->base); 249 + 250 + priv->clk_parent = devm_clk_get(dev, "link"); 251 + if (IS_ERR(priv->clk_parent)) 252 + return PTR_ERR(priv->clk_parent); 253 + 254 + if (priv->data->is_phy_clk) { 255 + priv->clk = devm_clk_get(dev, "phy"); 256 + if (IS_ERR(priv->clk)) 257 + return PTR_ERR(priv->clk); 258 + } 259 + 260 + priv->rst_parent = devm_reset_control_get_shared(dev, "link"); 261 + if (IS_ERR(priv->rst_parent)) 262 + return PTR_ERR(priv->rst_parent); 263 + 264 + priv->rst = devm_reset_control_get_shared(dev, "phy"); 265 + if (IS_ERR(priv->rst)) 266 + return PTR_ERR(priv->rst); 267 + 268 + phy = devm_phy_create(dev, dev->of_node, &uniphier_ahciphy_ops); 269 + if (IS_ERR(phy)) { 270 + dev_err(dev, "failed to create phy\n"); 271 + return PTR_ERR(phy); 272 + } 273 + 274 + phy_set_drvdata(phy, priv); 275 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 276 + if (IS_ERR(phy_provider)) 277 + return PTR_ERR(phy_provider); 278 + 279 + return 0; 280 + } 281 + 282 + static const struct uniphier_ahciphy_soc_data uniphier_pxs2_data = { 283 + .power_on = uniphier_ahciphy_pxs2_power_on, 284 + .power_off = uniphier_ahciphy_pxs2_power_off, 285 + .is_ready_high = false, 286 + .is_phy_clk = false, 287 + }; 288 + 289 + static const struct uniphier_ahciphy_soc_data uniphier_pxs3_data = { 290 + .init = uniphier_ahciphy_pxs3_init, 291 + .power_on = uniphier_ahciphy_pxs2_power_on, 292 + .power_off = uniphier_ahciphy_pxs2_power_off, 293 + .is_ready_high = true, 294 + .is_phy_clk = true, 295 + }; 296 + 297 + static const struct of_device_id uniphier_ahciphy_match[] = { 298 + { 299 + .compatible = "socionext,uniphier-pxs2-ahci-phy", 300 + .data = &uniphier_pxs2_data, 301 + }, 302 + { 303 + .compatible = "socionext,uniphier-pxs3-ahci-phy", 304 + .data = &uniphier_pxs3_data, 305 + }, 306 + { /* Sentinel */ }, 307 + }; 308 + MODULE_DEVICE_TABLE(of, uniphier_ahciphy_match); 309 + 310 + static struct platform_driver uniphier_ahciphy_driver = { 311 + .probe = uniphier_ahciphy_probe, 312 + .driver = { 313 + .name = "uniphier-ahci-phy", 314 + .of_match_table = uniphier_ahciphy_match, 315 + }, 316 + }; 317 + module_platform_driver(uniphier_ahciphy_driver); 318 + 319 + MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); 320 + MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller"); 321 + MODULE_LICENSE("GPL v2");
+210 -113
drivers/phy/ti/phy-am654-serdes.c
··· 19 19 #include <linux/pm_runtime.h> 20 20 #include <linux/regmap.h> 21 21 22 + #define CMU_R004 0x4 23 + #define CMU_R060 0x60 22 24 #define CMU_R07C 0x7c 25 + #define CMU_R088 0x88 26 + #define CMU_R0D0 0xd0 27 + #define CMU_R0E8 0xe8 23 28 29 + #define LANE_R048 0x248 30 + #define LANE_R058 0x258 31 + #define LANE_R06c 0x26c 32 + #define LANE_R070 0x270 33 + #define LANE_R070 0x270 34 + #define LANE_R19C 0x39c 35 + 36 + #define COMLANE_R004 0xa04 24 37 #define COMLANE_R138 0xb38 25 - #define VERSION 0x70 38 + #define VERSION_VAL 0x70 26 39 27 40 #define COMLANE_R190 0xb90 28 - 29 41 #define COMLANE_R194 0xb94 42 + 43 + #define COMRXEQ_R004 0x1404 44 + #define COMRXEQ_R008 0x1408 45 + #define COMRXEQ_R00C 0x140c 46 + #define COMRXEQ_R014 0x1414 47 + #define COMRXEQ_R018 0x1418 48 + #define COMRXEQ_R01C 0x141c 49 + #define COMRXEQ_R04C 0x144c 50 + #define COMRXEQ_R088 0x1488 51 + #define COMRXEQ_R094 0x1494 52 + #define COMRXEQ_R098 0x1498 30 53 31 54 #define SERDES_CTRL 0x1fd0 32 55 ··· 103 80 .max_register = 0x1ffc, 104 81 }; 105 82 106 - static const struct reg_field cmu_master_cdn_o = REG_FIELD(CMU_R07C, 24, 24); 107 - static const struct reg_field config_version = REG_FIELD(COMLANE_R138, 16, 23); 108 - static const struct reg_field l1_master_cdn_o = REG_FIELD(COMLANE_R190, 9, 9); 109 - static const struct reg_field cmu_ok_i_0 = REG_FIELD(COMLANE_R194, 19, 19); 110 - static const struct reg_field por_en = REG_FIELD(SERDES_CTRL, 29, 29); 111 - static const struct reg_field tx0_enable = REG_FIELD(WIZ_LANEXCTL_STS, 29, 31); 112 - static const struct reg_field rx0_enable = REG_FIELD(WIZ_LANEXCTL_STS, 13, 15); 113 - static const struct reg_field pll_enable = REG_FIELD(WIZ_PLL_CTRL, 29, 31); 114 - static const struct reg_field pll_ok = REG_FIELD(WIZ_PLL_CTRL, 28, 28); 83 + enum serdes_am654_fields { 84 + /* CMU PLL Control */ 85 + CMU_PLL_CTRL, 86 + 87 + LANE_PLL_CTRL_RXEQ_RXIDLE, 88 + 89 + /* CMU VCO bias current and VREG setting */ 90 + AHB_PMA_CM_VCO_VBIAS_VREG, 91 + AHB_PMA_CM_VCO_BIAS_VREG, 92 + 93 + AHB_PMA_CM_SR, 94 + AHB_SSC_GEN_Z_O_20_13, 95 + 96 + /* AHB PMA Lane Configuration */ 97 + AHB_PMA_LN_AGC_THSEL_VREGH, 98 + 99 + /* AGC and Signal detect threshold for Gen3 */ 100 + AHB_PMA_LN_GEN3_AGC_SD_THSEL, 101 + 102 + AHB_PMA_LN_RX_SELR_GEN3, 103 + AHB_PMA_LN_TX_DRV, 104 + 105 + /* CMU Master Reset */ 106 + CMU_MASTER_CDN, 107 + 108 + /* P2S ring buffer initial startup pointer difference */ 109 + P2S_RBUF_PTR_DIFF, 110 + 111 + CONFIG_VERSION, 112 + 113 + /* Lane 1 Master Reset */ 114 + L1_MASTER_CDN, 115 + 116 + /* CMU OK Status */ 117 + CMU_OK_I_0, 118 + 119 + /* Mid-speed initial calibration control */ 120 + COMRXEQ_MS_INIT_CTRL_7_0, 121 + 122 + /* High-speed initial calibration control */ 123 + COMRXEQ_HS_INIT_CAL_7_0, 124 + 125 + /* Mid-speed recalibration control */ 126 + COMRXEQ_MS_RECAL_CTRL_7_0, 127 + 128 + /* High-speed recalibration control */ 129 + COMRXEQ_HS_RECAL_CTRL_7_0, 130 + 131 + /* ATT configuration */ 132 + COMRXEQ_CSR_ATT_CONFIG, 133 + 134 + /* Edge based boost adaptation window length */ 135 + COMRXEQ_CSR_EBSTADAPT_WIN_LEN, 136 + 137 + /* COMRXEQ control 3 & 4 */ 138 + COMRXEQ_CTRL_3_4, 139 + 140 + /* COMRXEQ control 14, 15 and 16*/ 141 + COMRXEQ_CTRL_14_15_16, 142 + 143 + /* Threshold for errors in pattern data */ 144 + COMRXEQ_CSR_DLEV_ERR_THRESH, 145 + 146 + /* COMRXEQ control 25 */ 147 + COMRXEQ_CTRL_25, 148 + 149 + /* Mid-speed rate change calibration control */ 150 + CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O, 151 + 152 + /* High-speed rate change calibration control */ 153 + COMRXEQ_HS_RCHANGE_CTRL_7_0, 154 + 155 + /* Serdes reset */ 156 + POR_EN, 157 + 158 + /* Tx Enable Value */ 159 + TX0_ENABLE, 160 + 161 + /* Rx Enable Value */ 162 + RX0_ENABLE, 163 + 164 + /* PLL Enable Value */ 165 + PLL_ENABLE, 166 + 167 + /* PLL ready for use */ 168 + PLL_OK, 169 + 170 + /* sentinel */ 171 + MAX_FIELDS 172 + 173 + }; 174 + 175 + static const struct reg_field serdes_am654_reg_fields[] = { 176 + [CMU_PLL_CTRL] = REG_FIELD(CMU_R004, 8, 15), 177 + [AHB_PMA_CM_VCO_VBIAS_VREG] = REG_FIELD(CMU_R060, 8, 15), 178 + [CMU_MASTER_CDN] = REG_FIELD(CMU_R07C, 24, 31), 179 + [AHB_PMA_CM_VCO_BIAS_VREG] = REG_FIELD(CMU_R088, 24, 31), 180 + [AHB_PMA_CM_SR] = REG_FIELD(CMU_R0D0, 24, 31), 181 + [AHB_SSC_GEN_Z_O_20_13] = REG_FIELD(CMU_R0E8, 8, 15), 182 + [LANE_PLL_CTRL_RXEQ_RXIDLE] = REG_FIELD(LANE_R048, 8, 15), 183 + [AHB_PMA_LN_AGC_THSEL_VREGH] = REG_FIELD(LANE_R058, 16, 23), 184 + [AHB_PMA_LN_GEN3_AGC_SD_THSEL] = REG_FIELD(LANE_R06c, 0, 7), 185 + [AHB_PMA_LN_RX_SELR_GEN3] = REG_FIELD(LANE_R070, 16, 23), 186 + [AHB_PMA_LN_TX_DRV] = REG_FIELD(LANE_R19C, 16, 23), 187 + [P2S_RBUF_PTR_DIFF] = REG_FIELD(COMLANE_R004, 0, 7), 188 + [CONFIG_VERSION] = REG_FIELD(COMLANE_R138, 16, 23), 189 + [L1_MASTER_CDN] = REG_FIELD(COMLANE_R190, 8, 15), 190 + [CMU_OK_I_0] = REG_FIELD(COMLANE_R194, 19, 19), 191 + [COMRXEQ_MS_INIT_CTRL_7_0] = REG_FIELD(COMRXEQ_R004, 24, 31), 192 + [COMRXEQ_HS_INIT_CAL_7_0] = REG_FIELD(COMRXEQ_R008, 0, 7), 193 + [COMRXEQ_MS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 8, 15), 194 + [COMRXEQ_HS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 16, 23), 195 + [COMRXEQ_CSR_ATT_CONFIG] = REG_FIELD(COMRXEQ_R014, 16, 23), 196 + [COMRXEQ_CSR_EBSTADAPT_WIN_LEN] = REG_FIELD(COMRXEQ_R018, 16, 23), 197 + [COMRXEQ_CTRL_3_4] = REG_FIELD(COMRXEQ_R01C, 8, 15), 198 + [COMRXEQ_CTRL_14_15_16] = REG_FIELD(COMRXEQ_R04C, 0, 7), 199 + [COMRXEQ_CSR_DLEV_ERR_THRESH] = REG_FIELD(COMRXEQ_R088, 16, 23), 200 + [COMRXEQ_CTRL_25] = REG_FIELD(COMRXEQ_R094, 24, 31), 201 + [CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O] = REG_FIELD(COMRXEQ_R098, 8, 15), 202 + [COMRXEQ_HS_RCHANGE_CTRL_7_0] = REG_FIELD(COMRXEQ_R098, 16, 23), 203 + [POR_EN] = REG_FIELD(SERDES_CTRL, 29, 29), 204 + [TX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 29, 31), 205 + [RX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 13, 15), 206 + [PLL_ENABLE] = REG_FIELD(WIZ_PLL_CTRL, 29, 31), 207 + [PLL_OK] = REG_FIELD(WIZ_PLL_CTRL, 28, 28), 208 + }; 115 209 116 210 struct serdes_am654 { 117 211 struct regmap *regmap; 118 - struct regmap_field *cmu_master_cdn_o; 119 - struct regmap_field *config_version; 120 - struct regmap_field *l1_master_cdn_o; 121 - struct regmap_field *cmu_ok_i_0; 122 - struct regmap_field *por_en; 123 - struct regmap_field *tx0_enable; 124 - struct regmap_field *rx0_enable; 125 - struct regmap_field *pll_enable; 126 - struct regmap_field *pll_ok; 212 + struct regmap_field *fields[MAX_FIELDS]; 127 213 128 214 struct device *dev; 129 215 struct mux_control *control; ··· 248 116 int ret; 249 117 u32 val; 250 118 251 - ret = regmap_field_write(phy->pll_enable, PLL_ENABLE_STATE); 119 + ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_ENABLE_STATE); 252 120 if (ret) 253 121 return ret; 254 122 255 - return regmap_field_read_poll_timeout(phy->pll_ok, val, val, 1000, 256 - PLL_LOCK_TIME); 123 + return regmap_field_read_poll_timeout(phy->fields[PLL_OK], val, val, 124 + 1000, PLL_LOCK_TIME); 257 125 } 258 126 259 127 static void serdes_am654_disable_pll(struct serdes_am654 *phy) ··· 261 129 struct device *dev = phy->dev; 262 130 int ret; 263 131 264 - ret = regmap_field_write(phy->pll_enable, PLL_DISABLE_STATE); 132 + ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_DISABLE_STATE); 265 133 if (ret) 266 134 dev_err(dev, "Failed to disable PLL\n"); 267 135 } 268 136 269 137 static int serdes_am654_enable_txrx(struct serdes_am654 *phy) 270 138 { 271 - int ret; 139 + int ret = 0; 272 140 273 141 /* Enable TX */ 274 - ret = regmap_field_write(phy->tx0_enable, TX0_ENABLE_STATE); 275 - if (ret) 276 - return ret; 142 + ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_ENABLE_STATE); 277 143 278 144 /* Enable RX */ 279 - ret = regmap_field_write(phy->rx0_enable, RX0_ENABLE_STATE); 145 + ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_ENABLE_STATE); 146 + 280 147 if (ret) 281 - return ret; 148 + return -EIO; 282 149 283 150 return 0; 284 151 } 285 152 286 153 static int serdes_am654_disable_txrx(struct serdes_am654 *phy) 287 154 { 288 - int ret; 155 + int ret = 0; 289 156 290 157 /* Disable TX */ 291 - ret = regmap_field_write(phy->tx0_enable, TX0_DISABLE_STATE); 292 - if (ret) 293 - return ret; 158 + ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_DISABLE_STATE); 294 159 295 160 /* Disable RX */ 296 - ret = regmap_field_write(phy->rx0_enable, RX0_DISABLE_STATE); 161 + ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_DISABLE_STATE); 162 + 297 163 if (ret) 298 - return ret; 164 + return -EIO; 299 165 300 166 return 0; 301 167 } ··· 317 187 return ret; 318 188 } 319 189 320 - return regmap_field_read_poll_timeout(phy->cmu_ok_i_0, val, val, 321 - SLEEP_TIME, PLL_LOCK_TIME); 190 + return regmap_field_read_poll_timeout(phy->fields[CMU_OK_I_0], val, 191 + val, SLEEP_TIME, PLL_LOCK_TIME); 322 192 } 323 193 324 194 static int serdes_am654_power_off(struct phy *x) ··· 416 286 417 287 static int serdes_am654_pcie_init(struct serdes_am654 *phy) 418 288 { 419 - int ret; 289 + int ret = 0; 420 290 421 - ret = regmap_field_write(phy->config_version, VERSION); 422 - if (ret) 423 - return ret; 291 + ret |= regmap_field_write(phy->fields[CMU_PLL_CTRL], 0x2); 292 + ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_VBIAS_VREG], 0x98); 293 + ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_BIAS_VREG], 0x98); 294 + ret |= regmap_field_write(phy->fields[AHB_PMA_CM_SR], 0x45); 295 + ret |= regmap_field_write(phy->fields[AHB_SSC_GEN_Z_O_20_13], 0xe); 296 + ret |= regmap_field_write(phy->fields[LANE_PLL_CTRL_RXEQ_RXIDLE], 0x5); 297 + ret |= regmap_field_write(phy->fields[AHB_PMA_LN_AGC_THSEL_VREGH], 0x83); 298 + ret |= regmap_field_write(phy->fields[AHB_PMA_LN_GEN3_AGC_SD_THSEL], 0x83); 299 + ret |= regmap_field_write(phy->fields[AHB_PMA_LN_RX_SELR_GEN3], 0x81); 300 + ret |= regmap_field_write(phy->fields[AHB_PMA_LN_TX_DRV], 0x3b); 301 + ret |= regmap_field_write(phy->fields[P2S_RBUF_PTR_DIFF], 0x3); 302 + ret |= regmap_field_write(phy->fields[CONFIG_VERSION], VERSION_VAL); 303 + ret |= regmap_field_write(phy->fields[COMRXEQ_MS_INIT_CTRL_7_0], 0xf); 304 + ret |= regmap_field_write(phy->fields[COMRXEQ_HS_INIT_CAL_7_0], 0x4f); 305 + ret |= regmap_field_write(phy->fields[COMRXEQ_MS_RECAL_CTRL_7_0], 0xf); 306 + ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RECAL_CTRL_7_0], 0x4f); 307 + ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_ATT_CONFIG], 0x7); 308 + ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_EBSTADAPT_WIN_LEN], 0x7f); 309 + ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_3_4], 0xf); 310 + ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_14_15_16], 0x9a); 311 + ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_DLEV_ERR_THRESH], 0x32); 312 + ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_25], 0x80); 313 + ret |= regmap_field_write(phy->fields[CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O], 0xf); 314 + ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RCHANGE_CTRL_7_0], 0x4f); 315 + ret |= regmap_field_write(phy->fields[CMU_MASTER_CDN], 0x1); 316 + ret |= regmap_field_write(phy->fields[L1_MASTER_CDN], 0x2); 424 317 425 - ret = regmap_field_write(phy->cmu_master_cdn_o, 0x1); 426 318 if (ret) 427 - return ret; 428 - 429 - ret = regmap_field_write(phy->l1_master_cdn_o, 0x1); 430 - if (ret) 431 - return ret; 319 + return -EIO; 432 320 433 321 return 0; 434 322 } ··· 468 320 static int serdes_am654_reset(struct phy *x) 469 321 { 470 322 struct serdes_am654 *phy = phy_get_drvdata(x); 471 - int ret; 323 + int ret = 0; 472 324 473 325 serdes_am654_disable_pll(phy); 474 326 serdes_am654_disable_txrx(phy); 475 327 476 - ret = regmap_field_write(phy->por_en, 0x1); 477 - if (ret) 478 - return ret; 328 + ret |= regmap_field_write(phy->fields[POR_EN], 0x1); 479 329 480 330 mdelay(1); 481 331 482 - ret = regmap_field_write(phy->por_en, 0x0); 332 + ret |= regmap_field_write(phy->fields[POR_EN], 0x0); 333 + 483 334 if (ret) 484 - return ret; 335 + return -EIO; 485 336 486 337 return 0; 487 338 } ··· 734 587 { 735 588 struct regmap *regmap = am654_phy->regmap; 736 589 struct device *dev = am654_phy->dev; 590 + int i; 737 591 738 - am654_phy->cmu_master_cdn_o = devm_regmap_field_alloc(dev, regmap, 739 - cmu_master_cdn_o); 740 - if (IS_ERR(am654_phy->cmu_master_cdn_o)) { 741 - dev_err(dev, "CMU_MASTER_CDN_O reg field init failed\n"); 742 - return PTR_ERR(am654_phy->cmu_master_cdn_o); 743 - } 744 - 745 - am654_phy->config_version = devm_regmap_field_alloc(dev, regmap, 746 - config_version); 747 - if (IS_ERR(am654_phy->config_version)) { 748 - dev_err(dev, "CONFIG_VERSION reg field init failed\n"); 749 - return PTR_ERR(am654_phy->config_version); 750 - } 751 - 752 - am654_phy->l1_master_cdn_o = devm_regmap_field_alloc(dev, regmap, 753 - l1_master_cdn_o); 754 - if (IS_ERR(am654_phy->l1_master_cdn_o)) { 755 - dev_err(dev, "L1_MASTER_CDN_O reg field init failed\n"); 756 - return PTR_ERR(am654_phy->l1_master_cdn_o); 757 - } 758 - 759 - am654_phy->cmu_ok_i_0 = devm_regmap_field_alloc(dev, regmap, 760 - cmu_ok_i_0); 761 - if (IS_ERR(am654_phy->cmu_ok_i_0)) { 762 - dev_err(dev, "CMU_OK_I_0 reg field init failed\n"); 763 - return PTR_ERR(am654_phy->cmu_ok_i_0); 764 - } 765 - 766 - am654_phy->por_en = devm_regmap_field_alloc(dev, regmap, por_en); 767 - if (IS_ERR(am654_phy->por_en)) { 768 - dev_err(dev, "POR_EN reg field init failed\n"); 769 - return PTR_ERR(am654_phy->por_en); 770 - } 771 - 772 - am654_phy->tx0_enable = devm_regmap_field_alloc(dev, regmap, 773 - tx0_enable); 774 - if (IS_ERR(am654_phy->tx0_enable)) { 775 - dev_err(dev, "TX0_ENABLE reg field init failed\n"); 776 - return PTR_ERR(am654_phy->tx0_enable); 777 - } 778 - 779 - am654_phy->rx0_enable = devm_regmap_field_alloc(dev, regmap, 780 - rx0_enable); 781 - if (IS_ERR(am654_phy->rx0_enable)) { 782 - dev_err(dev, "RX0_ENABLE reg field init failed\n"); 783 - return PTR_ERR(am654_phy->rx0_enable); 784 - } 785 - 786 - am654_phy->pll_enable = devm_regmap_field_alloc(dev, regmap, 787 - pll_enable); 788 - if (IS_ERR(am654_phy->pll_enable)) { 789 - dev_err(dev, "PLL_ENABLE reg field init failed\n"); 790 - return PTR_ERR(am654_phy->pll_enable); 791 - } 792 - 793 - am654_phy->pll_ok = devm_regmap_field_alloc(dev, regmap, pll_ok); 794 - if (IS_ERR(am654_phy->pll_ok)) { 795 - dev_err(dev, "PLL_OK reg field init failed\n"); 796 - return PTR_ERR(am654_phy->pll_ok); 592 + for (i = 0; i < MAX_FIELDS; i++) { 593 + am654_phy->fields[i] = devm_regmap_field_alloc(dev, 594 + regmap, 595 + serdes_am654_reg_fields[i]); 596 + if (IS_ERR(am654_phy->fields[i])) { 597 + dev_err(dev, "Unable to allocate regmap field %d\n", i); 598 + return PTR_ERR(am654_phy->fields[i]); 599 + } 797 600 } 798 601 799 602 return 0;
+96 -63
drivers/phy/ti/phy-gmii-sel.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/mfd/syscon.h> 13 13 #include <linux/of.h> 14 + #include <linux/of_address.h> 14 15 #include <linux/of_net.h> 15 16 #include <linux/phy.h> 16 17 #include <linux/phy/phy.h> ··· 23 22 #define AM33XX_GMII_SEL_MODE_RGMII 2 24 23 25 24 enum { 26 - PHY_GMII_SEL_PORT_MODE, 25 + PHY_GMII_SEL_PORT_MODE = 0, 27 26 PHY_GMII_SEL_RGMII_ID_MODE, 28 27 PHY_GMII_SEL_RMII_IO_CLK_EN, 29 28 PHY_GMII_SEL_LAST, ··· 42 41 u32 num_ports; 43 42 u32 features; 44 43 const struct reg_field (*regfields)[PHY_GMII_SEL_LAST]; 44 + bool use_of_data; 45 45 }; 46 46 47 47 struct phy_gmii_sel_priv { ··· 51 49 struct regmap *regmap; 52 50 struct phy_provider *phy_provider; 53 51 struct phy_gmii_sel_phy_priv *if_phys; 52 + u32 num_ports; 53 + u32 reg_offset; 54 54 }; 55 55 56 56 static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode) ··· 151 147 struct reg_field phy_gmii_sel_fields_dra7[][PHY_GMII_SEL_LAST] = { 152 148 { 153 149 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 0, 1), 154 - [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0), 155 - [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0), 156 150 }, 157 151 { 158 152 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 4, 5), 159 - [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0), 160 - [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0), 161 153 }, 162 154 }; 163 155 ··· 172 172 173 173 static const 174 174 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = { 175 - { 176 - [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4040, 0, 1), 177 - [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0), 178 - [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0), 179 - }, 175 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), }, 176 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), }, 177 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), }, 178 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), }, 179 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), }, 180 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), }, 181 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), }, 182 + { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), }, 180 183 }; 181 184 182 185 static const 183 186 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = { 184 - .num_ports = 1, 187 + .use_of_data = true, 185 188 .regfields = phy_gmii_sel_fields_am654, 186 189 }; 187 190 ··· 231 228 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) && 232 229 args->args_count < 2) 233 230 return ERR_PTR(-EINVAL); 234 - if (phy_id > priv->soc_data->num_ports) 231 + if (phy_id > priv->num_ports) 235 232 return ERR_PTR(-EINVAL); 236 233 if (phy_id != priv->if_phys[phy_id - 1].id) 237 234 return ERR_PTR(-EINVAL); ··· 245 242 return priv->if_phys[phy_id].if_phy; 246 243 } 247 244 248 - static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv) 245 + static int phy_gmii_init_phy(struct phy_gmii_sel_priv *priv, int port, 246 + struct phy_gmii_sel_phy_priv *if_phy) 249 247 { 250 248 const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data; 251 249 struct device *dev = priv->dev; 250 + const struct reg_field *fields; 251 + struct regmap_field *regfield; 252 + struct reg_field field; 253 + int ret; 254 + 255 + if_phy->id = port; 256 + if_phy->priv = priv; 257 + 258 + fields = soc_data->regfields[port - 1]; 259 + field = *fields++; 260 + field.reg += priv->reg_offset; 261 + dev_dbg(dev, "%s field %x %d %d\n", __func__, 262 + field.reg, field.msb, field.lsb); 263 + 264 + regfield = devm_regmap_field_alloc(dev, priv->regmap, field); 265 + if (IS_ERR(regfield)) 266 + return PTR_ERR(regfield); 267 + if_phy->fields[PHY_GMII_SEL_PORT_MODE] = regfield; 268 + 269 + field = *fields++; 270 + field.reg += priv->reg_offset; 271 + if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE)) { 272 + regfield = devm_regmap_field_alloc(dev, 273 + priv->regmap, 274 + field); 275 + if (IS_ERR(regfield)) 276 + return PTR_ERR(regfield); 277 + if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE] = regfield; 278 + dev_dbg(dev, "%s field %x %d %d\n", __func__, 279 + field.reg, field.msb, field.lsb); 280 + } 281 + 282 + field = *fields; 283 + field.reg += priv->reg_offset; 284 + if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN)) { 285 + regfield = devm_regmap_field_alloc(dev, 286 + priv->regmap, 287 + field); 288 + if (IS_ERR(regfield)) 289 + return PTR_ERR(regfield); 290 + if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN] = regfield; 291 + dev_dbg(dev, "%s field %x %d %d\n", __func__, 292 + field.reg, field.msb, field.lsb); 293 + } 294 + 295 + if_phy->if_phy = devm_phy_create(dev, 296 + priv->dev->of_node, 297 + &phy_gmii_sel_ops); 298 + if (IS_ERR(if_phy->if_phy)) { 299 + ret = PTR_ERR(if_phy->if_phy); 300 + dev_err(dev, "Failed to create phy%d %d\n", port, ret); 301 + return ret; 302 + } 303 + phy_set_drvdata(if_phy->if_phy, if_phy); 304 + 305 + return 0; 306 + } 307 + 308 + static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv) 309 + { 310 + const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data; 252 311 struct phy_gmii_sel_phy_priv *if_phys; 253 - int i, num_ports, ret; 312 + struct device *dev = priv->dev; 313 + int i, ret; 254 314 255 - num_ports = priv->soc_data->num_ports; 315 + if (soc_data->use_of_data) { 316 + const __be32 *offset; 317 + u64 size; 256 318 257 - if_phys = devm_kcalloc(priv->dev, num_ports, 319 + offset = of_get_address(dev->of_node, 0, &size, NULL); 320 + priv->num_ports = size / sizeof(u32); 321 + if (!priv->num_ports) 322 + return -EINVAL; 323 + priv->reg_offset = __be32_to_cpu(*offset); 324 + } 325 + 326 + if_phys = devm_kcalloc(dev, priv->num_ports, 258 327 sizeof(*if_phys), GFP_KERNEL); 259 328 if (!if_phys) 260 329 return -ENOMEM; 261 - dev_dbg(dev, "%s %d\n", __func__, num_ports); 330 + dev_dbg(dev, "%s %d\n", __func__, priv->num_ports); 262 331 263 - for (i = 0; i < num_ports; i++) { 264 - const struct reg_field *field; 265 - struct regmap_field *regfield; 266 - 267 - if_phys[i].id = i + 1; 268 - if_phys[i].priv = priv; 269 - 270 - field = &soc_data->regfields[i][PHY_GMII_SEL_PORT_MODE]; 271 - dev_dbg(dev, "%s field %x %d %d\n", __func__, 272 - field->reg, field->msb, field->lsb); 273 - 274 - regfield = devm_regmap_field_alloc(dev, priv->regmap, *field); 275 - if (IS_ERR(regfield)) 276 - return PTR_ERR(regfield); 277 - if_phys[i].fields[PHY_GMII_SEL_PORT_MODE] = regfield; 278 - 279 - field = &soc_data->regfields[i][PHY_GMII_SEL_RGMII_ID_MODE]; 280 - if (field->reg != (~0)) { 281 - regfield = devm_regmap_field_alloc(dev, 282 - priv->regmap, 283 - *field); 284 - if (IS_ERR(regfield)) 285 - return PTR_ERR(regfield); 286 - if_phys[i].fields[PHY_GMII_SEL_RGMII_ID_MODE] = 287 - regfield; 288 - } 289 - 290 - field = &soc_data->regfields[i][PHY_GMII_SEL_RMII_IO_CLK_EN]; 291 - if (field->reg != (~0)) { 292 - regfield = devm_regmap_field_alloc(dev, 293 - priv->regmap, 294 - *field); 295 - if (IS_ERR(regfield)) 296 - return PTR_ERR(regfield); 297 - if_phys[i].fields[PHY_GMII_SEL_RMII_IO_CLK_EN] = 298 - regfield; 299 - } 300 - 301 - if_phys[i].if_phy = devm_phy_create(dev, 302 - priv->dev->of_node, 303 - &phy_gmii_sel_ops); 304 - if (IS_ERR(if_phys[i].if_phy)) { 305 - ret = PTR_ERR(if_phys[i].if_phy); 306 - dev_err(dev, "Failed to create phy%d %d\n", i, ret); 332 + for (i = 0; i < priv->num_ports; i++) { 333 + ret = phy_gmii_init_phy(priv, i + 1, &if_phys[i]); 334 + if (ret) 307 335 return ret; 308 - } 309 - phy_set_drvdata(if_phys[i].if_phy, &if_phys[i]); 310 336 } 311 337 312 338 priv->if_phys = if_phys; ··· 360 328 361 329 priv->dev = &pdev->dev; 362 330 priv->soc_data = of_id->data; 331 + priv->num_ports = priv->soc_data->num_ports; 363 332 364 333 priv->regmap = syscon_node_to_regmap(node->parent); 365 334 if (IS_ERR(priv->regmap)) {
-1
drivers/phy/ti/phy-j721e-wiz.c
··· 20 20 #include <linux/pm_runtime.h> 21 21 #include <linux/regmap.h> 22 22 #include <linux/reset-controller.h> 23 - #include <dt-bindings/phy/phy.h> 24 23 25 24 #define WIZ_SERDES_CTRL 0x404 26 25 #define WIZ_SERDES_TOP_CTRL 0x408
+18 -20
drivers/phy/ti/phy-omap-usb2.c
··· 6 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 7 */ 8 8 9 - #include <linux/module.h> 10 - #include <linux/platform_device.h> 11 - #include <linux/slab.h> 12 - #include <linux/of.h> 13 - #include <linux/io.h> 14 - #include <linux/phy/omap_usb.h> 15 - #include <linux/usb/phy_companion.h> 16 9 #include <linux/clk.h> 17 - #include <linux/err.h> 18 - #include <linux/pm_runtime.h> 19 10 #include <linux/delay.h> 20 - #include <linux/phy/omap_control_phy.h> 21 - #include <linux/phy/phy.h> 11 + #include <linux/err.h> 12 + #include <linux/io.h> 22 13 #include <linux/mfd/syscon.h> 23 - #include <linux/regmap.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 24 16 #include <linux/of_platform.h> 17 + #include <linux/phy/omap_control_phy.h> 18 + #include <linux/phy/omap_usb.h> 19 + #include <linux/phy/phy.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/pm_runtime.h> 22 + #include <linux/regmap.h> 23 + #include <linux/slab.h> 25 24 #include <linux/sys_soc.h> 25 + #include <linux/usb/phy_companion.h> 26 26 27 27 #define USB2PHY_ANA_CONFIG1 0x4c 28 28 #define USB2PHY_DISCON_BYP_LATCH BIT(31) ··· 89 89 } 90 90 91 91 /** 92 - * omap_usb2_set_comparator - links the comparator present in the sytem with 92 + * omap_usb2_set_comparator - links the comparator present in the system with 93 93 * this phy 94 94 * @comparator - the companion phy(comparator) for this phy 95 95 * ··· 142 142 } 143 143 144 144 static int omap_usb_set_peripheral(struct usb_otg *otg, 145 - struct usb_gadget *gadget) 145 + struct usb_gadget *gadget) 146 146 { 147 147 otg->gadget = gadget; 148 148 if (!gadget) ··· 409 409 return PTR_ERR(phy->phy_base); 410 410 411 411 phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node, 412 - "syscon-phy-power"); 412 + "syscon-phy-power"); 413 413 if (IS_ERR(phy->syscon_phy_power)) { 414 414 dev_dbg(&pdev->dev, 415 415 "can't get syscon-phy-power, using control device\n"); ··· 438 438 } 439 439 } 440 440 441 - 442 441 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); 443 442 if (IS_ERR(phy->wkupclk)) { 444 443 if (PTR_ERR(phy->wkupclk) == -EPROBE_DEFER) ··· 451 452 if (PTR_ERR(phy->wkupclk) != -EPROBE_DEFER) 452 453 dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); 453 454 return PTR_ERR(phy->wkupclk); 454 - } else { 455 - dev_warn(&pdev->dev, 456 - "found usb_phy_cm_clk32k, please fix DTS\n"); 457 455 } 456 + 457 + dev_warn(&pdev->dev, 458 + "found usb_phy_cm_clk32k, please fix DTS\n"); 458 459 } 459 460 460 461 phy->optclk = devm_clk_get(phy->dev, "refclk"); ··· 502 503 pm_runtime_disable(phy->dev); 503 504 return PTR_ERR(phy_provider); 504 505 } 505 - 506 506 507 507 usb_add_phy_dev(&phy->phy); 508 508
-2
drivers/staging/media/Kconfig
··· 42 42 43 43 source "drivers/staging/media/ipu3/Kconfig" 44 44 45 - source "drivers/staging/media/phy-rockchip-dphy-rx0/Kconfig" 46 - 47 45 source "drivers/staging/media/rkisp1/Kconfig" 48 46 49 47 if MEDIA_ANALOG_TV_SUPPORT
-1
drivers/staging/media/Makefile
··· 10 10 obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ 11 11 obj-$(CONFIG_VIDEO_HANTRO) += hantro/ 12 12 obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ 13 - obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0/ 14 13 obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/ 15 14 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
-13
drivers/staging/media/phy-rockchip-dphy-rx0/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - 3 - config PHY_ROCKCHIP_DPHY_RX0 4 - tristate "Rockchip MIPI Synopsys DPHY RX0 driver" 5 - depends on ARCH_ROCKCHIP || COMPILE_TEST 6 - select GENERIC_PHY_MIPI_DPHY 7 - select GENERIC_PHY 8 - help 9 - Enable this to support the Rockchip MIPI Synopsys DPHY RX0 10 - associated to the Rockchip ISP module present in RK3399 SoCs. 11 - 12 - To compile this driver as a module, choose M here: the module 13 - will be called phy-rockchip-dphy-rx0.
-2
drivers/staging/media/phy-rockchip-dphy-rx0/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0.o
-6
drivers/staging/media/phy-rockchip-dphy-rx0/TODO
··· 1 - The main reason for keeping this in staging is because the only driver 2 - that uses this is rkisp1, which is also in staging. It should be moved together 3 - with rkisp1. 4 - 5 - Please CC patches to Linux Media <linux-media@vger.kernel.org> and 6 - Helen Koike <helen.koike@collabora.com>.
+1
drivers/staging/media/phy-rockchip-dphy-rx0/phy-rockchip-dphy-rx0.c drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
··· 16 16 */ 17 17 18 18 #include <linux/clk.h> 19 + #include <linux/delay.h> 19 20 #include <linux/io.h> 20 21 #include <linux/mfd/syscon.h> 21 22 #include <linux/module.h>
+13
include/dt-bindings/phy/phy-cadence-torrent.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * This header provides constants for Cadence Torrent SERDES. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_TORRENT_SERDES_H 7 + #define _DT_BINDINGS_TORRENT_SERDES_H 8 + 9 + #define TORRENT_SERDES_NO_SSC 0 10 + #define TORRENT_SERDES_EXTERNAL_SSC 1 11 + #define TORRENT_SERDES_INTERNAL_SSC 2 12 + 13 + #endif /* _DT_BINDINGS_TORRENT_SERDES_H */
+1
include/dt-bindings/phy/phy.h
··· 19 19 #define PHY_TYPE_DP 6 20 20 #define PHY_TYPE_XPCS 7 21 21 #define PHY_TYPE_SGMII 8 22 + #define PHY_TYPE_QSGMII 9 22 23 23 24 #endif /* _DT_BINDINGS_PHY */
+2
include/linux/phy/phy.h
··· 115 115 /** 116 116 * struct phy_attrs - represents phy attributes 117 117 * @bus_width: Data path width implemented by PHY 118 + * @max_link_rate: Maximum link rate supported by PHY (in Mbps) 118 119 * @mode: PHY mode 119 120 */ 120 121 struct phy_attrs { 121 122 u32 bus_width; 123 + u32 max_link_rate; 122 124 enum phy_mode mode; 123 125 }; 124 126