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

Merge tag 'usb-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB/PHY driver updates from Greg KH:
"Here are the large set of USB and PHY driver updates for 5.8-rc1.

Nothing huge, just lots of little things:

- USB gadget fixes and additions all over the place

- new PHY drivers

- PHY driver fixes and updates

- XHCI driver updates

- musb driver updates

- more USB-serial driver ids added

- various USB quirks added

- thunderbolt minor updates and fixes

- typec updates and additions

All of these have been in linux-next for a while with no reported
issues"

* tag 'usb-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (245 commits)
usb: dwc3: meson-g12a: fix USB2 PHY initialization on G12A and A1 SoCs
usb: dwc3: meson-g12a: fix error path when fetching the reset line fails
Revert "dt-bindings: usb: qcom,dwc3: Convert USB DWC3 bindings"
Revert "dt-bindings: usb: qcom,dwc3: Add compatible for SC7180"
Revert "dt-bindings: usb: qcom,dwc3: Introduce interconnect properties for Qualcomm DWC3 driver"
USB: serial: ch341: fix lockup of devices with limited prescaler
USB: serial: ch341: add basis for quirk detection
CDC-ACM: heed quirk also in error handling
USB: serial: option: add Telit LE910C1-EUX compositions
usb: musb: Fix runtime PM imbalance on error
usb: musb: jz4740: Prevent lockup when CONFIG_SMP is set
usb: musb: mediatek: add reset FADDR to zero in reset interrupt handle
usb: musb: use true for 'use_dma'
usb: musb: start session in resume for host port
usb: musb: return -ESHUTDOWN in urb when three-strikes error happened
USB: serial: qcserial: add DW5816e QDL support
thunderbolt: Add trivial .shutdown
usb: dwc3: keystone: Turn on USB3 PHY before controller
dt-bindings: usb: ti,keystone-dwc3.yaml: Add USB3.0 PHY property
dt-bindings: usb: convert keystone-usb.txt to YAML
...

+7743 -2673
+64
Documentation/devicetree/bindings/phy/amlogic,meson8b-usb2-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/phy/amlogic,meson8b-usb2-phy.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Amlogic Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY 8 + 9 + maintainers: 10 + - Martin Blumenstingl <martin.blumenstingl@googlemail.com> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - items: 16 + - enum: 17 + - amlogic,meson8-usb2-phy 18 + - amlogic,meson8b-usb2-phy 19 + - amlogic,meson8m2-usb2-phy 20 + - const: amlogic,meson-mx-usb2-phy 21 + - const: amlogic,meson-gxbb-usb2-phy 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + clocks: 27 + minItems: 2 28 + 29 + clock-names: 30 + items: 31 + - const: usb_general 32 + - const: usb 33 + 34 + resets: 35 + minItems: 1 36 + 37 + "#phy-cells": 38 + const: 0 39 + 40 + phy-supply: 41 + description: 42 + Phandle to a regulator that provides power to the PHY. This 43 + regulator will be managed during the PHY power on/off sequence. 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - clocks 49 + - clock-names 50 + - "#phy-cells" 51 + 52 + additionalProperties: false 53 + 54 + examples: 55 + - | 56 + usb-phy@c0000000 { 57 + compatible = "amlogic,meson-gxbb-usb2-phy"; 58 + reg = <0xc0000000 0x20>; 59 + resets = <&reset_usb_phy>; 60 + clocks = <&clk_usb_general>, <&reset_usb>; 61 + clock-names = "usb_general", "usb"; 62 + phy-supply = <&usb_vbus>; 63 + #phy-cells = <0>; 64 + };
+52
Documentation/devicetree/bindings/phy/cdns,salvo-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright (c) 2020 NXP 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/phy/cdns,salvo-phy.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Cadence SALVO PHY 9 + 10 + maintainers: 11 + - Peter Chen <peter.chen@nxp.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - nxp,salvo-phy 17 + 18 + reg: 19 + maxItems: 1 20 + 21 + clocks: 22 + maxItems: 1 23 + 24 + clock-names: 25 + items: 26 + - const: salvo_phy_clk 27 + 28 + power-domains: 29 + maxItems: 1 30 + 31 + "#phy-cells": 32 + const: 0 33 + 34 + required: 35 + - compatible 36 + - reg 37 + - "#phy-cells" 38 + 39 + additionalProperties: false 40 + 41 + examples: 42 + - | 43 + #include <dt-bindings/firmware/imx/rsrc.h> 44 + 45 + usb3phy: usb3-phy@5b160000 { 46 + compatible = "nxp,salvo-phy"; 47 + reg = <0x5b160000 0x40000>; 48 + clocks = <&usb3_lpcg 4>; 49 + clock-names = "salvo_phy_clk"; 50 + power-domains = <&pd IMX_SC_R_USB_2_PHY>; 51 + #phy-cells = <0>; 52 + };
+101
Documentation/devicetree/bindings/phy/intel,combo-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,combo-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intel ComboPhy Subsystem 8 + 9 + maintainers: 10 + - Dilip Kota <eswara.kota@linux.intel.com> 11 + 12 + description: | 13 + Intel Combophy subsystem supports PHYs for PCIe, EMAC and SATA 14 + controllers. A single Combophy provides two PHY instances. 15 + 16 + properties: 17 + $nodename: 18 + pattern: "combophy(@.*|-[0-9a-f])*$" 19 + 20 + compatible: 21 + items: 22 + - const: intel,combophy-lgm 23 + - const: intel,combo-phy 24 + 25 + clocks: 26 + maxItems: 1 27 + 28 + reg: 29 + items: 30 + - description: ComboPhy core registers 31 + - description: PCIe app core control registers 32 + 33 + reg-names: 34 + items: 35 + - const: core 36 + - const: app 37 + 38 + resets: 39 + maxItems: 4 40 + 41 + reset-names: 42 + items: 43 + - const: phy 44 + - const: core 45 + - const: iphy0 46 + - const: iphy1 47 + 48 + intel,syscfg: 49 + $ref: /schemas/types.yaml#/definitions/phandle-array 50 + description: Chip configuration registers handle and ComboPhy instance id 51 + 52 + intel,hsio: 53 + $ref: /schemas/types.yaml#/definitions/phandle-array 54 + description: HSIO registers handle and ComboPhy instance id on NOC 55 + 56 + intel,aggregation: 57 + type: boolean 58 + description: | 59 + Specify the flag to configure ComboPHY in dual lane mode. 60 + 61 + intel,phy-mode: 62 + $ref: /schemas/types.yaml#/definitions/uint32 63 + description: | 64 + Mode of the two phys in ComboPhy. 65 + See dt-bindings/phy/phy.h for values. 66 + 67 + "#phy-cells": 68 + const: 1 69 + 70 + required: 71 + - compatible 72 + - clocks 73 + - reg 74 + - reg-names 75 + - intel,syscfg 76 + - intel,hsio 77 + - intel,phy-mode 78 + - "#phy-cells" 79 + 80 + additionalProperties: false 81 + 82 + examples: 83 + - | 84 + #include <dt-bindings/phy/phy.h> 85 + combophy@d0a00000 { 86 + compatible = "intel,combophy-lgm", "intel,combo-phy"; 87 + clocks = <&cgu0 1>; 88 + #phy-cells = <1>; 89 + reg = <0xd0a00000 0x40000>, 90 + <0xd0a40000 0x1000>; 91 + reg-names = "core", "app"; 92 + resets = <&rcu0 0x50 6>, 93 + <&rcu0 0x50 17>, 94 + <&rcu0 0x50 23>, 95 + <&rcu0 0x50 24>; 96 + reset-names = "phy", "core", "iphy0", "iphy1"; 97 + intel,syscfg = <&sysconf 0>; 98 + intel,hsio = <&hsiol 0>; 99 + intel,phy-mode = <PHY_TYPE_PCIE>; 100 + intel,aggregation; 101 + };
-31
Documentation/devicetree/bindings/phy/meson-gxl-usb3-phy.txt
··· 1 - * Amlogic Meson GXL and GXM USB3 PHY and OTG detection binding 2 - 3 - Required properties: 4 - - compatible: Should be "amlogic,meson-gxl-usb3-phy" 5 - - #phys-cells: must be 0 (see phy-bindings.txt in this directory) 6 - - reg: The base address and length of the registers 7 - - interrupts: the interrupt specifier for the OTG detection 8 - - clocks: phandles to the clocks for 9 - - the USB3 PHY 10 - - and peripheral mode/OTG detection 11 - - clock-names: must contain "phy" and "peripheral" 12 - - resets: phandle to the reset lines for: 13 - - the USB3 PHY and 14 - - peripheral mode/OTG detection 15 - - reset-names: must contain "phy" and "peripheral" 16 - 17 - Optional properties: 18 - - phy-supply: see phy-bindings.txt in this directory 19 - 20 - 21 - Example: 22 - usb3_phy0: phy@78080 { 23 - compatible = "amlogic,meson-gxl-usb3-phy"; 24 - #phy-cells = <0>; 25 - reg = <0x0 0x78080 0x0 0x20>; 26 - interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; 27 - clocks = <&clkc CLKID_USB_OTG>, <&clkc_AO CLKID_AO_CEC_32K>; 28 - clock-names = "phy", "peripheral"; 29 - resets = <&reset RESET_USB_OTG>, <&reset RESET_USB_OTG>; 30 - reset-names = "phy", "peripheral"; 31 - };
-28
Documentation/devicetree/bindings/phy/meson8b-usb2-phy.txt
··· 1 - * Amlogic Meson8, Meson8b and GXBB USB2 PHY 2 - 3 - Required properties: 4 - - compatible: Depending on the platform this should be one of: 5 - "amlogic,meson8-usb2-phy" 6 - "amlogic,meson8b-usb2-phy" 7 - "amlogic,meson-gxbb-usb2-phy" 8 - - reg: The base address and length of the registers 9 - - #phys-cells: should be 0 (see phy-bindings.txt in this directory) 10 - - clocks: phandle and clock identifier for the phy clocks 11 - - clock-names: "usb_general" and "usb" 12 - 13 - Optional properties: 14 - - resets: reference to the reset controller 15 - - phy-supply: see phy-bindings.txt in this directory 16 - 17 - 18 - Example: 19 - 20 - usb0_phy: usb-phy@c0000000 { 21 - compatible = "amlogic,meson-gxbb-usb2-phy"; 22 - #phy-cells = <0>; 23 - reg = <0x0 0xc0000000 0x0 0x20>; 24 - resets = <&reset RESET_USB_OTG>; 25 - clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>; 26 - clock-names = "usb_general", "usb"; 27 - phy-supply = <&usb_vbus>; 28 - };
+313
Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/phy/qcom,qmp-phy.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Qualcomm QMP PHY controller 9 + 10 + maintainers: 11 + - Manu Gautam <mgautam@codeaurora.org> 12 + 13 + description: 14 + QMP phy controller supports physical layer functionality for a number of 15 + controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - qcom,ipq8074-qmp-pcie-phy 21 + - qcom,msm8996-qmp-pcie-phy 22 + - qcom,msm8996-qmp-ufs-phy 23 + - qcom,msm8996-qmp-usb3-phy 24 + - qcom,msm8998-qmp-pcie-phy 25 + - qcom,msm8998-qmp-ufs-phy 26 + - qcom,msm8998-qmp-usb3-phy 27 + - qcom,sdm845-qhp-pcie-phy 28 + - qcom,sdm845-qmp-pcie-phy 29 + - qcom,sdm845-qmp-ufs-phy 30 + - qcom,sdm845-qmp-usb3-uni-phy 31 + - qcom,sm8150-qmp-ufs-phy 32 + - qcom,sm8250-qmp-ufs-phy 33 + 34 + reg: 35 + items: 36 + - description: Address and length of PHY's common serdes block. 37 + 38 + "#clock-cells": 39 + enum: [ 1, 2 ] 40 + 41 + "#address-cells": 42 + enum: [ 1, 2 ] 43 + 44 + "#size-cells": 45 + enum: [ 1, 2 ] 46 + 47 + clocks: 48 + minItems: 1 49 + maxItems: 4 50 + 51 + clock-names: 52 + minItems: 1 53 + maxItems: 4 54 + 55 + resets: 56 + minItems: 1 57 + maxItems: 3 58 + 59 + reset-names: 60 + minItems: 1 61 + maxItems: 3 62 + 63 + vdda-phy-supply: 64 + description: 65 + Phandle to a regulator supply to PHY core block. 66 + 67 + vdda-pll-supply: 68 + description: 69 + Phandle to 1.8V regulator supply to PHY refclk pll block. 70 + 71 + vddp-ref-clk-supply: 72 + description: 73 + Phandle to a regulator supply to any specific refclk 74 + pll block. 75 + 76 + #Required nodes: 77 + patternProperties: 78 + "^phy@[0-9a-f]+$": 79 + type: object 80 + description: 81 + Each device node of QMP phy is required to have as many child nodes as 82 + the number of lanes the PHY has. 83 + 84 + required: 85 + - compatible 86 + - reg 87 + - "#clock-cells" 88 + - "#address-cells" 89 + - "#size-cells" 90 + - clocks 91 + - clock-names 92 + - resets 93 + - reset-names 94 + - vdda-phy-supply 95 + - vdda-pll-supply 96 + 97 + additionalProperties: false 98 + 99 + allOf: 100 + - if: 101 + properties: 102 + compatible: 103 + contains: 104 + enum: 105 + - qcom,sdm845-qmp-usb3-uni-phy 106 + then: 107 + properties: 108 + clocks: 109 + items: 110 + - description: Phy aux clock. 111 + - description: Phy config clock. 112 + - description: 19.2 MHz ref clk. 113 + - description: Phy common block aux clock. 114 + clock-names: 115 + items: 116 + - const: aux 117 + - const: cfg_ahb 118 + - const: ref 119 + - const: com_aux 120 + resets: 121 + items: 122 + - description: reset of phy block. 123 + - description: phy common block reset. 124 + reset-names: 125 + items: 126 + - const: phy 127 + - const: common 128 + - if: 129 + properties: 130 + compatible: 131 + contains: 132 + enum: 133 + - qcom,msm8996-qmp-pcie-phy 134 + then: 135 + properties: 136 + clocks: 137 + items: 138 + - description: Phy aux clock. 139 + - description: Phy config clock. 140 + - description: 19.2 MHz ref clk. 141 + clock-names: 142 + items: 143 + - const: aux 144 + - const: cfg_ahb 145 + - const: ref 146 + resets: 147 + items: 148 + - description: reset of phy block. 149 + - description: phy common block reset. 150 + - description: phy's ahb cfg block reset. 151 + reset-names: 152 + items: 153 + - const: phy 154 + - const: common 155 + - const: cfg 156 + - if: 157 + properties: 158 + compatible: 159 + contains: 160 + enum: 161 + - qcom,msm8996-qmp-usb3-phy 162 + - qcom,msm8998-qmp-pcie-phy 163 + - qcom,msm8998-qmp-usb3-phy 164 + then: 165 + properties: 166 + clocks: 167 + items: 168 + - description: Phy aux clock. 169 + - description: Phy config clock. 170 + - description: 19.2 MHz ref clk. 171 + clock-names: 172 + items: 173 + - const: aux 174 + - const: cfg_ahb 175 + - const: ref 176 + resets: 177 + items: 178 + - description: reset of phy block. 179 + - description: phy common block reset. 180 + reset-names: 181 + items: 182 + - const: phy 183 + - const: common 184 + - if: 185 + properties: 186 + compatible: 187 + contains: 188 + enum: 189 + - qcom,msm8996-qmp-ufs-phy 190 + then: 191 + properties: 192 + clocks: 193 + items: 194 + - description: 19.2 MHz ref clk. 195 + clock-names: 196 + items: 197 + - const: ref 198 + resets: 199 + items: 200 + - description: PHY reset in the UFS controller. 201 + reset-names: 202 + items: 203 + - const: ufsphy 204 + - if: 205 + properties: 206 + compatible: 207 + contains: 208 + enum: 209 + - qcom,msm8998-qmp-ufs-phy 210 + - qcom,sdm845-qmp-ufs-phy 211 + - qcom,sm8150-qmp-ufs-phy 212 + - qcom,sm8250-qmp-ufs-phy 213 + then: 214 + properties: 215 + clocks: 216 + items: 217 + - description: 19.2 MHz ref clk. 218 + - description: Phy reference aux clock. 219 + clock-names: 220 + items: 221 + - const: ref 222 + - const: ref_aux 223 + resets: 224 + items: 225 + - description: PHY reset in the UFS controller. 226 + reset-names: 227 + items: 228 + - const: ufsphy 229 + - if: 230 + properties: 231 + compatible: 232 + contains: 233 + enum: 234 + - qcom,ipq8074-qmp-pcie-phy 235 + then: 236 + properties: 237 + clocks: 238 + items: 239 + - description: pipe clk. 240 + clock-names: 241 + items: 242 + - const: pipe_clk 243 + resets: 244 + items: 245 + - description: reset of phy block. 246 + - description: phy common block reset. 247 + reset-names: 248 + items: 249 + - const: phy 250 + - const: common 251 + - if: 252 + properties: 253 + compatible: 254 + contains: 255 + enum: 256 + - qcom,sdm845-qhp-pcie-phy 257 + - qcom,sdm845-qmp-pcie-phy 258 + then: 259 + properties: 260 + clocks: 261 + items: 262 + - description: Phy aux clock. 263 + - description: Phy config clock. 264 + - description: 19.2 MHz ref clk. 265 + - description: Phy refgen clk. 266 + clock-names: 267 + items: 268 + - const: aux 269 + - const: cfg_ahb 270 + - const: ref 271 + - const: refgen 272 + resets: 273 + items: 274 + - description: reset of phy block. 275 + reset-names: 276 + items: 277 + - const: phy 278 + 279 + examples: 280 + - | 281 + #include <dt-bindings/clock/qcom,gcc-sdm845.h> 282 + usb_2_qmpphy: phy-wrapper@88eb000 { 283 + compatible = "qcom,sdm845-qmp-usb3-uni-phy"; 284 + reg = <0 0x088eb000 0 0x18c>; 285 + #clock-cells = <1>; 286 + #address-cells = <2>; 287 + #size-cells = <2>; 288 + 289 + clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK >, 290 + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, 291 + <&gcc GCC_USB3_SEC_CLKREF_CLK>, 292 + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; 293 + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; 294 + 295 + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, 296 + <&gcc GCC_USB3_PHY_SEC_BCR>; 297 + reset-names = "phy", "common"; 298 + 299 + vdda-phy-supply = <&vdda_usb2_ss_1p2>; 300 + vdda-pll-supply = <&vdda_usb2_ss_core>; 301 + 302 + usb_2_ssphy: phy@88eb200 { 303 + reg = <0 0x088eb200 0 0x128>, 304 + <0 0x088eb400 0 0x1fc>, 305 + <0 0x088eb800 0 0x218>, 306 + <0 0x088eb600 0 0x70>; 307 + #clock-cells = <0>; 308 + #phy-cells = <0>; 309 + clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; 310 + clock-names = "pipe0"; 311 + clock-output-names = "usb3_uni_phy_pipe_clk_src"; 312 + }; 313 + };
+136
Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + 3 + %YAML 1.2 4 + --- 5 + $id: "http://devicetree.org/schemas/phy/qcom,qmp-usb3-dp-phy.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Qualcomm QMP USB3 DP PHY controller 9 + 10 + maintainers: 11 + - Manu Gautam <mgautam@codeaurora.org> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - qcom,sc7180-qmp-usb3-phy 17 + - qcom,sdm845-qmp-usb3-phy 18 + reg: 19 + items: 20 + - description: Address and length of PHY's common serdes block. 21 + - description: Address and length of the DP_COM control block. 22 + 23 + reg-names: 24 + items: 25 + - const: reg-base 26 + - const: dp_com 27 + 28 + "#clock-cells": 29 + enum: [ 1, 2 ] 30 + 31 + "#address-cells": 32 + enum: [ 1, 2 ] 33 + 34 + "#size-cells": 35 + enum: [ 1, 2 ] 36 + 37 + clocks: 38 + items: 39 + - description: Phy aux clock. 40 + - description: Phy config clock. 41 + - description: 19.2 MHz ref clk. 42 + - description: Phy common block aux clock. 43 + 44 + clock-names: 45 + items: 46 + - const: aux 47 + - const: cfg_ahb 48 + - const: ref 49 + - const: com_aux 50 + 51 + resets: 52 + items: 53 + - description: reset of phy block. 54 + - description: phy common block reset. 55 + 56 + reset-names: 57 + items: 58 + - const: phy 59 + - const: common 60 + 61 + vdda-phy-supply: 62 + description: 63 + Phandle to a regulator supply to PHY core block. 64 + 65 + vdda-pll-supply: 66 + description: 67 + Phandle to 1.8V regulator supply to PHY refclk pll block. 68 + 69 + vddp-ref-clk-supply: 70 + description: 71 + Phandle to a regulator supply to any specific refclk 72 + pll block. 73 + 74 + #Required nodes: 75 + patternProperties: 76 + "^phy@[0-9a-f]+$": 77 + type: object 78 + description: 79 + Each device node of QMP phy is required to have as many child nodes as 80 + the number of lanes the PHY has. 81 + 82 + required: 83 + - compatible 84 + - reg 85 + - reg-names 86 + - "#clock-cells" 87 + - "#address-cells" 88 + - "#size-cells" 89 + - clocks 90 + - clock-names 91 + - resets 92 + - reset-names 93 + - vdda-phy-supply 94 + - vdda-pll-supply 95 + 96 + additionalProperties: false 97 + 98 + examples: 99 + - | 100 + #include <dt-bindings/clock/qcom,gcc-sdm845.h> 101 + usb_1_qmpphy: phy-wrapper@88e9000 { 102 + compatible = "qcom,sdm845-qmp-usb3-phy"; 103 + reg = <0 0x088e9000 0 0x18c>, 104 + <0 0x088e8000 0 0x10>; 105 + reg-names = "reg-base", "dp_com"; 106 + #clock-cells = <1>; 107 + #address-cells = <2>; 108 + #size-cells = <2>; 109 + 110 + clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, 111 + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, 112 + <&gcc GCC_USB3_PRIM_CLKREF_CLK>, 113 + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; 114 + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; 115 + 116 + resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, 117 + <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; 118 + reset-names = "phy", "common"; 119 + 120 + vdda-phy-supply = <&vdda_usb2_ss_1p2>; 121 + vdda-pll-supply = <&vdda_usb2_ss_core>; 122 + 123 + usb_1_ssphy: phy@88e9200 { 124 + reg = <0 0x088e9200 0 0x128>, 125 + <0 0x088e9400 0 0x200>, 126 + <0 0x088e9c00 0 0x218>, 127 + <0 0x088e9600 0 0x128>, 128 + <0 0x088e9800 0 0x200>, 129 + <0 0x088e9a00 0 0x100>; 130 + #clock-cells = <0>; 131 + #phy-cells = <0>; 132 + clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; 133 + clock-names = "pipe0"; 134 + clock-output-names = "usb3_phy_pipe_clk_src"; 135 + }; 136 + };
+80
Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.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/qcom,usb-snps-femto-v2.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Qualcomm Synopsys Femto High-Speed USB PHY V2 8 + 9 + maintainers: 10 + - Wesley Cheng <wcheng@codeaurora.org> 11 + 12 + description: | 13 + Qualcomm High-Speed USB PHY 14 + 15 + properties: 16 + compatible: 17 + enum: 18 + - qcom,usb-snps-hs-7nm-phy 19 + - qcom,sm8150-usb-hs-phy 20 + - qcom,usb-snps-femto-v2-phy 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + "#phy-cells": 26 + const: 0 27 + 28 + clocks: 29 + items: 30 + - description: rpmhcc ref clock 31 + 32 + clock-names: 33 + items: 34 + - const: ref 35 + 36 + resets: 37 + items: 38 + - description: PHY core reset 39 + 40 + vdda-pll-supply: 41 + description: phandle to the regulator VDD supply node. 42 + 43 + vdda18-supply: 44 + description: phandle to the regulator 1.8V supply node. 45 + 46 + vdda33-supply: 47 + description: phandle to the regulator 3.3V supply node. 48 + 49 + required: 50 + - compatible 51 + - reg 52 + - "#phy-cells" 53 + - clocks 54 + - clock-names 55 + - resets 56 + - vdda-pll-supply 57 + - vdda18-supply 58 + - vdda33-supply 59 + 60 + additionalProperties: false 61 + 62 + examples: 63 + - | 64 + #include <dt-bindings/clock/qcom,rpmh.h> 65 + #include <dt-bindings/clock/qcom,gcc-sm8150.h> 66 + phy@88e2000 { 67 + compatible = "qcom,sm8150-usb-hs-phy"; 68 + reg = <0 0x088e2000 0 0x400>; 69 + #phy-cells = <0>; 70 + 71 + clocks = <&rpmhcc RPMH_CXO_CLK>; 72 + clock-names = "ref"; 73 + 74 + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; 75 + 76 + vdda-pll-supply = <&vdd_usb_hs_core>; 77 + vdda33-supply = <&vdda_usb_hs_3p1>; 78 + vdda18-supply = <&vdda_usb_hs_1p8>; 79 + }; 80 + ...
-242
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
··· 1 - Qualcomm QMP PHY controller 2 - =========================== 3 - 4 - QMP phy controller supports physical layer functionality for a number of 5 - controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB. 6 - 7 - Required properties: 8 - - compatible: compatible list, contains: 9 - "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074 10 - "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996, 11 - "qcom,msm8996-qmp-ufs-phy" for 14nm UFS phy on msm8996, 12 - "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996, 13 - "qcom,msm8998-qmp-usb3-phy" for USB3 QMP V3 phy on msm8998, 14 - "qcom,msm8998-qmp-ufs-phy" for UFS QMP phy on msm8998, 15 - "qcom,msm8998-qmp-pcie-phy" for PCIe QMP phy on msm8998, 16 - "qcom,sdm845-qhp-pcie-phy" for QHP PCIe phy on sdm845, 17 - "qcom,sdm845-qmp-pcie-phy" for QMP PCIe phy on sdm845, 18 - "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, 19 - "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845, 20 - "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845, 21 - "qcom,sm8150-qmp-ufs-phy" for UFS QMP phy on sm8150. 22 - 23 - - reg: 24 - - index 0: address and length of register set for PHY's common 25 - serdes block. 26 - - index 1: address and length of the DP_COM control block (for 27 - "qcom,sdm845-qmp-usb3-phy" only). 28 - 29 - - reg-names: 30 - - For "qcom,sdm845-qmp-usb3-phy": 31 - - Should be: "reg-base", "dp_com" 32 - - For all others: 33 - - The reg-names property shouldn't be defined. 34 - 35 - - #address-cells: must be 1 36 - - #size-cells: must be 1 37 - - ranges: must be present 38 - 39 - - clocks: a list of phandles and clock-specifier pairs, 40 - one for each entry in clock-names. 41 - - clock-names: "cfg_ahb" for phy config clock, 42 - "aux" for phy aux clock, 43 - "ref" for 19.2 MHz ref clk, 44 - "com_aux" for phy common block aux clock, 45 - "ref_aux" for phy reference aux clock, 46 - 47 - For "qcom,ipq8074-qmp-pcie-phy": no clocks are listed. 48 - For "qcom,msm8996-qmp-pcie-phy" must contain: 49 - "aux", "cfg_ahb", "ref". 50 - For "qcom,msm8996-qmp-ufs-phy" must contain: 51 - "ref". 52 - For "qcom,msm8996-qmp-usb3-phy" must contain: 53 - "aux", "cfg_ahb", "ref". 54 - For "qcom,msm8998-qmp-usb3-phy" must contain: 55 - "aux", "cfg_ahb", "ref". 56 - For "qcom,msm8998-qmp-ufs-phy" must contain: 57 - "ref", "ref_aux". 58 - For "qcom,msm8998-qmp-pcie-phy" must contain: 59 - "aux", "cfg_ahb", "ref". 60 - For "qcom,sdm845-qhp-pcie-phy" must contain: 61 - "aux", "cfg_ahb", "ref", "refgen". 62 - For "qcom,sdm845-qmp-pcie-phy" must contain: 63 - "aux", "cfg_ahb", "ref", "refgen". 64 - For "qcom,sdm845-qmp-usb3-phy" must contain: 65 - "aux", "cfg_ahb", "ref", "com_aux". 66 - For "qcom,sdm845-qmp-usb3-uni-phy" must contain: 67 - "aux", "cfg_ahb", "ref", "com_aux". 68 - For "qcom,sdm845-qmp-ufs-phy" must contain: 69 - "ref", "ref_aux". 70 - For "qcom,sm8150-qmp-ufs-phy" must contain: 71 - "ref", "ref_aux". 72 - 73 - - resets: a list of phandles and reset controller specifier pairs, 74 - one for each entry in reset-names. 75 - - reset-names: "phy" for reset of phy block, 76 - "common" for phy common block reset, 77 - "cfg" for phy's ahb cfg block reset, 78 - "ufsphy" for the PHY reset in the UFS controller. 79 - 80 - For "qcom,ipq8074-qmp-pcie-phy" must contain: 81 - "phy", "common". 82 - For "qcom,msm8996-qmp-pcie-phy" must contain: 83 - "phy", "common", "cfg". 84 - For "qcom,msm8996-qmp-ufs-phy": must contain: 85 - "ufsphy". 86 - For "qcom,msm8996-qmp-usb3-phy" must contain 87 - "phy", "common". 88 - For "qcom,msm8998-qmp-usb3-phy" must contain 89 - "phy", "common". 90 - For "qcom,msm8998-qmp-ufs-phy": must contain: 91 - "ufsphy". 92 - For "qcom,msm8998-qmp-pcie-phy" must contain: 93 - "phy", "common". 94 - For "qcom,sdm845-qhp-pcie-phy" must contain: 95 - "phy". 96 - For "qcom,sdm845-qmp-pcie-phy" must contain: 97 - "phy". 98 - For "qcom,sdm845-qmp-usb3-phy" must contain: 99 - "phy", "common". 100 - For "qcom,sdm845-qmp-usb3-uni-phy" must contain: 101 - "phy", "common". 102 - For "qcom,sdm845-qmp-ufs-phy": must contain: 103 - "ufsphy". 104 - For "qcom,sm8150-qmp-ufs-phy": must contain: 105 - "ufsphy". 106 - 107 - - vdda-phy-supply: Phandle to a regulator supply to PHY core block. 108 - - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block. 109 - 110 - Optional properties: 111 - - vddp-ref-clk-supply: Phandle to a regulator supply to any specific refclk 112 - pll block. 113 - 114 - Required nodes: 115 - - Each device node of QMP phy is required to have as many child nodes as 116 - the number of lanes the PHY has. 117 - 118 - Required properties for child nodes of PCIe PHYs (one child per lane): 119 - - reg: list of offset and length pairs of register sets for PHY blocks - 120 - tx, rx, pcs, and pcs_misc (optional). 121 - - #phy-cells: must be 0 122 - 123 - Required properties for a single "lanes" child node of non-PCIe PHYs: 124 - - reg: list of offset and length pairs of register sets for PHY blocks 125 - For 1-lane devices: 126 - tx, rx, pcs, and (optionally) pcs_misc 127 - For 2-lane devices: 128 - tx0, rx0, pcs, tx1, rx1, and (optionally) pcs_misc 129 - - #phy-cells: must be 0 130 - 131 - Required properties for child node of PCIe and USB3 qmp phys: 132 - - clocks: a list of phandles and clock-specifier pairs, 133 - one for each entry in clock-names. 134 - - clock-names: Must contain following: 135 - "pipe<lane-number>" for pipe clock specific to each lane. 136 - - clock-output-names: Name of the PHY clock that will be the parent for 137 - the above pipe clock. 138 - For "qcom,ipq8074-qmp-pcie-phy": 139 - - "pcie20_phy0_pipe_clk" Pipe Clock parent 140 - (or) 141 - "pcie20_phy1_pipe_clk" 142 - - #clock-cells: must be 0 143 - - Phy pll outputs pipe clocks for pipe based PHYs. These clocks are then 144 - gate-controlled by the gcc. 145 - 146 - Required properties for child node of PHYs with lane reset, AKA: 147 - "qcom,msm8996-qmp-pcie-phy" 148 - - resets: a list of phandles and reset controller specifier pairs, 149 - one for each entry in reset-names. 150 - - reset-names: Must contain following: 151 - "lane<lane-number>" for reset specific to each lane. 152 - 153 - Example: 154 - phy@34000 { 155 - compatible = "qcom,msm8996-qmp-pcie-phy"; 156 - reg = <0x34000 0x488>; 157 - #address-cells = <1>; 158 - #size-cells = <1>; 159 - ranges; 160 - 161 - clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, 162 - <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>, 163 - <&gcc GCC_PCIE_CLKREF_CLK>; 164 - clock-names = "aux", "cfg_ahb", "ref"; 165 - 166 - vdda-phy-supply = <&pm8994_l28>; 167 - vdda-pll-supply = <&pm8994_l12>; 168 - 169 - resets = <&gcc GCC_PCIE_PHY_BCR>, 170 - <&gcc GCC_PCIE_PHY_COM_BCR>, 171 - <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>; 172 - reset-names = "phy", "common", "cfg"; 173 - 174 - pciephy_0: lane@35000 { 175 - reg = <0x35000 0x130>, 176 - <0x35200 0x200>, 177 - <0x35400 0x1dc>; 178 - #clock-cells = <0>; 179 - #phy-cells = <0>; 180 - 181 - clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; 182 - clock-names = "pipe0"; 183 - clock-output-names = "pcie_0_pipe_clk_src"; 184 - resets = <&gcc GCC_PCIE_0_PHY_BCR>; 185 - reset-names = "lane0"; 186 - }; 187 - 188 - pciephy_1: lane@36000 { 189 - ... 190 - ... 191 - }; 192 - 193 - phy@88eb000 { 194 - compatible = "qcom,sdm845-qmp-usb3-uni-phy"; 195 - reg = <0x88eb000 0x18c>; 196 - #address-cells = <1>; 197 - #size-cells = <1>; 198 - ranges; 199 - 200 - clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, 201 - <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, 202 - <&gcc GCC_USB3_SEC_CLKREF_CLK>, 203 - <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; 204 - clock-names = "aux", "cfg_ahb", "ref", "com_aux"; 205 - 206 - resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, 207 - <&gcc GCC_USB3_PHY_SEC_BCR>; 208 - reset-names = "phy", "common"; 209 - 210 - lane@88eb200 { 211 - reg = <0x88eb200 0x128>, 212 - <0x88eb400 0x1fc>, 213 - <0x88eb800 0x218>, 214 - <0x88eb600 0x70>; 215 - #clock-cells = <0>; 216 - #phy-cells = <0>; 217 - clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; 218 - clock-names = "pipe0"; 219 - clock-output-names = "usb3_uni_phy_pipe_clk_src"; 220 - }; 221 - }; 222 - 223 - phy@1d87000 { 224 - compatible = "qcom,sdm845-qmp-ufs-phy"; 225 - reg = <0x1d87000 0x18c>; 226 - #address-cells = <1>; 227 - #size-cells = <1>; 228 - ranges; 229 - clock-names = "ref", 230 - "ref_aux"; 231 - clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, 232 - <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; 233 - 234 - lanes@1d87400 { 235 - reg = <0x1d87400 0x108>, 236 - <0x1d87600 0x1e0>, 237 - <0x1d87c00 0x1dc>, 238 - <0x1d87800 0x108>, 239 - <0x1d87a00 0x1e0>; 240 - #phy-cells = <0>; 241 - }; 242 - };
+50
Documentation/devicetree/bindings/phy/qcom-usb-ipq4019-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/phy/qcom-usb-ipq4019-phy.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Qualcom IPQ40xx Dakota HS/SS USB PHY 8 + 9 + maintainers: 10 + - Robert Marko <robert.marko@sartura.hr> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - qcom,usb-ss-ipq4019-phy 16 + - qcom,usb-hs-ipq4019-phy 17 + 18 + reg: 19 + maxItems: 1 20 + 21 + resets: 22 + maxItems: 2 23 + 24 + reset-names: 25 + items: 26 + - const: por_rst 27 + - const: srif_rst 28 + 29 + "#phy-cells": 30 + const: 0 31 + 32 + required: 33 + - compatible 34 + - reg 35 + - resets 36 + - reset-names 37 + - "#phy-cells" 38 + 39 + examples: 40 + - | 41 + #include <dt-bindings/clock/qcom,gcc-ipq4019.h> 42 + 43 + hsphy@a8000 { 44 + #phy-cells = <0>; 45 + compatible = "qcom,usb-hs-ipq4019-phy"; 46 + reg = <0xa8000 0x40>; 47 + resets = <&gcc USB2_HSPHY_POR_ARES>, 48 + <&gcc USB2_HSPHY_S_ARES>; 49 + reset-names = "por_rst", "srif_rst"; 50 + };
-70
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
··· 1 - * Renesas R-Car generation 3 USB 2.0 PHY 2 - 3 - This file provides information on what the device node for the R-Car generation 4 - 3, RZ/G1C, RZ/G2 and RZ/A2 USB 2.0 PHY contain. 5 - 6 - Required properties: 7 - - compatible: "renesas,usb2-phy-r7s9210" if the device is a part of an R7S9210 8 - SoC. 9 - "renesas,usb2-phy-r8a77470" if the device is a part of an R8A77470 10 - SoC. 11 - "renesas,usb2-phy-r8a774a1" if the device is a part of an R8A774A1 12 - SoC. 13 - "renesas,usb2-phy-r8a774b1" if the device is a part of an R8A774B1 14 - SoC. 15 - "renesas,usb2-phy-r8a774c0" if the device is a part of an R8A774C0 16 - SoC. 17 - "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 18 - SoC. 19 - "renesas,usb2-phy-r8a7796" if the device is a part of an R8A7796 20 - SoC. 21 - "renesas,usb2-phy-r8a77965" if the device is a part of an 22 - R8A77965 SoC. 23 - "renesas,usb2-phy-r8a77990" if the device is a part of an 24 - R8A77990 SoC. 25 - "renesas,usb2-phy-r8a77995" if the device is a part of an 26 - R8A77995 SoC. 27 - "renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3, RZ/G2 or 28 - RZ/A2 compatible device. 29 - 30 - When compatible with the generic version, nodes must list the 31 - SoC-specific version corresponding to the platform first 32 - followed by the generic version. 33 - 34 - - reg: offset and length of the partial USB 2.0 Host register block. 35 - - clocks: clock phandle and specifier pair(s). 36 - - #phy-cells: see phy-bindings.txt in the same directory, must be <1> (and 37 - using <0> is deprecated). 38 - 39 - The phandle's argument in the PHY specifier is the INT_STATUS bit of controller: 40 - - 1 = USBH_INTA (OHCI) 41 - - 2 = USBH_INTB (EHCI) 42 - - 3 = UCOM_INT (OTG and BC) 43 - 44 - Optional properties: 45 - To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are 46 - combined, the device tree node should set interrupt properties to use the 47 - channel as USB OTG: 48 - - interrupts: interrupt specifier for the PHY. 49 - - vbus-supply: Phandle to a regulator that provides power to the VBUS. This 50 - regulator will be managed during the PHY power on/off sequence. 51 - - renesas,no-otg-pins: boolean, specify when a board does not provide proper 52 - otg pins. 53 - - dr_mode: string, indicates the working mode for the PHY. Can be "host", 54 - "peripheral", or "otg". Should be set if otg controller is not used. 55 - 56 - 57 - Example (R-Car H3): 58 - 59 - usb-phy@ee080200 { 60 - compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; 61 - reg = <0 0xee080200 0 0x700>; 62 - interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; 63 - clocks = <&cpg CPG_MOD 703>; 64 - }; 65 - 66 - usb-phy@ee0a0200 { 67 - compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; 68 - reg = <0 0xee0a0200 0 0x700>; 69 - clocks = <&cpg CPG_MOD 702>; 70 - };
-52
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt
··· 1 - * Renesas R-Car generation 3 USB 3.0 PHY 2 - 3 - This file provides information on what the device node for the R-Car generation 4 - 3 and RZ/G2 USB 3.0 PHY contain. 5 - If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL 6 - instead of USB3_CLK. However, if you don't want to these features, you don't 7 - need this driver. 8 - 9 - Required properties: 10 - - compatible: "renesas,r8a774a1-usb3-phy" if the device is a part of an R8A774A1 11 - SoC. 12 - "renesas,r8a774b1-usb3-phy" if the device is a part of an R8A774B1 13 - SoC. 14 - "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795 15 - SoC. 16 - "renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796 17 - SoC. 18 - "renesas,r8a77965-usb3-phy" if the device is a part of an 19 - R8A77965 SoC. 20 - "renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 or RZ/G2 21 - compatible device. 22 - 23 - When compatible with the generic version, nodes must list the 24 - SoC-specific version corresponding to the platform first 25 - followed by the generic version. 26 - 27 - - reg: offset and length of the USB 3.0 PHY register block. 28 - - clocks: A list of phandles and clock-specifier pairs. 29 - - clock-names: Name of the clocks. 30 - - The funcional clock must be "usb3-if". 31 - - The usb3's external clock must be "usb3s_clk". 32 - - The usb2's external clock must be "usb_extal". If you want to use the ssc, 33 - the clock-frequency must not be 0. 34 - - #phy-cells: see phy-bindings.txt in the same directory, must be <0>. 35 - 36 - Optional properties: 37 - - renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using 38 - the following values as u32: 39 - - 0 (or the property doesn't exist): disable the ssc 40 - - 4980: enable the ssc as -4980 ppm 41 - - 4492: enable the ssc as -4492 ppm 42 - - 4003: enable the ssc as -4003 ppm 43 - 44 - Example (R-Car H3): 45 - 46 - usb-phy@e65ee000 { 47 - compatible = "renesas,r8a7795-usb3-phy", 48 - "renesas,rcar-gen3-usb3-phy"; 49 - reg = <0 0xe65ee000 0 0x90>; 50 - clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>; 51 - clock-names = "usb3-if", "usb3s_clk", "usb_extal"; 52 - };
+117
Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/phy/renesas,usb2-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas R-Car generation 3 USB 2.0 PHY 8 + 9 + maintainers: 10 + - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - items: 16 + - const: renesas,usb2-phy-r8a77470 # RZ/G1C 17 + 18 + - items: 19 + - enum: 20 + - renesas,usb2-phy-r7s9210 # RZ/A2 21 + - renesas,usb2-phy-r8a774a1 # RZ/G2M 22 + - renesas,usb2-phy-r8a774b1 # RZ/G2N 23 + - renesas,usb2-phy-r8a774c0 # RZ/G2E 24 + - renesas,usb2-phy-r8a7795 # R-Car H3 25 + - renesas,usb2-phy-r8a7796 # R-Car M3-W 26 + - renesas,usb2-phy-r8a77961 # R-Car M3-W+ 27 + - renesas,usb2-phy-r8a77965 # R-Car M3-N 28 + - renesas,usb2-phy-r8a77990 # R-Car E3 29 + - renesas,usb2-phy-r8a77995 # R-Car D3 30 + - const: renesas,rcar-gen3-usb2-phy 31 + 32 + reg: 33 + maxItems: 1 34 + 35 + clocks: 36 + minItems: 1 37 + maxItems: 2 38 + 39 + clock-names: 40 + minItems: 1 41 + maxItems: 2 42 + items: 43 + - const: fck 44 + - const: usb_x1 45 + 46 + '#phy-cells': 47 + enum: [0, 1] # and 0 is deprecated. 48 + description: | 49 + The phandle's argument in the PHY specifier is the INT_STATUS bit of 50 + controller. 51 + - 1 = USBH_INTA (OHCI) 52 + - 2 = USBH_INTB (EHCI) 53 + - 3 = UCOM_INT (OTG and BC) 54 + 55 + interrupts: 56 + maxItems: 1 57 + 58 + power-domains: 59 + maxItems: 1 60 + 61 + resets: 62 + minItems: 1 63 + maxItems: 2 64 + items: 65 + - description: reset of USB 2.0 host side 66 + - description: reset of USB 2.0 peripheral side 67 + 68 + vbus-supply: 69 + description: | 70 + Phandle to a regulator that provides power to the VBUS. This regulator 71 + will be managed during the PHY power on/off sequence. 72 + 73 + renesas,no-otg-pins: 74 + $ref: /schemas/types.yaml#/definitions/flag 75 + description: | 76 + specify when a board does not provide proper otg pins. 77 + 78 + dr_mode: true 79 + 80 + if: 81 + properties: 82 + compatible: 83 + items: 84 + enum: 85 + - renesas,usb2-phy-r7s9210 86 + then: 87 + required: 88 + - clock-names 89 + 90 + required: 91 + - compatible 92 + - reg 93 + - clocks 94 + - '#phy-cells' 95 + 96 + additionalProperties: false 97 + 98 + examples: 99 + - | 100 + #include <dt-bindings/clock/r8a7795-cpg-mssr.h> 101 + #include <dt-bindings/interrupt-controller/arm-gic.h> 102 + #include <dt-bindings/power/r8a7795-sysc.h> 103 + 104 + usb-phy@ee080200 { 105 + compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; 106 + reg = <0xee080200 0x700>; 107 + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; 108 + clocks = <&cpg CPG_MOD 703>; 109 + #phy-cells = <1>; 110 + }; 111 + 112 + usb-phy@ee0a0200 { 113 + compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; 114 + reg = <0xee0a0200 0x700>; 115 + clocks = <&cpg CPG_MOD 702>; 116 + #phy-cells = <1>; 117 + };
+79
Documentation/devicetree/bindings/phy/renesas,usb3-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/renesas,usb3-phy.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas R-Car generation 3 USB 3.0 PHY 8 + 9 + maintainers: 10 + - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> 11 + 12 + properties: 13 + compatible: 14 + items: 15 + - enum: 16 + - renesas,r8a774a1-usb3-phy # RZ/G2M 17 + - renesas,r8a774b1-usb3-phy # RZ/G2N 18 + - renesas,r8a7795-usb3-phy # R-Car H3 19 + - renesas,r8a7796-usb3-phy # R-Car M3-W 20 + - renesas,r8a77961-usb3-phy # R-Car M3-W+ 21 + - renesas,r8a77965-usb3-phy # R-Car M3-N 22 + - const: renesas,rcar-gen3-usb3-phy 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + clocks: 28 + minItems: 2 29 + maxItems: 3 30 + 31 + clock-names: 32 + # If you want to use the ssc, the clock-frequency of usb_extal 33 + # must not be 0. 34 + minItems: 2 35 + maxItems: 3 36 + items: 37 + - const: usb3-if # The funcional clock 38 + - const: usb3s_clk # The usb3's external clock 39 + - const: usb_extal # The usb2's external clock 40 + 41 + '#phy-cells': 42 + # see phy-bindings.txt in the same directory 43 + const: 0 44 + 45 + power-domains: 46 + maxItems: 1 47 + 48 + resets: 49 + maxItems: 1 50 + 51 + renesas,ssc-range: 52 + description: | 53 + Enable/disable spread spectrum clock (ssc). 0 or the property doesn't 54 + exist means disabling the ssc. The actual value will be -<value> ppm. 55 + allOf: 56 + - $ref: /schemas/types.yaml#/definitions/uint32 57 + - enum: [ 0, 4003, 4492, 4980 ] 58 + 59 + required: 60 + - compatible 61 + - reg 62 + - clocks 63 + - clock-names 64 + - '#phy-cells' 65 + 66 + additionalProperties: false 67 + 68 + examples: 69 + - | 70 + #include <dt-bindings/clock/r8a7795-cpg-mssr.h> 71 + #include <dt-bindings/power/r8a7795-sysc.h> 72 + 73 + usb-phy@e65ee000 { 74 + compatible = "renesas,r8a7795-usb3-phy", "renesas,rcar-gen3-usb3-phy"; 75 + reg = <0xe65ee000 0x90>; 76 + clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>; 77 + clock-names = "usb3-if", "usb3s_clk", "usb_extal"; 78 + #phy-cells = <0>; 79 + };
-42
Documentation/devicetree/bindings/usb/amlogic,dwc3.txt
··· 1 - Amlogic Meson GX DWC3 USB SoC controller 2 - 3 - Required properties: 4 - - compatible: depending on the SoC this should contain one of: 5 - * amlogic,meson-axg-dwc3 6 - * amlogic,meson-gxl-dwc3 7 - - clocks: a handle for the "USB general" clock 8 - - clock-names: must be "usb_general" 9 - - resets: a handle for the shared "USB OTG" reset line 10 - - reset-names: must be "usb_otg" 11 - 12 - Required child node: 13 - A child node must exist to represent the core DWC3 IP block. The name of 14 - the node is not important. The content of the node is defined in dwc3.txt. 15 - 16 - PHY documentation is provided in the following places: 17 - - Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt 18 - - Documentation/devicetree/bindings/phy/meson-gxl-usb3-phy.txt 19 - 20 - Example device nodes: 21 - usb0: usb@ff500000 { 22 - compatible = "amlogic,meson-axg-dwc3"; 23 - #address-cells = <2>; 24 - #size-cells = <2>; 25 - ranges; 26 - 27 - clocks = <&clkc CLKID_USB>; 28 - clock-names = "usb_general"; 29 - resets = <&reset RESET_USB_OTG>; 30 - reset-names = "usb_otg"; 31 - 32 - dwc3: dwc3@ff500000 { 33 - compatible = "snps,dwc3"; 34 - reg = <0x0 0xff500000 0x0 0x100000>; 35 - interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; 36 - dr_mode = "host"; 37 - maximum-speed = "high-speed"; 38 - snps,dis_u2_susphy_quirk; 39 - phys = <&usb3_phy>, <&usb2_phy0>; 40 - phy-names = "usb2-phy", "usb3-phy"; 41 - }; 42 - };
+69 -4
Documentation/devicetree/bindings/usb/amlogic,meson-g12a-usb-ctrl.yaml
··· 25 25 The Amlogic A1 embeds a DWC3 USB IP Core configured for USB2 in 26 26 host-only mode. 27 27 28 + The Amlogic GXL & GXM SoCs doesn't embed an USB3 PHY. 29 + 28 30 properties: 29 31 compatible: 30 32 enum: 33 + - amlogic,meson-gxl-usb-ctrl 34 + - amlogic,meson-gxm-usb-ctrl 31 35 - amlogic,meson-g12a-usb-ctrl 32 36 - amlogic,meson-a1-usb-ctrl 33 37 ··· 45 41 46 42 clocks: 47 43 minItems: 1 44 + maxItems: 3 45 + 46 + clock-names: 47 + minItems: 1 48 + maxItems: 3 48 49 49 50 resets: 50 51 minItems: 1 ··· 61 52 maxItems: 1 62 53 63 54 phy-names: 64 - items: 65 - - const: usb2-phy0 # USB2 PHY0 if USBHOST_A port is used 66 - - const: usb2-phy1 # USB2 PHY1 if USBOTG_B port is used 67 - - const: usb3-phy0 # USB3 PHY if USB3_0 is used 55 + minItems: 1 56 + maxItems: 3 68 57 69 58 phys: 70 59 minItems: 1 ··· 100 93 properties: 101 94 compatible: 102 95 enum: 96 + - amlogic,meson-g12a-usb-ctrl 97 + 98 + then: 99 + properties: 100 + phy-names: 101 + items: 102 + - const: usb2-phy0 # USB2 PHY0 if USBHOST_A port is used 103 + - const: usb2-phy1 # USB2 PHY1 if USBOTG_B port is used 104 + - const: usb3-phy0 # USB3 PHY if USB3_0 is used 105 + - if: 106 + properties: 107 + compatible: 108 + enum: 109 + - amlogic,meson-gxl-usb-ctrl 110 + 111 + then: 112 + properties: 113 + clocks: 114 + minItems: 2 115 + clock-names: 116 + items: 117 + - const: usb_ctrl 118 + - const: ddr 119 + phy-names: 120 + items: 121 + - const: usb2-phy0 # USB2 PHY0 if USBHOST_A port is used 122 + - const: usb2-phy1 # USB2 PHY1 if USBOTG_B port is used 123 + required: 124 + - clock-names 125 + - if: 126 + properties: 127 + compatible: 128 + enum: 129 + - amlogic,meson-gxm-usb-ctrl 130 + 131 + then: 132 + properties: 133 + clocks: 134 + minItems: 2 135 + clock-names: 136 + items: 137 + - const: usb_ctrl 138 + - const: ddr 139 + phy-names: 140 + items: 141 + - const: usb2-phy0 # USB2 PHY0 if USBHOST_A port is used 142 + - const: usb2-phy1 # USB2 PHY1 if USBOTG_B port is used 143 + - const: usb2-phy2 # USB2 PHY2 if USBOTG_C port is used 144 + 145 + required: 146 + - clock-names 147 + - if: 148 + properties: 149 + compatible: 150 + enum: 103 151 - amlogic,meson-a1-usb-ctrl 104 152 105 153 then: 106 154 properties: 155 + phy-names: 156 + items: 157 + - const: usb2-phy1 # USB2 PHY1 if USBOTG_B port is used 107 158 clocks: 108 159 minItems: 3 109 160 clock-names:
+68
Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
··· 50 50 minimum: 1 51 51 maximum: 21 52 52 53 + vhub-vendor-id: 54 + description: vhub Vendor ID 55 + allOf: 56 + - $ref: /schemas/types.yaml#/definitions/uint32 57 + - maximum: 65535 58 + 59 + vhub-product-id: 60 + description: vhub Product ID 61 + allOf: 62 + - $ref: /schemas/types.yaml#/definitions/uint32 63 + - maximum: 65535 64 + 65 + vhub-device-revision: 66 + description: vhub Device Revision in binary-coded decimal 67 + allOf: 68 + - $ref: /schemas/types.yaml#/definitions/uint32 69 + - maximum: 65535 70 + 71 + vhub-strings: 72 + type: object 73 + 74 + properties: 75 + '#address-cells': 76 + const: 1 77 + 78 + '#size-cells': 79 + const: 0 80 + 81 + patternProperties: 82 + '^string@[0-9a-f]+$': 83 + type: object 84 + description: string descriptors of the specific language 85 + 86 + properties: 87 + reg: 88 + maxItems: 1 89 + description: 16-bit Language Identifier defined by USB-IF 90 + 91 + manufacturer: 92 + description: vhub manufacturer 93 + allOf: 94 + - $ref: /schemas/types.yaml#/definitions/string 95 + 96 + product: 97 + description: vhub product name 98 + allOf: 99 + - $ref: /schemas/types.yaml#/definitions/string 100 + 101 + serial-number: 102 + description: vhub device serial number 103 + allOf: 104 + - $ref: /schemas/types.yaml#/definitions/string 105 + 53 106 required: 54 107 - compatible 55 108 - reg ··· 125 72 aspeed,vhub-generic-endpoints = <15>; 126 73 pinctrl-names = "default"; 127 74 pinctrl-0 = <&pinctrl_usb2ad_default>; 75 + 76 + vhub-vendor-id = <0x1d6b>; 77 + vhub-product-id = <0x0107>; 78 + vhub-device-revision = <0x0100>; 79 + vhub-strings { 80 + #address-cells = <1>; 81 + #size-cells = <0>; 82 + 83 + string@0409 { 84 + reg = <0x0409>; 85 + manufacturer = "ASPEED"; 86 + product = "USB Virtual Hub"; 87 + serial-number = "0000"; 88 + }; 89 + }; 128 90 };
+3 -53
Documentation/devicetree/bindings/usb/atmel-usb.txt
··· 88 88 - clock-names: Should contain two strings 89 89 "pclk" for the peripheral clock 90 90 "hclk" for the host clock 91 + 92 + Deprecated property: 91 93 - ep childnode: To specify the number of endpoints and their properties. 92 94 93 95 Optional properties: 94 96 - atmel,vbus-gpio: If present, specifies a gpio that allows to detect whether 95 97 vbus is present (USB is connected). 96 98 97 - Required child node properties: 99 + Deprecated child node properties: 98 100 - name: Name of the endpoint. 99 101 - reg: Num of the endpoint. 100 102 - atmel,fifo-size: Size of the fifo. ··· 114 112 clocks = <&utmi>, <&udphs_clk>; 115 113 clock-names = "hclk", "pclk"; 116 114 atmel,vbus-gpio = <&pioB 19 0>; 117 - 118 - ep@0 { 119 - reg = <0>; 120 - atmel,fifo-size = <64>; 121 - atmel,nb-banks = <1>; 122 - }; 123 - 124 - ep@1 { 125 - reg = <1>; 126 - atmel,fifo-size = <1024>; 127 - atmel,nb-banks = <2>; 128 - atmel,can-dma; 129 - atmel,can-isoc; 130 - }; 131 - 132 - ep@2 { 133 - reg = <2>; 134 - atmel,fifo-size = <1024>; 135 - atmel,nb-banks = <2>; 136 - atmel,can-dma; 137 - atmel,can-isoc; 138 - }; 139 - 140 - ep@3 { 141 - reg = <3>; 142 - atmel,fifo-size = <1024>; 143 - atmel,nb-banks = <3>; 144 - atmel,can-dma; 145 - }; 146 - 147 - ep@4 { 148 - reg = <4>; 149 - atmel,fifo-size = <1024>; 150 - atmel,nb-banks = <3>; 151 - atmel,can-dma; 152 - }; 153 - 154 - ep@5 { 155 - reg = <5>; 156 - atmel,fifo-size = <1024>; 157 - atmel,nb-banks = <3>; 158 - atmel,can-dma; 159 - atmel,can-isoc; 160 - }; 161 - 162 - ep@6 { 163 - reg = <6>; 164 - atmel,fifo-size = <1024>; 165 - atmel,nb-banks = <3>; 166 - atmel,can-dma; 167 - atmel,can-isoc; 168 - }; 169 115 };
+59
Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/usb/brcm,bcm7445-ehci.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Broadcom STB USB EHCI Controller Device Tree Bindings 8 + 9 + allOf: 10 + - $ref: "usb-hcd.yaml" 11 + 12 + maintainers: 13 + - Al Cooper <alcooperx@gmail.com> 14 + 15 + properties: 16 + compatible: 17 + const: brcm,bcm7445-ehci 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + interrupts: 23 + maxItems: 1 24 + 25 + clocks: 26 + maxItems: 1 27 + description: Clock specifier for the EHCI clock 28 + 29 + clock-names: 30 + const: sw_usb 31 + 32 + phys: 33 + maxItems: 1 34 + 35 + phy-names: 36 + const: usbphy 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - interrupts 42 + - phys 43 + - clocks 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + usb@f0b00300 { 50 + compatible = "brcm,bcm7445-ehci"; 51 + reg = <0xf0b00300 0xa8>; 52 + interrupts = <0x0 0x5a 0x0>; 53 + phys = <&usbphy_0 0x0>; 54 + phy-names = "usbphy"; 55 + clocks = <&usb20>; 56 + clock-names = "sw_usb"; 57 + }; 58 + 59 + ...
-2
Documentation/devicetree/bindings/usb/dwc3.txt
··· 15 15 Exception for clocks: 16 16 clocks are optional if the parent node (i.e. glue-layer) is compatible to 17 17 one of the following: 18 - "amlogic,meson-axg-dwc3" 19 - "amlogic,meson-gxl-dwc3" 20 18 "cavium,octeon-7130-usb-uctl" 21 19 "qcom,dwc3" 22 20 "samsung,exynos5250-dwusb3"
-56
Documentation/devicetree/bindings/usb/keystone-usb.txt
··· 1 - TI Keystone Soc USB Controller 2 - 3 - DWC3 GLUE 4 - 5 - Required properties: 6 - - compatible: should be 7 - "ti,keystone-dwc3" for Keystone 2 SoCs 8 - "ti,am654-dwc3" for AM654 SoC 9 - - #address-cells, #size-cells : should be '1' if the device has sub-nodes 10 - with 'reg' property. 11 - - reg : Address and length of the register set for the USB subsystem on 12 - the SOC. 13 - - interrupts : The irq number of this device that is used to interrupt the 14 - MPU. 15 - - ranges: allows valid 1:1 translation between child's address space and 16 - parent's address space. 17 - 18 - SoC-specific Required Properties: 19 - The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E 20 - SoCs only: 21 - 22 - - clocks: Clock ID for USB functional clock. 23 - - clock-names: Must be "usb". 24 - 25 - 26 - The following are mandatory properties for 66AK2G and AM654: 27 - 28 - - power-domains: Should contain a phandle to a PM domain provider node 29 - and an args specifier containing the USB device id 30 - value. This property is as per the binding, 31 - Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt 32 - 33 - Sub-nodes: 34 - The dwc3 core should be added as subnode to Keystone DWC3 glue. 35 - - dwc3 : 36 - The binding details of dwc3 can be found in: 37 - Documentation/devicetree/bindings/usb/dwc3.txt 38 - 39 - Example: 40 - usb: usb@2680000 { 41 - compatible = "ti,keystone-dwc3"; 42 - #address-cells = <1>; 43 - #size-cells = <1>; 44 - reg = <0x2680000 0x10000>; 45 - clocks = <&clkusb>; 46 - clock-names = "usb"; 47 - interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>; 48 - ranges; 49 - 50 - dwc3@2690000 { 51 - compatible = "synopsys,dwc3"; 52 - reg = <0x2690000 0x70000>; 53 - interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>; 54 - usb-phy = <&usb_phy>, <&usb_phy>; 55 - }; 56 - };
+2
Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
··· 21 21 - enum: 22 22 - nvidia,tegra210-xudc # For Tegra210 23 23 - nvidia,tegra186-xudc # For Tegra186 24 + - nvidia,tegra194-xudc # For Tegra194 24 25 25 26 reg: 26 27 minItems: 2 ··· 145 144 contains: 146 145 enum: 147 146 - nvidia,tegra186-xudc 147 + - nvidia,tegra194-xudc 148 148 then: 149 149 properties: 150 150 reg:
+77
Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/usb/ti,keystone-dwc3.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: TI Keystone Soc USB Controller 8 + 9 + maintainers: 10 + - Roger Quadros <rogerq@ti.com> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - const: "ti,keystone-dwc3" 16 + - const: "ti,am654-dwc3" 17 + 18 + reg: 19 + maxItems: 1 20 + description: Address and length of the register set for the USB subsystem on 21 + the SOC. 22 + 23 + interrupts: 24 + maxItems: 1 25 + description: The irq number of this device that is used to interrupt the MPU. 26 + 27 + 28 + clocks: 29 + description: Clock ID for USB functional clock. 30 + 31 + power-domains: 32 + description: Should contain a phandle to a PM domain provider node 33 + and an args specifier containing the USB device id 34 + value. This property is as per the binding, 35 + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt 36 + 37 + phys: 38 + description: 39 + PHY specifier for the USB3.0 PHY. Some SoCs need the USB3.0 PHY 40 + to be turned on before the controller. 41 + Documentation/devicetree/bindings/phy/phy-bindings.txt 42 + 43 + phy-names: 44 + items: 45 + - const: "usb3-phy" 46 + 47 + dwc3: 48 + description: This is the node representing the DWC3 controller instance 49 + Documentation/devicetree/bindings/usb/dwc3.txt 50 + 51 + required: 52 + - compatible 53 + - reg 54 + - interrupts 55 + - clocks 56 + 57 + examples: 58 + - | 59 + #include <dt-bindings/interrupt-controller/arm-gic.h> 60 + 61 + usb: usb@2680000 { 62 + compatible = "ti,keystone-dwc3"; 63 + #address-cells = <1>; 64 + #size-cells = <1>; 65 + reg = <0x2680000 0x10000>; 66 + clocks = <&clkusb>; 67 + clock-names = "usb"; 68 + interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>; 69 + ranges; 70 + 71 + dwc3@2690000 { 72 + compatible = "synopsys,dwc3"; 73 + reg = <0x2690000 0x70000>; 74 + interrupts = <GIC_SPI 393 IRQ_TYPE_EDGE_RISING>; 75 + usb-phy = <&usb_phy>, <&usb_phy>; 76 + }; 77 + };
+64
Documentation/devicetree/bindings/usb/ti,tps6598x.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/usb/ti,tps6598x.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Texas Instruments 6598x Type-C Port Switch and Power Delivery controller DT bindings 8 + 9 + maintainers: 10 + - Bryan O'Donoghue <bryan.odonoghue@linaro.org> 11 + 12 + description: | 13 + Texas Instruments 6598x Type-C Port Switch and Power Delivery controller 14 + 15 + properties: 16 + compatible: 17 + enum: 18 + - ti,tps6598x 19 + reg: 20 + maxItems: 1 21 + 22 + interrupts: 23 + maxItems: 1 24 + 25 + interrupt-names: 26 + items: 27 + - const: irq 28 + 29 + required: 30 + - compatible 31 + - reg 32 + - interrupts 33 + - interrupt-names 34 + 35 + examples: 36 + - | 37 + #include <dt-bindings/interrupt-controller/irq.h> 38 + i2c0 { 39 + #address-cells = <1>; 40 + #size-cells = <0>; 41 + 42 + tps6598x: tps6598x@38 { 43 + compatible = "ti,tps6598x"; 44 + reg = <0x38>; 45 + 46 + interrupt-parent = <&msmgpio>; 47 + interrupts = <107 IRQ_TYPE_LEVEL_LOW>; 48 + interrupt-names = "irq"; 49 + 50 + pinctrl-names = "default"; 51 + pinctrl-0 = <&typec_pins>; 52 + 53 + typec_con: connector { 54 + compatible = "usb-c-connector"; 55 + label = "USB-C"; 56 + port { 57 + typec_ep: endpoint { 58 + remote-endpoint = <&otg_ep>; 59 + }; 60 + }; 61 + }; 62 + }; 63 + }; 64 + ...
+1
Documentation/devicetree/bindings/usb/usb-xhci.txt
··· 25 25 device 26 26 - "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 or RZ/G2 compatible 27 27 device 28 + - "brcm,bcm7445-xhci" for Broadcom STB SoCs with XHCI 28 29 - "xhci-platform" (deprecated) 29 30 30 31 When compatible with the generic version, nodes must list the
+153
Documentation/firmware-guide/acpi/intel-pmc-mux.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ===================== 4 + Intel North Mux-Agent 5 + ===================== 6 + 7 + Introduction 8 + ============ 9 + 10 + North Mux-Agent is a function of the Intel PMC firmware that is supported on 11 + most Intel based platforms that have the PMC microcontroller. It's used for 12 + configuring the various USB Multiplexer/DeMultiplexers on the system. The 13 + platforms that allow the mux-agent to be configured from the operating system 14 + have an ACPI device object (node) with HID "INTC105C" that represents it. 15 + 16 + The North Mux-Agent (aka. Intel PMC Mux Control, or just mux-agent) driver 17 + communicates with the PMC microcontroller by using the PMC IPC method 18 + (drivers/platform/x86/intel_scu_ipc.c). The driver registers with the USB Type-C 19 + Mux Class which allows the USB Type-C Controller and Interface drivers to 20 + configure the cable plug orientation and mode (with Alternate Modes). The driver 21 + also registers with the USB Role Class in order to support both USB Host and 22 + Device modes. The driver is located here: drivers/usb/typec/mux/intel_pmc_mux.c. 23 + 24 + Port nodes 25 + ========== 26 + 27 + General 28 + ------- 29 + 30 + For every USB Type-C connector under the mux-agent control on the system, there 31 + is a separate child node under the PMC mux-agent device node. Those nodes do not 32 + represent the actual connectors, but instead the "channels" in the mux-agent 33 + that are associated with the connectors:: 34 + 35 + Scope (_SB.PCI0.PMC.MUX) 36 + { 37 + Device (CH0) 38 + { 39 + Name (_ADR, 0) 40 + } 41 + 42 + Device (CH1) 43 + { 44 + Name (_ADR, 1) 45 + } 46 + } 47 + 48 + _PLD (Physical Location of Device) 49 + ---------------------------------- 50 + 51 + The optional _PLD object can be used with the port (the channel) nodes. If _PLD 52 + is supplied, it should match the connector node _PLD:: 53 + 54 + Scope (_SB.PCI0.PMC.MUX) 55 + { 56 + Device (CH0) 57 + { 58 + Name (_ADR, 0) 59 + Method (_PLD, 0, NotSerialized) 60 + { 61 + /* Consider this as pseudocode. */ 62 + Return (\_SB.USBC.CON0._PLD()) 63 + } 64 + } 65 + } 66 + 67 + Mux-agent specific _DSD Device Properties 68 + ----------------------------------------- 69 + 70 + Port Numbers 71 + ~~~~~~~~~~~~ 72 + 73 + In order to configure the muxes behind a USB Type-C connector, the PMC firmware 74 + needs to know the USB2 port and the USB3 port that is associated with the 75 + connector. The driver extracts the correct port numbers by reading specific _DSD 76 + device properties named "usb2-port-number" and "usb3-port-number". These 77 + properties have integer value that means the port index. The port index number 78 + is 1's based, and value 0 is illegal. The driver uses the numbers extracted from 79 + these device properties as-is when sending the mux-agent specific messages to 80 + the PMC:: 81 + 82 + Name (_DSD, Package () { 83 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 84 + Package() { 85 + Package () {"usb2-port-number", 6}, 86 + Package () {"usb3-port-number", 3}, 87 + }, 88 + }) 89 + 90 + Orientation 91 + ~~~~~~~~~~~ 92 + 93 + Depending on the platform, the data and SBU lines coming from the connector may 94 + be "fixed" from the mux-agent's point of view, which means the mux-agent driver 95 + should not configure them according to the cable plug orientation. This can 96 + happen for example if a retimer on the platform handles the cable plug 97 + orientation. The driver uses a specific device properties "sbu-orientation" 98 + (SBU) and "hsl-orientation" (data) to know if those lines are "fixed", and to 99 + which orientation. The value that these properties have is a string value, and 100 + it can be one that is defined for the USB Type-C connector orientation: "normal" 101 + or "reversed":: 102 + 103 + Name (_DSD, Package () { 104 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 105 + Package() { 106 + Package () {"sbu-orientation", "normal"}, 107 + Package () {"hsl-orientation", "normal"}, 108 + }, 109 + }) 110 + 111 + Example ASL 112 + =========== 113 + 114 + The following ASL is an example that shows the mux-agent node, and two 115 + connectors under its control:: 116 + 117 + Scope (_SB.PCI0.PMC) 118 + { 119 + Device (MUX) 120 + { 121 + Name (_HID, "INTC105C") 122 + 123 + Device (CH0) 124 + { 125 + Name (_ADR, 0) 126 + 127 + Name (_DSD, Package () { 128 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 129 + Package() { 130 + Package () {"usb2-port-number", 6}, 131 + Package () {"usb3-port-number", 3}, 132 + Package () {"sbu-orientation", "normal"}, 133 + Package () {"hsl-orientation", "normal"}, 134 + }, 135 + }) 136 + } 137 + 138 + Device (CH1) 139 + { 140 + Name (_ADR, 1) 141 + 142 + Name (_DSD, Package () { 143 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 144 + Package() { 145 + Package () {"usb2-port-number", 5}, 146 + Package () {"usb3-port-number", 2}, 147 + Package () {"sbu-orientation", "normal"}, 148 + Package () {"hsl-orientation", "normal"}, 149 + }, 150 + }) 151 + } 152 + } 153 + }
+15
MAINTAINERS
··· 3500 3500 F: Documentation/devicetree/bindings/i2c/brcm,brcmstb-i2c.yaml 3501 3501 F: drivers/i2c/busses/i2c-brcmstb.c 3502 3502 3503 + BROADCOM BRCMSTB USB EHCI DRIVER 3504 + M: Al Cooper <alcooperx@gmail.com> 3505 + L: linux-usb@vger.kernel.org 3506 + L: bcm-kernel-feedback-list@broadcom.com 3507 + S: Maintained 3508 + F: Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml 3509 + F: drivers/usb/host/ehci-brcm.* 3510 + 3503 3511 BROADCOM BRCMSTB USB2 and USB3 PHY DRIVER 3504 3512 M: Al Cooper <alcooperx@gmail.com> 3505 3513 L: linux-kernel@vger.kernel.org ··· 17766 17758 F: Documentation/driver-api/usb/typec.rst 17767 17759 F: drivers/usb/typec/ 17768 17760 F: include/linux/usb/typec.h 17761 + 17762 + USB TYPEC INTEL PMC MUX DRIVER 17763 + M: Heikki Krogerus <heikki.krogerus@linux.intel.com> 17764 + L: linux-usb@vger.kernel.org 17765 + S: Maintained 17766 + F: Documentation/firmware-guide/acpi/intel-pmc-mux.rst 17767 + F: drivers/usb/typec/mux/intel_pmc_mux.c 17769 17768 17770 17769 USB TYPEC PI3USB30532 MUX DRIVER 17771 17770 M: Hans de Goede <hdegoede@redhat.com>
-54
arch/arm/boot/dts/at91sam9g45.dtsi
··· 933 933 }; 934 934 935 935 usb2: gadget@fff78000 { 936 - #address-cells = <1>; 937 - #size-cells = <0>; 938 936 compatible = "atmel,at91sam9g45-udc"; 939 937 reg = <0x00600000 0x80000 940 938 0xfff78000 0x400>; ··· 940 942 clocks = <&pmc PMC_TYPE_PERIPHERAL 27>, <&pmc PMC_TYPE_CORE PMC_UTMI>; 941 943 clock-names = "pclk", "hclk"; 942 944 status = "disabled"; 943 - 944 - ep@0 { 945 - reg = <0>; 946 - atmel,fifo-size = <64>; 947 - atmel,nb-banks = <1>; 948 - }; 949 - 950 - ep@1 { 951 - reg = <1>; 952 - atmel,fifo-size = <1024>; 953 - atmel,nb-banks = <2>; 954 - atmel,can-dma; 955 - atmel,can-isoc; 956 - }; 957 - 958 - ep@2 { 959 - reg = <2>; 960 - atmel,fifo-size = <1024>; 961 - atmel,nb-banks = <2>; 962 - atmel,can-dma; 963 - atmel,can-isoc; 964 - }; 965 - 966 - ep@3 { 967 - reg = <3>; 968 - atmel,fifo-size = <1024>; 969 - atmel,nb-banks = <3>; 970 - atmel,can-dma; 971 - }; 972 - 973 - ep@4 { 974 - reg = <4>; 975 - atmel,fifo-size = <1024>; 976 - atmel,nb-banks = <3>; 977 - atmel,can-dma; 978 - }; 979 - 980 - ep@5 { 981 - reg = <5>; 982 - atmel,fifo-size = <1024>; 983 - atmel,nb-banks = <3>; 984 - atmel,can-dma; 985 - atmel,can-isoc; 986 - }; 987 - 988 - ep@6 { 989 - reg = <6>; 990 - atmel,fifo-size = <1024>; 991 - atmel,nb-banks = <3>; 992 - atmel,can-dma; 993 - atmel,can-isoc; 994 - }; 995 945 }; 996 946 997 947 clk32k: sckc@fffffd50 {
-54
arch/arm/boot/dts/at91sam9rl.dtsi
··· 299 299 }; 300 300 301 301 usb0: gadget@fffd4000 { 302 - #address-cells = <1>; 303 - #size-cells = <0>; 304 302 compatible = "atmel,at91sam9rl-udc"; 305 303 reg = <0x00600000 0x100000>, 306 304 <0xfffd4000 0x4000>; ··· 306 308 clocks = <&pmc PMC_TYPE_PERIPHERAL 22>, <&pmc PMC_TYPE_CORE PMC_UTMI>; 307 309 clock-names = "pclk", "hclk"; 308 310 status = "disabled"; 309 - 310 - ep@0 { 311 - reg = <0>; 312 - atmel,fifo-size = <64>; 313 - atmel,nb-banks = <1>; 314 - }; 315 - 316 - ep@1 { 317 - reg = <1>; 318 - atmel,fifo-size = <1024>; 319 - atmel,nb-banks = <2>; 320 - atmel,can-dma; 321 - atmel,can-isoc; 322 - }; 323 - 324 - ep@2 { 325 - reg = <2>; 326 - atmel,fifo-size = <1024>; 327 - atmel,nb-banks = <2>; 328 - atmel,can-dma; 329 - atmel,can-isoc; 330 - }; 331 - 332 - ep@3 { 333 - reg = <3>; 334 - atmel,fifo-size = <1024>; 335 - atmel,nb-banks = <3>; 336 - atmel,can-dma; 337 - }; 338 - 339 - ep@4 { 340 - reg = <4>; 341 - atmel,fifo-size = <1024>; 342 - atmel,nb-banks = <3>; 343 - atmel,can-dma; 344 - }; 345 - 346 - ep@5 { 347 - reg = <5>; 348 - atmel,fifo-size = <1024>; 349 - atmel,nb-banks = <3>; 350 - atmel,can-dma; 351 - atmel,can-isoc; 352 - }; 353 - 354 - ep@6 { 355 - reg = <6>; 356 - atmel,fifo-size = <1024>; 357 - atmel,nb-banks = <3>; 358 - atmel,can-dma; 359 - atmel,can-isoc; 360 - }; 361 311 }; 362 312 363 313 dma0: dma-controller@ffffe600 {
-54
arch/arm/boot/dts/at91sam9x5.dtsi
··· 867 867 }; 868 868 869 869 usb2: gadget@f803c000 { 870 - #address-cells = <1>; 871 - #size-cells = <0>; 872 870 compatible = "atmel,at91sam9g45-udc"; 873 871 reg = <0x00500000 0x80000 874 872 0xf803c000 0x400>; ··· 874 876 clocks = <&pmc PMC_TYPE_CORE PMC_UTMI>, <&pmc PMC_TYPE_PERIPHERAL 23>; 875 877 clock-names = "hclk", "pclk"; 876 878 status = "disabled"; 877 - 878 - ep@0 { 879 - reg = <0>; 880 - atmel,fifo-size = <64>; 881 - atmel,nb-banks = <1>; 882 - }; 883 - 884 - ep@1 { 885 - reg = <1>; 886 - atmel,fifo-size = <1024>; 887 - atmel,nb-banks = <2>; 888 - atmel,can-dma; 889 - atmel,can-isoc; 890 - }; 891 - 892 - ep@2 { 893 - reg = <2>; 894 - atmel,fifo-size = <1024>; 895 - atmel,nb-banks = <2>; 896 - atmel,can-dma; 897 - atmel,can-isoc; 898 - }; 899 - 900 - ep@3 { 901 - reg = <3>; 902 - atmel,fifo-size = <1024>; 903 - atmel,nb-banks = <3>; 904 - atmel,can-dma; 905 - }; 906 - 907 - ep@4 { 908 - reg = <4>; 909 - atmel,fifo-size = <1024>; 910 - atmel,nb-banks = <3>; 911 - atmel,can-dma; 912 - }; 913 - 914 - ep@5 { 915 - reg = <5>; 916 - atmel,fifo-size = <1024>; 917 - atmel,nb-banks = <3>; 918 - atmel,can-dma; 919 - atmel,can-isoc; 920 - }; 921 - 922 - ep@6 { 923 - reg = <6>; 924 - atmel,fifo-size = <1024>; 925 - atmel,nb-banks = <3>; 926 - atmel,can-dma; 927 - atmel,can-isoc; 928 - }; 929 879 }; 930 880 931 881 watchdog: watchdog@fffffe40 {
-120
arch/arm/boot/dts/sama5d2.dtsi
··· 109 109 }; 110 110 111 111 usb0: gadget@300000 { 112 - #address-cells = <1>; 113 - #size-cells = <0>; 114 112 compatible = "atmel,sama5d3-udc"; 115 113 reg = <0x00300000 0x100000 116 114 0xfc02c000 0x400>; ··· 116 118 clocks = <&pmc PMC_TYPE_PERIPHERAL 42>, <&pmc PMC_TYPE_CORE PMC_UTMI>; 117 119 clock-names = "pclk", "hclk"; 118 120 status = "disabled"; 119 - 120 - ep@0 { 121 - reg = <0>; 122 - atmel,fifo-size = <64>; 123 - atmel,nb-banks = <1>; 124 - }; 125 - 126 - ep@1 { 127 - reg = <1>; 128 - atmel,fifo-size = <1024>; 129 - atmel,nb-banks = <3>; 130 - atmel,can-dma; 131 - atmel,can-isoc; 132 - }; 133 - 134 - ep@2 { 135 - reg = <2>; 136 - atmel,fifo-size = <1024>; 137 - atmel,nb-banks = <3>; 138 - atmel,can-dma; 139 - atmel,can-isoc; 140 - }; 141 - 142 - ep@3 { 143 - reg = <3>; 144 - atmel,fifo-size = <1024>; 145 - atmel,nb-banks = <2>; 146 - atmel,can-dma; 147 - atmel,can-isoc; 148 - }; 149 - 150 - ep@4 { 151 - reg = <4>; 152 - atmel,fifo-size = <1024>; 153 - atmel,nb-banks = <2>; 154 - atmel,can-dma; 155 - atmel,can-isoc; 156 - }; 157 - 158 - ep@5 { 159 - reg = <5>; 160 - atmel,fifo-size = <1024>; 161 - atmel,nb-banks = <2>; 162 - atmel,can-dma; 163 - atmel,can-isoc; 164 - }; 165 - 166 - ep@6 { 167 - reg = <6>; 168 - atmel,fifo-size = <1024>; 169 - atmel,nb-banks = <2>; 170 - atmel,can-dma; 171 - atmel,can-isoc; 172 - }; 173 - 174 - ep@7 { 175 - reg = <7>; 176 - atmel,fifo-size = <1024>; 177 - atmel,nb-banks = <2>; 178 - atmel,can-dma; 179 - atmel,can-isoc; 180 - }; 181 - 182 - ep@8 { 183 - reg = <8>; 184 - atmel,fifo-size = <1024>; 185 - atmel,nb-banks = <2>; 186 - atmel,can-isoc; 187 - }; 188 - 189 - ep@9 { 190 - reg = <9>; 191 - atmel,fifo-size = <1024>; 192 - atmel,nb-banks = <2>; 193 - atmel,can-isoc; 194 - }; 195 - 196 - ep@10 { 197 - reg = <10>; 198 - atmel,fifo-size = <1024>; 199 - atmel,nb-banks = <2>; 200 - atmel,can-isoc; 201 - }; 202 - 203 - ep@11 { 204 - reg = <11>; 205 - atmel,fifo-size = <1024>; 206 - atmel,nb-banks = <2>; 207 - atmel,can-isoc; 208 - }; 209 - 210 - ep@12 { 211 - reg = <12>; 212 - atmel,fifo-size = <1024>; 213 - atmel,nb-banks = <2>; 214 - atmel,can-isoc; 215 - }; 216 - 217 - ep@13 { 218 - reg = <13>; 219 - atmel,fifo-size = <1024>; 220 - atmel,nb-banks = <2>; 221 - atmel,can-isoc; 222 - }; 223 - 224 - ep@14 { 225 - reg = <14>; 226 - atmel,fifo-size = <1024>; 227 - atmel,nb-banks = <2>; 228 - atmel,can-isoc; 229 - }; 230 - 231 - ep@15 { 232 - reg = <15>; 233 - atmel,fifo-size = <1024>; 234 - atmel,nb-banks = <2>; 235 - atmel,can-isoc; 236 - }; 237 121 }; 238 122 239 123 usb1: ohci@400000 {
-107
arch/arm/boot/dts/sama5d3.dtsi
··· 1076 1076 }; 1077 1077 1078 1078 usb0: gadget@500000 { 1079 - #address-cells = <1>; 1080 - #size-cells = <0>; 1081 1079 compatible = "atmel,sama5d3-udc"; 1082 1080 reg = <0x00500000 0x100000 1083 1081 0xf8030000 0x4000>; ··· 1083 1085 clocks = <&pmc PMC_TYPE_PERIPHERAL 33>, <&pmc PMC_TYPE_CORE PMC_UTMI>; 1084 1086 clock-names = "pclk", "hclk"; 1085 1087 status = "disabled"; 1086 - 1087 - ep@0 { 1088 - reg = <0>; 1089 - atmel,fifo-size = <64>; 1090 - atmel,nb-banks = <1>; 1091 - }; 1092 - 1093 - ep@1 { 1094 - reg = <1>; 1095 - atmel,fifo-size = <1024>; 1096 - atmel,nb-banks = <3>; 1097 - atmel,can-dma; 1098 - atmel,can-isoc; 1099 - }; 1100 - 1101 - ep@2 { 1102 - reg = <2>; 1103 - atmel,fifo-size = <1024>; 1104 - atmel,nb-banks = <3>; 1105 - atmel,can-dma; 1106 - atmel,can-isoc; 1107 - }; 1108 - 1109 - ep@3 { 1110 - reg = <3>; 1111 - atmel,fifo-size = <1024>; 1112 - atmel,nb-banks = <2>; 1113 - atmel,can-dma; 1114 - }; 1115 - 1116 - ep@4 { 1117 - reg = <4>; 1118 - atmel,fifo-size = <1024>; 1119 - atmel,nb-banks = <2>; 1120 - atmel,can-dma; 1121 - }; 1122 - 1123 - ep@5 { 1124 - reg = <5>; 1125 - atmel,fifo-size = <1024>; 1126 - atmel,nb-banks = <2>; 1127 - atmel,can-dma; 1128 - }; 1129 - 1130 - ep@6 { 1131 - reg = <6>; 1132 - atmel,fifo-size = <1024>; 1133 - atmel,nb-banks = <2>; 1134 - atmel,can-dma; 1135 - }; 1136 - 1137 - ep@7 { 1138 - reg = <7>; 1139 - atmel,fifo-size = <1024>; 1140 - atmel,nb-banks = <2>; 1141 - atmel,can-dma; 1142 - }; 1143 - 1144 - ep@8 { 1145 - reg = <8>; 1146 - atmel,fifo-size = <1024>; 1147 - atmel,nb-banks = <2>; 1148 - }; 1149 - 1150 - ep@9 { 1151 - reg = <9>; 1152 - atmel,fifo-size = <1024>; 1153 - atmel,nb-banks = <2>; 1154 - }; 1155 - 1156 - ep@10 { 1157 - reg = <10>; 1158 - atmel,fifo-size = <1024>; 1159 - atmel,nb-banks = <2>; 1160 - }; 1161 - 1162 - ep@11 { 1163 - reg = <11>; 1164 - atmel,fifo-size = <1024>; 1165 - atmel,nb-banks = <2>; 1166 - }; 1167 - 1168 - ep@12 { 1169 - reg = <12>; 1170 - atmel,fifo-size = <1024>; 1171 - atmel,nb-banks = <2>; 1172 - }; 1173 - 1174 - ep@13 { 1175 - reg = <13>; 1176 - atmel,fifo-size = <1024>; 1177 - atmel,nb-banks = <2>; 1178 - }; 1179 - 1180 - ep@14 { 1181 - reg = <14>; 1182 - atmel,fifo-size = <1024>; 1183 - atmel,nb-banks = <2>; 1184 - }; 1185 - 1186 - ep@15 { 1187 - reg = <15>; 1188 - atmel,fifo-size = <1024>; 1189 - atmel,nb-banks = <2>; 1190 - }; 1191 1088 }; 1192 1089 1193 1090 usb1: ohci@600000 {
-120
arch/arm/boot/dts/sama5d4.dtsi
··· 96 96 }; 97 97 98 98 usb0: gadget@400000 { 99 - #address-cells = <1>; 100 - #size-cells = <0>; 101 99 compatible = "atmel,sama5d3-udc"; 102 100 reg = <0x00400000 0x100000 103 101 0xfc02c000 0x4000>; ··· 103 105 clocks = <&pmc PMC_TYPE_PERIPHERAL 47>, <&pmc PMC_TYPE_CORE PMC_UTMI>; 104 106 clock-names = "pclk", "hclk"; 105 107 status = "disabled"; 106 - 107 - ep@0 { 108 - reg = <0>; 109 - atmel,fifo-size = <64>; 110 - atmel,nb-banks = <1>; 111 - }; 112 - 113 - ep@1 { 114 - reg = <1>; 115 - atmel,fifo-size = <1024>; 116 - atmel,nb-banks = <3>; 117 - atmel,can-dma; 118 - atmel,can-isoc; 119 - }; 120 - 121 - ep@2 { 122 - reg = <2>; 123 - atmel,fifo-size = <1024>; 124 - atmel,nb-banks = <3>; 125 - atmel,can-dma; 126 - atmel,can-isoc; 127 - }; 128 - 129 - ep@3 { 130 - reg = <3>; 131 - atmel,fifo-size = <1024>; 132 - atmel,nb-banks = <2>; 133 - atmel,can-dma; 134 - atmel,can-isoc; 135 - }; 136 - 137 - ep@4 { 138 - reg = <4>; 139 - atmel,fifo-size = <1024>; 140 - atmel,nb-banks = <2>; 141 - atmel,can-dma; 142 - atmel,can-isoc; 143 - }; 144 - 145 - ep@5 { 146 - reg = <5>; 147 - atmel,fifo-size = <1024>; 148 - atmel,nb-banks = <2>; 149 - atmel,can-dma; 150 - atmel,can-isoc; 151 - }; 152 - 153 - ep@6 { 154 - reg = <6>; 155 - atmel,fifo-size = <1024>; 156 - atmel,nb-banks = <2>; 157 - atmel,can-dma; 158 - atmel,can-isoc; 159 - }; 160 - 161 - ep@7 { 162 - reg = <7>; 163 - atmel,fifo-size = <1024>; 164 - atmel,nb-banks = <2>; 165 - atmel,can-dma; 166 - atmel,can-isoc; 167 - }; 168 - 169 - ep@8 { 170 - reg = <8>; 171 - atmel,fifo-size = <1024>; 172 - atmel,nb-banks = <2>; 173 - atmel,can-isoc; 174 - }; 175 - 176 - ep@9 { 177 - reg = <9>; 178 - atmel,fifo-size = <1024>; 179 - atmel,nb-banks = <2>; 180 - atmel,can-isoc; 181 - }; 182 - 183 - ep@10 { 184 - reg = <10>; 185 - atmel,fifo-size = <1024>; 186 - atmel,nb-banks = <2>; 187 - atmel,can-isoc; 188 - }; 189 - 190 - ep@11 { 191 - reg = <11>; 192 - atmel,fifo-size = <1024>; 193 - atmel,nb-banks = <2>; 194 - atmel,can-isoc; 195 - }; 196 - 197 - ep@12 { 198 - reg = <12>; 199 - atmel,fifo-size = <1024>; 200 - atmel,nb-banks = <2>; 201 - atmel,can-isoc; 202 - }; 203 - 204 - ep@13 { 205 - reg = <13>; 206 - atmel,fifo-size = <1024>; 207 - atmel,nb-banks = <2>; 208 - atmel,can-isoc; 209 - }; 210 - 211 - ep@14 { 212 - reg = <14>; 213 - atmel,fifo-size = <1024>; 214 - atmel,nb-banks = <2>; 215 - atmel,can-isoc; 216 - }; 217 - 218 - ep@15 { 219 - reg = <15>; 220 - atmel,fifo-size = <1024>; 221 - atmel,nb-banks = <2>; 222 - atmel,can-isoc; 223 - }; 224 108 }; 225 109 226 110 usb1: ohci@500000 {
+4
arch/arm64/boot/dts/qcom/sc7180.dtsi
··· 2244 2244 2245 2245 resets = <&gcc GCC_USB30_PRIM_BCR>; 2246 2246 2247 + interconnects = <&aggre2_noc MASTER_USB3 &mc_virt SLAVE_EBI1>, 2248 + <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3>; 2249 + interconnect-names = "usb-ddr", "apps-usb"; 2250 + 2247 2251 usb_1_dwc3: dwc3@a600000 { 2248 2252 compatible = "snps,dwc3"; 2249 2253 reg = <0 0x0a600000 0 0xe000>;
+8
arch/arm64/boot/dts/qcom/sdm845.dtsi
··· 3136 3136 3137 3137 resets = <&gcc GCC_USB30_PRIM_BCR>; 3138 3138 3139 + interconnects = <&aggre2_noc MASTER_USB3_0 &mem_noc SLAVE_EBI1>, 3140 + <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3_0>; 3141 + interconnect-names = "usb-ddr", "apps-usb"; 3142 + 3139 3143 usb_1_dwc3: dwc3@a600000 { 3140 3144 compatible = "snps,dwc3"; 3141 3145 reg = <0 0x0a600000 0 0xcd00>; ··· 3183 3179 power-domains = <&gcc USB30_SEC_GDSC>; 3184 3180 3185 3181 resets = <&gcc GCC_USB30_SEC_BCR>; 3182 + 3183 + interconnects = <&aggre2_noc MASTER_USB3_1 &mem_noc SLAVE_EBI1>, 3184 + <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3_1>; 3185 + interconnect-names = "usb-ddr", "apps-usb"; 3186 3186 3187 3187 usb_2_dwc3: dwc3@a800000 { 3188 3188 compatible = "snps,dwc3";
+21
drivers/gpio/gpiolib-of.c
··· 466 466 return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags); 467 467 } 468 468 469 + static struct gpio_desc *of_find_usb_gpio(struct device *dev, 470 + const char *con_id, 471 + enum of_gpio_flags *of_flags) 472 + { 473 + /* 474 + * Currently this USB quirk is only for the Fairchild FUSB302 host which is using 475 + * an undocumented DT GPIO line named "fcs,int_n" without the compulsory "-gpios" 476 + * suffix. 477 + */ 478 + if (!IS_ENABLED(CONFIG_TYPEC_FUSB302)) 479 + return ERR_PTR(-ENOENT); 480 + 481 + if (!con_id || strcmp(con_id, "fcs,int_n")) 482 + return ERR_PTR(-ENOENT); 483 + 484 + return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags); 485 + } 486 + 469 487 struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, 470 488 unsigned int idx, unsigned long *flags) 471 489 { ··· 527 509 528 510 if (PTR_ERR(desc) == -ENOENT) 529 511 desc = of_find_arizona_gpio(dev, con_id, &of_flags); 512 + 513 + if (PTR_ERR(desc) == -ENOENT) 514 + desc = of_find_usb_gpio(dev, con_id, &of_flags); 530 515 531 516 if (IS_ERR(desc)) 532 517 return desc;
+2 -13
drivers/phy/amlogic/Kconfig
··· 3 3 # Phy drivers for Amlogic platforms 4 4 # 5 5 config PHY_MESON8B_USB2 6 - tristate "Meson8, Meson8b and GXBB USB2 PHY driver" 6 + tristate "Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY driver" 7 7 default ARCH_MESON 8 8 depends on OF && (ARCH_MESON || COMPILE_TEST) 9 9 depends on USB_SUPPORT 10 10 select USB_COMMON 11 11 select GENERIC_PHY 12 + select REGMAP_MMIO 12 13 help 13 14 Enable this to support the Meson USB2 PHYs found in Meson8, 14 15 Meson8b and GXBB SoCs. ··· 25 24 help 26 25 Enable this to support the Meson USB2 PHYs found in Meson 27 26 GXL and GXM SoCs. 28 - If unsure, say N. 29 - 30 - config PHY_MESON_GXL_USB3 31 - tristate "Meson GXL and GXM USB3 PHY drivers" 32 - default ARCH_MESON 33 - depends on OF && (ARCH_MESON || COMPILE_TEST) 34 - depends on USB_SUPPORT 35 - select GENERIC_PHY 36 - select REGMAP_MMIO 37 - help 38 - Enable this to support the Meson USB3 PHY and OTG detection 39 - IP block found in Meson GXL and GXM SoCs. 40 27 If unsure, say N. 41 28 42 29 config PHY_MESON_G12A_USB2
-1
drivers/phy/amlogic/Makefile
··· 2 2 obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o 3 3 obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o 4 4 obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o 5 - obj-$(CONFIG_PHY_MESON_GXL_USB3) += phy-meson-gxl-usb3.o 6 5 obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o 7 6 obj-$(CONFIG_PHY_MESON_AXG_PCIE) += phy-meson-axg-pcie.o 8 7 obj-$(CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG) += phy-meson-axg-mipi-pcie-analog.o
-283
drivers/phy/amlogic/phy-meson-gxl-usb3.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Meson GXL USB3 PHY and OTG mode detection driver 4 - * 5 - * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com> 6 - */ 7 - 8 - #include <linux/bitfield.h> 9 - #include <linux/bitops.h> 10 - #include <linux/clk.h> 11 - #include <linux/module.h> 12 - #include <linux/of_device.h> 13 - #include <linux/phy/phy.h> 14 - #include <linux/regmap.h> 15 - #include <linux/reset.h> 16 - #include <linux/platform_device.h> 17 - 18 - #define USB_R0 0x00 19 - #define USB_R0_P30_FSEL_MASK GENMASK(5, 0) 20 - #define USB_R0_P30_PHY_RESET BIT(6) 21 - #define USB_R0_P30_TEST_POWERDOWN_HSP BIT(7) 22 - #define USB_R0_P30_TEST_POWERDOWN_SSP BIT(8) 23 - #define USB_R0_P30_ACJT_LEVEL_MASK GENMASK(13, 9) 24 - #define USB_R0_P30_TX_BOOST_LEVEL_MASK GENMASK(16, 14) 25 - #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17) 26 - #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18) 27 - #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19) 28 - #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29) 29 - #define USB_R0_U2D_ACT BIT(31) 30 - 31 - #define USB_R1 0x04 32 - #define USB_R1_U3H_BIGENDIAN_GS BIT(0) 33 - #define USB_R1_U3H_PME_ENABLE BIT(1) 34 - #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(6, 2) 35 - #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(11, 7) 36 - #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(15, 12) 37 - #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16) 38 - #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17) 39 - #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18) 40 - #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19) 41 - #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25) 42 - 43 - #define USB_R2 0x08 44 - #define USB_R2_P30_CR_DATA_IN_MASK GENMASK(15, 0) 45 - #define USB_R2_P30_CR_READ BIT(16) 46 - #define USB_R2_P30_CR_WRITE BIT(17) 47 - #define USB_R2_P30_CR_CAP_ADDR BIT(18) 48 - #define USB_R2_P30_CR_CAP_DATA BIT(19) 49 - #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20) 50 - #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26) 51 - 52 - #define USB_R3 0x0c 53 - #define USB_R3_P30_SSC_ENABLE BIT(0) 54 - #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1) 55 - #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4) 56 - #define USB_R3_P30_REF_SSP_EN BIT(13) 57 - #define USB_R3_P30_LOS_BIAS_MASK GENMASK(18, 16) 58 - #define USB_R3_P30_LOS_LEVEL_MASK GENMASK(23, 19) 59 - #define USB_R3_P30_MPLL_MULTIPLIER_MASK GENMASK(30, 24) 60 - 61 - #define USB_R4 0x10 62 - #define USB_R4_P21_PORT_RESET_0 BIT(0) 63 - #define USB_R4_P21_SLEEP_M0 BIT(1) 64 - #define USB_R4_MEM_PD_MASK GENMASK(3, 2) 65 - #define USB_R4_P21_ONLY BIT(4) 66 - 67 - #define USB_R5 0x14 68 - #define USB_R5_ID_DIG_SYNC BIT(0) 69 - #define USB_R5_ID_DIG_REG BIT(1) 70 - #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2) 71 - #define USB_R5_ID_DIG_EN_0 BIT(4) 72 - #define USB_R5_ID_DIG_EN_1 BIT(5) 73 - #define USB_R5_ID_DIG_CURR BIT(6) 74 - #define USB_R5_ID_DIG_IRQ BIT(7) 75 - #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8) 76 - #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16) 77 - 78 - /* read-only register */ 79 - #define USB_R6 0x18 80 - #define USB_R6_P30_CR_DATA_OUT_MASK GENMASK(15, 0) 81 - #define USB_R6_P30_CR_ACK BIT(16) 82 - 83 - struct phy_meson_gxl_usb3_priv { 84 - struct regmap *regmap; 85 - enum phy_mode mode; 86 - struct clk *clk_phy; 87 - struct clk *clk_peripheral; 88 - struct reset_control *reset; 89 - }; 90 - 91 - static const struct regmap_config phy_meson_gxl_usb3_regmap_conf = { 92 - .reg_bits = 8, 93 - .val_bits = 32, 94 - .reg_stride = 4, 95 - .max_register = USB_R6, 96 - }; 97 - 98 - static int phy_meson_gxl_usb3_power_on(struct phy *phy) 99 - { 100 - struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 101 - 102 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_EN_0, 103 - USB_R5_ID_DIG_EN_0); 104 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_EN_1, 105 - USB_R5_ID_DIG_EN_1); 106 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_TH_MASK, 107 - FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff)); 108 - 109 - return 0; 110 - } 111 - 112 - static int phy_meson_gxl_usb3_power_off(struct phy *phy) 113 - { 114 - struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 115 - 116 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_EN_0, 0); 117 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_EN_1, 0); 118 - 119 - return 0; 120 - } 121 - 122 - static int phy_meson_gxl_usb3_set_mode(struct phy *phy, 123 - enum phy_mode mode, int submode) 124 - { 125 - struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 126 - 127 - switch (mode) { 128 - case PHY_MODE_USB_HOST: 129 - regmap_update_bits(priv->regmap, USB_R0, USB_R0_U2D_ACT, 0); 130 - regmap_update_bits(priv->regmap, USB_R4, USB_R4_P21_SLEEP_M0, 131 - 0); 132 - break; 133 - 134 - case PHY_MODE_USB_DEVICE: 135 - regmap_update_bits(priv->regmap, USB_R0, USB_R0_U2D_ACT, 136 - USB_R0_U2D_ACT); 137 - regmap_update_bits(priv->regmap, USB_R4, USB_R4_P21_SLEEP_M0, 138 - USB_R4_P21_SLEEP_M0); 139 - break; 140 - 141 - default: 142 - dev_err(&phy->dev, "unsupported PHY mode %d\n", mode); 143 - return -EINVAL; 144 - } 145 - 146 - priv->mode = mode; 147 - 148 - return 0; 149 - } 150 - 151 - static int phy_meson_gxl_usb3_init(struct phy *phy) 152 - { 153 - struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 154 - int ret; 155 - 156 - ret = reset_control_reset(priv->reset); 157 - if (ret) 158 - goto err; 159 - 160 - ret = clk_prepare_enable(priv->clk_phy); 161 - if (ret) 162 - goto err; 163 - 164 - ret = clk_prepare_enable(priv->clk_peripheral); 165 - if (ret) 166 - goto err_disable_clk_phy; 167 - 168 - ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode, 0); 169 - if (ret) 170 - goto err_disable_clk_peripheral; 171 - 172 - regmap_update_bits(priv->regmap, USB_R1, 173 - USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 174 - FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20)); 175 - 176 - return 0; 177 - 178 - err_disable_clk_peripheral: 179 - clk_disable_unprepare(priv->clk_peripheral); 180 - err_disable_clk_phy: 181 - clk_disable_unprepare(priv->clk_phy); 182 - err: 183 - return ret; 184 - } 185 - 186 - static int phy_meson_gxl_usb3_exit(struct phy *phy) 187 - { 188 - struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 189 - 190 - clk_disable_unprepare(priv->clk_peripheral); 191 - clk_disable_unprepare(priv->clk_phy); 192 - 193 - return 0; 194 - } 195 - 196 - static const struct phy_ops phy_meson_gxl_usb3_ops = { 197 - .power_on = phy_meson_gxl_usb3_power_on, 198 - .power_off = phy_meson_gxl_usb3_power_off, 199 - .set_mode = phy_meson_gxl_usb3_set_mode, 200 - .init = phy_meson_gxl_usb3_init, 201 - .exit = phy_meson_gxl_usb3_exit, 202 - .owner = THIS_MODULE, 203 - }; 204 - 205 - static int phy_meson_gxl_usb3_probe(struct platform_device *pdev) 206 - { 207 - struct device *dev = &pdev->dev; 208 - struct device_node *np = dev->of_node; 209 - struct phy_meson_gxl_usb3_priv *priv; 210 - struct resource *res; 211 - struct phy *phy; 212 - struct phy_provider *phy_provider; 213 - void __iomem *base; 214 - int ret; 215 - 216 - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 217 - if (!priv) 218 - return -ENOMEM; 219 - 220 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 221 - base = devm_ioremap_resource(dev, res); 222 - if (IS_ERR(base)) 223 - return PTR_ERR(base); 224 - 225 - priv->regmap = devm_regmap_init_mmio(dev, base, 226 - &phy_meson_gxl_usb3_regmap_conf); 227 - if (IS_ERR(priv->regmap)) 228 - return PTR_ERR(priv->regmap); 229 - 230 - priv->clk_phy = devm_clk_get(dev, "phy"); 231 - if (IS_ERR(priv->clk_phy)) 232 - return PTR_ERR(priv->clk_phy); 233 - 234 - priv->clk_peripheral = devm_clk_get(dev, "peripheral"); 235 - if (IS_ERR(priv->clk_peripheral)) 236 - return PTR_ERR(priv->clk_peripheral); 237 - 238 - priv->reset = devm_reset_control_array_get_shared(dev); 239 - if (IS_ERR(priv->reset)) 240 - return PTR_ERR(priv->reset); 241 - 242 - /* 243 - * default to host mode as hardware defaults and/or boot-loader 244 - * behavior can result in this PHY starting up in device mode. this 245 - * default and the initialization in phy_meson_gxl_usb3_init ensure 246 - * that we reproducibly start in a known mode on all devices. 247 - */ 248 - priv->mode = PHY_MODE_USB_HOST; 249 - 250 - phy = devm_phy_create(dev, np, &phy_meson_gxl_usb3_ops); 251 - if (IS_ERR(phy)) { 252 - ret = PTR_ERR(phy); 253 - if (ret != -EPROBE_DEFER) 254 - dev_err(dev, "failed to create PHY\n"); 255 - 256 - return ret; 257 - } 258 - 259 - phy_set_drvdata(phy, priv); 260 - 261 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 262 - 263 - return PTR_ERR_OR_ZERO(phy_provider); 264 - } 265 - 266 - static const struct of_device_id phy_meson_gxl_usb3_of_match[] = { 267 - { .compatible = "amlogic,meson-gxl-usb3-phy", }, 268 - { }, 269 - }; 270 - MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb3_of_match); 271 - 272 - static struct platform_driver phy_meson_gxl_usb3_driver = { 273 - .probe = phy_meson_gxl_usb3_probe, 274 - .driver = { 275 - .name = "phy-meson-gxl-usb3", 276 - .of_match_table = phy_meson_gxl_usb3_of_match, 277 - }, 278 - }; 279 - module_platform_driver(phy_meson_gxl_usb3_driver); 280 - 281 - MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); 282 - MODULE_DESCRIPTION("Meson GXL USB3 PHY and OTG detection driver"); 283 - MODULE_LICENSE("GPL v2");
+98 -51
drivers/phy/amlogic/phy-meson8b-usb2.c
··· 10 10 #include <linux/io.h> 11 11 #include <linux/module.h> 12 12 #include <linux/of_device.h> 13 + #include <linux/property.h> 14 + #include <linux/regmap.h> 13 15 #include <linux/reset.h> 14 16 #include <linux/phy/phy.h> 15 17 #include <linux/platform_device.h> ··· 78 76 #define REG_ADP_BC_ACA_PIN_FLOAT BIT(26) 79 77 80 78 #define REG_DBG_UART 0x10 79 + #define REG_DBG_UART_BYPASS_SEL BIT(0) 80 + #define REG_DBG_UART_BYPASS_DM_EN BIT(1) 81 + #define REG_DBG_UART_BYPASS_DP_EN BIT(2) 82 + #define REG_DBG_UART_BYPASS_DM_DATA BIT(3) 83 + #define REG_DBG_UART_BYPASS_DP_DATA BIT(4) 84 + #define REG_DBG_UART_FSV_MINUS BIT(5) 85 + #define REG_DBG_UART_FSV_PLUS BIT(6) 86 + #define REG_DBG_UART_FSV_BURN_IN_TEST BIT(7) 87 + #define REG_DBG_UART_LOOPBACK_EN_B BIT(8) 88 + #define REG_DBG_UART_SET_IDDQ BIT(9) 89 + #define REG_DBG_UART_ATE_RESET BIT(10) 81 90 82 91 #define REG_TEST 0x14 83 92 #define REG_TEST_DATA_IN_MASK GENMASK(3, 0) ··· 117 104 #define RESET_COMPLETE_TIME 500 118 105 #define ACA_ENABLE_COMPLETE_TIME 50 119 106 120 - struct phy_meson8b_usb2_priv { 121 - void __iomem *regs; 122 - enum usb_dr_mode dr_mode; 123 - struct clk *clk_usb_general; 124 - struct clk *clk_usb; 125 - struct reset_control *reset; 107 + struct phy_meson8b_usb2_match_data { 108 + bool host_enable_aca; 126 109 }; 127 110 128 - static u32 phy_meson8b_usb2_read(struct phy_meson8b_usb2_priv *phy_priv, 129 - u32 reg) 130 - { 131 - return readl(phy_priv->regs + reg); 132 - } 111 + struct phy_meson8b_usb2_priv { 112 + struct regmap *regmap; 113 + enum usb_dr_mode dr_mode; 114 + struct clk *clk_usb_general; 115 + struct clk *clk_usb; 116 + struct reset_control *reset; 117 + const struct phy_meson8b_usb2_match_data *match; 118 + }; 133 119 134 - static void phy_meson8b_usb2_mask_bits(struct phy_meson8b_usb2_priv *phy_priv, 135 - u32 reg, u32 mask, u32 value) 136 - { 137 - u32 data; 138 - 139 - data = phy_meson8b_usb2_read(phy_priv, reg); 140 - data &= ~mask; 141 - data |= (value & mask); 142 - 143 - writel(data, phy_priv->regs + reg); 144 - } 120 + static const struct regmap_config phy_meson8b_usb2_regmap_conf = { 121 + .reg_bits = 8, 122 + .val_bits = 32, 123 + .reg_stride = 4, 124 + .max_register = REG_TUNE, 125 + }; 145 126 146 127 static int phy_meson8b_usb2_power_on(struct phy *phy) 147 128 { 148 129 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); 130 + u32 reg; 149 131 int ret; 150 132 151 133 if (!IS_ERR_OR_NULL(priv->reset)) { ··· 164 156 return ret; 165 157 } 166 158 167 - phy_meson8b_usb2_mask_bits(priv, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, 168 - REG_CONFIG_CLK_32k_ALTSEL); 159 + regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, 160 + REG_CONFIG_CLK_32k_ALTSEL); 169 161 170 - phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, 171 - 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); 162 + regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, 163 + 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); 172 164 173 - phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_FSEL_MASK, 174 - 0x5 << REG_CTRL_FSEL_SHIFT); 165 + regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK, 166 + 0x5 << REG_CTRL_FSEL_SHIFT); 175 167 176 168 /* reset the PHY */ 177 - phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET, 178 - REG_CTRL_POWER_ON_RESET); 169 + regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 170 + REG_CTRL_POWER_ON_RESET); 179 171 udelay(RESET_COMPLETE_TIME); 180 - phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); 172 + regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); 181 173 udelay(RESET_COMPLETE_TIME); 182 174 183 - phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, 184 - REG_CTRL_SOF_TOGGLE_OUT); 175 + regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, 176 + REG_CTRL_SOF_TOGGLE_OUT); 185 177 186 178 if (priv->dr_mode == USB_DR_MODE_HOST) { 187 - phy_meson8b_usb2_mask_bits(priv, REG_ADP_BC, 179 + regmap_update_bits(priv->regmap, REG_DBG_UART, 180 + REG_DBG_UART_SET_IDDQ, 0); 181 + 182 + if (priv->match->host_enable_aca) { 183 + regmap_update_bits(priv->regmap, REG_ADP_BC, 188 184 REG_ADP_BC_ACA_ENABLE, 189 185 REG_ADP_BC_ACA_ENABLE); 190 186 191 - udelay(ACA_ENABLE_COMPLETE_TIME); 187 + udelay(ACA_ENABLE_COMPLETE_TIME); 192 188 193 - if (phy_meson8b_usb2_read(priv, REG_ADP_BC) & 194 - REG_ADP_BC_ACA_PIN_FLOAT) { 195 - dev_warn(&phy->dev, "USB ID detect failed!\n"); 196 - clk_disable_unprepare(priv->clk_usb); 197 - clk_disable_unprepare(priv->clk_usb_general); 198 - return -EINVAL; 189 + regmap_read(priv->regmap, REG_ADP_BC, &reg); 190 + if (reg & REG_ADP_BC_ACA_PIN_FLOAT) { 191 + dev_warn(&phy->dev, "USB ID detect failed!\n"); 192 + clk_disable_unprepare(priv->clk_usb); 193 + clk_disable_unprepare(priv->clk_usb_general); 194 + return -EINVAL; 195 + } 199 196 } 200 197 } 201 198 ··· 210 197 static int phy_meson8b_usb2_power_off(struct phy *phy) 211 198 { 212 199 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); 200 + 201 + if (priv->dr_mode == USB_DR_MODE_HOST) 202 + regmap_update_bits(priv->regmap, REG_DBG_UART, 203 + REG_DBG_UART_SET_IDDQ, 204 + REG_DBG_UART_SET_IDDQ); 213 205 214 206 clk_disable_unprepare(priv->clk_usb); 215 207 clk_disable_unprepare(priv->clk_usb_general); ··· 231 213 static int phy_meson8b_usb2_probe(struct platform_device *pdev) 232 214 { 233 215 struct phy_meson8b_usb2_priv *priv; 234 - struct resource *res; 235 216 struct phy *phy; 236 217 struct phy_provider *phy_provider; 218 + void __iomem *base; 237 219 238 220 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 239 221 if (!priv) 240 222 return -ENOMEM; 241 223 242 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 243 - priv->regs = devm_ioremap_resource(&pdev->dev, res); 244 - if (IS_ERR(priv->regs)) 245 - return PTR_ERR(priv->regs); 224 + base = devm_platform_ioremap_resource(pdev, 0); 225 + if (IS_ERR(base)) 226 + return PTR_ERR(base); 227 + 228 + priv->match = device_get_match_data(&pdev->dev); 229 + if (!priv->match) 230 + return -ENODEV; 231 + 232 + priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, 233 + &phy_meson8b_usb2_regmap_conf); 234 + if (IS_ERR(priv->regmap)) 235 + return PTR_ERR(priv->regmap); 246 236 247 237 priv->clk_usb_general = devm_clk_get(&pdev->dev, "usb_general"); 248 238 if (IS_ERR(priv->clk_usb_general)) ··· 285 259 return PTR_ERR_OR_ZERO(phy_provider); 286 260 } 287 261 262 + static const struct phy_meson8b_usb2_match_data phy_meson8_usb2_match_data = { 263 + .host_enable_aca = false, 264 + }; 265 + 266 + static const struct phy_meson8b_usb2_match_data phy_meson8b_usb2_match_data = { 267 + .host_enable_aca = true, 268 + }; 269 + 288 270 static const struct of_device_id phy_meson8b_usb2_of_match[] = { 289 - { .compatible = "amlogic,meson8-usb2-phy", }, 290 - { .compatible = "amlogic,meson8b-usb2-phy", }, 291 - { .compatible = "amlogic,meson-gxbb-usb2-phy", }, 292 - { }, 271 + { 272 + .compatible = "amlogic,meson8-usb2-phy", 273 + .data = &phy_meson8_usb2_match_data 274 + }, 275 + { 276 + .compatible = "amlogic,meson8b-usb2-phy", 277 + .data = &phy_meson8b_usb2_match_data 278 + }, 279 + { 280 + .compatible = "amlogic,meson8m2-usb2-phy", 281 + .data = &phy_meson8b_usb2_match_data 282 + }, 283 + { 284 + .compatible = "amlogic,meson-gxbb-usb2-phy", 285 + .data = &phy_meson8b_usb2_match_data 286 + }, 287 + { /* sentinel */ } 293 288 }; 294 289 MODULE_DEVICE_TABLE(of, phy_meson8b_usb2_of_match); 295 290 ··· 324 277 module_platform_driver(phy_meson8b_usb2_driver); 325 278 326 279 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); 327 - MODULE_DESCRIPTION("Meson8, Meson8b and GXBB USB2 PHY driver"); 280 + MODULE_DESCRIPTION("Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY driver"); 328 281 MODULE_LICENSE("GPL");
+1 -1
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
··· 279 279 return IRQ_HANDLED; 280 280 } 281 281 282 - static struct phy_ops ops = { 282 + static const struct phy_ops ops = { 283 283 .init = ns2_drd_phy_init, 284 284 .power_on = ns2_drd_phy_poweron, 285 285 .power_off = ns2_drd_phy_poweroff,
+3 -54
drivers/phy/broadcom/phy-bcm-sr-usb.c
··· 16 16 }; 17 17 18 18 enum bcm_usb_phy_reg { 19 - PLL_NDIV_FRAC, 20 - PLL_NDIV_INT, 21 19 PLL_CTRL, 22 20 PHY_CTRL, 23 21 PHY_PLL_CTRL, ··· 29 31 }; 30 32 31 33 static const u8 bcm_usb_combo_phy_hs[] = { 32 - [PLL_NDIV_FRAC] = 0x04, 33 - [PLL_NDIV_INT] = 0x08, 34 34 [PLL_CTRL] = 0x0c, 35 35 [PHY_CTRL] = 0x10, 36 36 }; 37 37 38 - #define HSPLL_NDIV_INT_VAL 0x13 39 - #define HSPLL_NDIV_FRAC_VAL 0x1005 40 - 41 38 static const u8 bcm_usb_hs_phy[] = { 42 - [PLL_NDIV_FRAC] = 0x0, 43 - [PLL_NDIV_INT] = 0x4, 44 39 [PLL_CTRL] = 0x8, 45 40 [PHY_CTRL] = 0xc, 46 41 }; ··· 43 52 SSPLL_SUSPEND_EN, 44 53 PLL_SEQ_START, 45 54 PLL_LOCK, 46 - PLL_PDIV, 47 55 }; 48 56 49 57 static const u8 u3pll_ctrl[] = { ··· 56 66 #define HSPLL_PDIV_VAL 0x1 57 67 58 68 static const u8 u2pll_ctrl[] = { 59 - [PLL_PDIV] = 1, 60 69 [PLL_RESETB] = 5, 61 70 [PLL_LOCK] = 6, 62 71 }; 63 72 64 73 enum bcm_usb_phy_ctrl_bits { 65 74 CORERDY, 66 - AFE_LDO_PWRDWNB, 67 - AFE_PLL_PWRDWNB, 68 - AFE_BG_PWRDWNB, 69 - PHY_ISO, 70 75 PHY_RESETB, 71 76 PHY_PCTL, 72 77 }; 73 78 74 79 #define PHY_PCTL_MASK 0xffff 75 - /* 76 - * 0x0806 of PCTL_VAL has below bits set 77 - * BIT-8 : refclk divider 1 78 - * BIT-3:2: device mode; mode is not effect 79 - * BIT-1: soft reset active low 80 - */ 81 - #define HSPHY_PCTL_VAL 0x0806 82 80 #define SSPHY_PCTL_VAL 0x0006 83 81 84 82 static const u8 u3phy_ctrl[] = { ··· 76 98 77 99 static const u8 u2phy_ctrl[] = { 78 100 [CORERDY] = 0, 79 - [AFE_LDO_PWRDWNB] = 1, 80 - [AFE_PLL_PWRDWNB] = 2, 81 - [AFE_BG_PWRDWNB] = 3, 82 - [PHY_ISO] = 4, 83 101 [PHY_RESETB] = 5, 84 102 [PHY_PCTL] = 6, 85 103 }; ··· 160 186 int ret = 0; 161 187 void __iomem *regs = phy_cfg->regs; 162 188 const u8 *offset; 163 - u32 rd_data; 164 189 165 190 offset = phy_cfg->offset; 166 191 167 - writel(HSPLL_NDIV_INT_VAL, regs + offset[PLL_NDIV_INT]); 168 - writel(HSPLL_NDIV_FRAC_VAL, regs + offset[PLL_NDIV_FRAC]); 169 - 170 - rd_data = readl(regs + offset[PLL_CTRL]); 171 - rd_data &= ~(HSPLL_PDIV_MASK << u2pll_ctrl[PLL_PDIV]); 172 - rd_data |= (HSPLL_PDIV_VAL << u2pll_ctrl[PLL_PDIV]); 173 - writel(rd_data, regs + offset[PLL_CTRL]); 174 - 175 - /* Set Core Ready high */ 176 - bcm_usb_reg32_setbits(regs + offset[PHY_CTRL], 177 - BIT(u2phy_ctrl[CORERDY])); 178 - 179 - /* Maximum timeout for Core Ready done */ 180 - msleep(30); 181 - 192 + bcm_usb_reg32_clrbits(regs + offset[PLL_CTRL], 193 + BIT(u2pll_ctrl[PLL_RESETB])); 182 194 bcm_usb_reg32_setbits(regs + offset[PLL_CTRL], 183 195 BIT(u2pll_ctrl[PLL_RESETB])); 184 - bcm_usb_reg32_setbits(regs + offset[PHY_CTRL], 185 - BIT(u2phy_ctrl[PHY_RESETB])); 186 - 187 - 188 - rd_data = readl(regs + offset[PHY_CTRL]); 189 - rd_data &= ~(PHY_PCTL_MASK << u2phy_ctrl[PHY_PCTL]); 190 - rd_data |= (HSPHY_PCTL_VAL << u2phy_ctrl[PHY_PCTL]); 191 - writel(rd_data, regs + offset[PHY_CTRL]); 192 - 193 - /* Maximum timeout for PLL reset done */ 194 - msleep(30); 195 196 196 197 ret = bcm_usb_pll_lock_check(regs + offset[PLL_CTRL], 197 198 BIT(u2pll_ctrl[PLL_LOCK])); ··· 205 256 return ret; 206 257 } 207 258 208 - static struct phy_ops sr_phy_ops = { 259 + static const struct phy_ops sr_phy_ops = { 209 260 .init = bcm_usb_phy_init, 210 261 .reset = bcm_usb_phy_reset, 211 262 .owner = THIS_MODULE,
+8 -8
drivers/phy/broadcom/phy-brcm-usb.c
··· 39 39 u8 optional_reg; 40 40 }; 41 41 42 - static struct value_to_name_map brcm_dr_mode_to_name[] = { 42 + static const struct value_to_name_map brcm_dr_mode_to_name[] = { 43 43 { USB_CTLR_MODE_HOST, "host" }, 44 44 { USB_CTLR_MODE_DEVICE, "peripheral" }, 45 45 { USB_CTLR_MODE_DRD, "drd" }, 46 46 { USB_CTLR_MODE_TYPEC_PD, "typec-pd" } 47 47 }; 48 48 49 - static struct value_to_name_map brcm_dual_mode_to_name[] = { 49 + static const struct value_to_name_map brcm_dual_mode_to_name[] = { 50 50 { 0, "host" }, 51 51 { 1, "device" }, 52 52 { 2, "auto" }, ··· 138 138 return 0; 139 139 } 140 140 141 - static struct phy_ops brcm_usb_phy_ops = { 141 + static const struct phy_ops brcm_usb_phy_ops = { 142 142 .init = brcm_usb_phy_init, 143 143 .exit = brcm_usb_phy_exit, 144 144 .owner = THIS_MODULE, ··· 170 170 return ERR_PTR(-ENODEV); 171 171 } 172 172 173 - static int name_to_value(struct value_to_name_map *table, int count, 173 + static int name_to_value(const struct value_to_name_map *table, int count, 174 174 const char *name, int *value) 175 175 { 176 176 int x; ··· 185 185 return -EINVAL; 186 186 } 187 187 188 - static const char *value_to_name(struct value_to_name_map *table, int count, 188 + static const char *value_to_name(const struct value_to_name_map *table, int count, 189 189 int value) 190 190 { 191 191 if (value >= count) ··· 252 252 .attrs = brcm_usb_phy_attrs, 253 253 }; 254 254 255 - static struct match_chip_info chip_info_7216 = { 255 + static const struct match_chip_info chip_info_7216 = { 256 256 .init_func = &brcm_usb_dvr_init_7216, 257 257 .required_regs = { 258 258 BRCM_REGS_CTRL, ··· 262 262 }, 263 263 }; 264 264 265 - static struct match_chip_info chip_info_7211b0 = { 265 + static const struct match_chip_info chip_info_7211b0 = { 266 266 .init_func = &brcm_usb_dvr_init_7211b0, 267 267 .required_regs = { 268 268 BRCM_REGS_CTRL, ··· 275 275 .optional_reg = BRCM_REGS_BDC_EC, 276 276 }; 277 277 278 - static struct match_chip_info chip_info_7445 = { 278 + static const struct match_chip_info chip_info_7445 = { 279 279 .init_func = &brcm_usb_dvr_init_7445, 280 280 .required_regs = { 281 281 BRCM_REGS_CTRL,
+9
drivers/phy/cadence/Kconfig
··· 27 27 select GENERIC_PHY 28 28 help 29 29 Enable this to support the Cadence Sierra PHY driver 30 + 31 + config PHY_CADENCE_SALVO 32 + tristate "Cadence Salvo PHY Driver" 33 + depends on OF && HAS_IOMEM 34 + select GENERIC_PHY 35 + help 36 + Enable this to support the Cadence SALVO PHY driver, 37 + this PHY is a legacy PHY, and only are used for USB3 38 + and USB2.
+1
drivers/phy/cadence/Makefile
··· 2 2 obj-$(CONFIG_PHY_CADENCE_TORRENT) += phy-cadence-torrent.o 3 3 obj-$(CONFIG_PHY_CADENCE_DPHY) += cdns-dphy.o 4 4 obj-$(CONFIG_PHY_CADENCE_SIERRA) += phy-cadence-sierra.o 5 + obj-$(CONFIG_PHY_CADENCE_SALVO) += phy-cadence-salvo.o
+325
drivers/phy/cadence/phy-cadence-salvo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Salvo PHY is a 28nm PHY, it is a legacy PHY, and only 4 + * for USB3 and USB2. 5 + * 6 + * Copyright (c) 2019-2020 NXP 7 + */ 8 + 9 + #include <linux/clk.h> 10 + #include <linux/io.h> 11 + #include <linux/module.h> 12 + #include <linux/phy/phy.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/delay.h> 15 + #include <linux/of.h> 16 + #include <linux/of_platform.h> 17 + 18 + /* PHY register definition */ 19 + #define PHY_PMA_CMN_CTRL1 0xC800 20 + #define TB_ADDR_CMN_DIAG_HSCLK_SEL 0x01e0 21 + #define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR 0x0084 22 + #define TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR 0x0085 23 + #define TB_ADDR_CMN_PLL0_INTDIV 0x0094 24 + #define TB_ADDR_CMN_PLL0_FRACDIV 0x0095 25 + #define TB_ADDR_CMN_PLL0_HIGH_THR 0x0096 26 + #define TB_ADDR_CMN_PLL0_SS_CTRL1 0x0098 27 + #define TB_ADDR_CMN_PLL0_SS_CTRL2 0x0099 28 + #define TB_ADDR_CMN_PLL0_DSM_DIAG 0x0097 29 + #define TB_ADDR_CMN_DIAG_PLL0_OVRD 0x01c2 30 + #define TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD 0x01c0 31 + #define TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD 0x01c1 32 + #define TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE 0x01C5 33 + #define TB_ADDR_CMN_DIAG_PLL0_CP_TUNE 0x01C6 34 + #define TB_ADDR_CMN_DIAG_PLL0_LF_PROG 0x01C7 35 + #define TB_ADDR_CMN_DIAG_PLL0_TEST_MODE 0x01c4 36 + #define TB_ADDR_CMN_PSM_CLK_CTRL 0x0061 37 + #define TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR 0x40ea 38 + #define TB_ADDR_XCVR_PSM_RCTRL 0x4001 39 + #define TB_ADDR_TX_PSC_A0 0x4100 40 + #define TB_ADDR_TX_PSC_A1 0x4101 41 + #define TB_ADDR_TX_PSC_A2 0x4102 42 + #define TB_ADDR_TX_PSC_A3 0x4103 43 + #define TB_ADDR_TX_DIAG_ECTRL_OVRD 0x41f5 44 + #define TB_ADDR_TX_PSC_CAL 0x4106 45 + #define TB_ADDR_TX_PSC_RDY 0x4107 46 + #define TB_ADDR_RX_PSC_A0 0x8000 47 + #define TB_ADDR_RX_PSC_A1 0x8001 48 + #define TB_ADDR_RX_PSC_A2 0x8002 49 + #define TB_ADDR_RX_PSC_A3 0x8003 50 + #define TB_ADDR_RX_PSC_CAL 0x8006 51 + #define TB_ADDR_RX_PSC_RDY 0x8007 52 + #define TB_ADDR_TX_TXCC_MGNLS_MULT_000 0x4058 53 + #define TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY 0x41e7 54 + #define TB_ADDR_RX_SLC_CU_ITER_TMR 0x80e3 55 + #define TB_ADDR_RX_SIGDET_HL_FILT_TMR 0x8090 56 + #define TB_ADDR_RX_SAMP_DAC_CTRL 0x8058 57 + #define TB_ADDR_RX_DIAG_SIGDET_TUNE 0x81dc 58 + #define TB_ADDR_RX_DIAG_LFPSDET_TUNE2 0x81df 59 + #define TB_ADDR_RX_DIAG_BS_TM 0x81f5 60 + #define TB_ADDR_RX_DIAG_DFE_CTRL1 0x81d3 61 + #define TB_ADDR_RX_DIAG_ILL_IQE_TRIM4 0x81c7 62 + #define TB_ADDR_RX_DIAG_ILL_E_TRIM0 0x81c2 63 + #define TB_ADDR_RX_DIAG_ILL_IQ_TRIM0 0x81c1 64 + #define TB_ADDR_RX_DIAG_ILL_IQE_TRIM6 0x81c9 65 + #define TB_ADDR_RX_DIAG_RXFE_TM3 0x81f8 66 + #define TB_ADDR_RX_DIAG_RXFE_TM4 0x81f9 67 + #define TB_ADDR_RX_DIAG_LFPSDET_TUNE 0x81dd 68 + #define TB_ADDR_RX_DIAG_DFE_CTRL3 0x81d5 69 + #define TB_ADDR_RX_DIAG_SC2C_DELAY 0x81e1 70 + #define TB_ADDR_RX_REE_VGA_GAIN_NODFE 0x81bf 71 + #define TB_ADDR_XCVR_PSM_CAL_TMR 0x4002 72 + #define TB_ADDR_XCVR_PSM_A0BYP_TMR 0x4004 73 + #define TB_ADDR_XCVR_PSM_A0IN_TMR 0x4003 74 + #define TB_ADDR_XCVR_PSM_A1IN_TMR 0x4005 75 + #define TB_ADDR_XCVR_PSM_A2IN_TMR 0x4006 76 + #define TB_ADDR_XCVR_PSM_A3IN_TMR 0x4007 77 + #define TB_ADDR_XCVR_PSM_A4IN_TMR 0x4008 78 + #define TB_ADDR_XCVR_PSM_A5IN_TMR 0x4009 79 + #define TB_ADDR_XCVR_PSM_A0OUT_TMR 0x400a 80 + #define TB_ADDR_XCVR_PSM_A1OUT_TMR 0x400b 81 + #define TB_ADDR_XCVR_PSM_A2OUT_TMR 0x400c 82 + #define TB_ADDR_XCVR_PSM_A3OUT_TMR 0x400d 83 + #define TB_ADDR_XCVR_PSM_A4OUT_TMR 0x400e 84 + #define TB_ADDR_XCVR_PSM_A5OUT_TMR 0x400f 85 + #define TB_ADDR_TX_RCVDET_EN_TMR 0x4122 86 + #define TB_ADDR_TX_RCVDET_ST_TMR 0x4123 87 + #define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2 88 + #define TB_ADDR_TX_RCVDETSC_CTRL 0x4124 89 + 90 + /* TB_ADDR_TX_RCVDETSC_CTRL */ 91 + #define RXDET_IN_P3_32KHZ BIT(1) 92 + 93 + struct cdns_reg_pairs { 94 + u16 val; 95 + u32 off; 96 + }; 97 + 98 + struct cdns_salvo_data { 99 + u8 reg_offset_shift; 100 + struct cdns_reg_pairs *init_sequence_val; 101 + u8 init_sequence_length; 102 + }; 103 + 104 + struct cdns_salvo_phy { 105 + struct phy *phy; 106 + struct clk *clk; 107 + void __iomem *base; 108 + struct cdns_salvo_data *data; 109 + }; 110 + 111 + static const struct of_device_id cdns_salvo_phy_of_match[]; 112 + static u16 cdns_salvo_read(struct cdns_salvo_phy *salvo_phy, u32 reg) 113 + { 114 + return (u16)readl(salvo_phy->base + 115 + reg * (1 << salvo_phy->data->reg_offset_shift)); 116 + } 117 + 118 + static void cdns_salvo_write(struct cdns_salvo_phy *salvo_phy, 119 + u32 reg, u16 val) 120 + { 121 + writel(val, salvo_phy->base + 122 + reg * (1 << salvo_phy->data->reg_offset_shift)); 123 + } 124 + 125 + /* 126 + * Below bringup sequence pair are from Cadence PHY's User Guide 127 + * and NXP platform tuning results. 128 + */ 129 + static struct cdns_reg_pairs cdns_nxp_sequence_pair[] = { 130 + {0x0830, PHY_PMA_CMN_CTRL1}, 131 + {0x0010, TB_ADDR_CMN_DIAG_HSCLK_SEL}, 132 + {0x00f0, TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR}, 133 + {0x0018, TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR}, 134 + {0x00d0, TB_ADDR_CMN_PLL0_INTDIV}, 135 + {0x4aaa, TB_ADDR_CMN_PLL0_FRACDIV}, 136 + {0x0034, TB_ADDR_CMN_PLL0_HIGH_THR}, 137 + {0x01ee, TB_ADDR_CMN_PLL0_SS_CTRL1}, 138 + {0x7f03, TB_ADDR_CMN_PLL0_SS_CTRL2}, 139 + {0x0020, TB_ADDR_CMN_PLL0_DSM_DIAG}, 140 + {0x0000, TB_ADDR_CMN_DIAG_PLL0_OVRD}, 141 + {0x0000, TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD}, 142 + {0x0000, TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD}, 143 + {0x0007, TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE}, 144 + {0x0027, TB_ADDR_CMN_DIAG_PLL0_CP_TUNE}, 145 + {0x0008, TB_ADDR_CMN_DIAG_PLL0_LF_PROG}, 146 + {0x0022, TB_ADDR_CMN_DIAG_PLL0_TEST_MODE}, 147 + {0x000a, TB_ADDR_CMN_PSM_CLK_CTRL}, 148 + {0x0139, TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR}, 149 + {0xbefc, TB_ADDR_XCVR_PSM_RCTRL}, 150 + 151 + {0x7799, TB_ADDR_TX_PSC_A0}, 152 + {0x7798, TB_ADDR_TX_PSC_A1}, 153 + {0x509b, TB_ADDR_TX_PSC_A2}, 154 + {0x0003, TB_ADDR_TX_DIAG_ECTRL_OVRD}, 155 + {0x509b, TB_ADDR_TX_PSC_A3}, 156 + {0x2090, TB_ADDR_TX_PSC_CAL}, 157 + {0x2090, TB_ADDR_TX_PSC_RDY}, 158 + 159 + {0xA6FD, TB_ADDR_RX_PSC_A0}, 160 + {0xA6FD, TB_ADDR_RX_PSC_A1}, 161 + {0xA410, TB_ADDR_RX_PSC_A2}, 162 + {0x2410, TB_ADDR_RX_PSC_A3}, 163 + 164 + {0x23FF, TB_ADDR_RX_PSC_CAL}, 165 + {0x2010, TB_ADDR_RX_PSC_RDY}, 166 + 167 + {0x0020, TB_ADDR_TX_TXCC_MGNLS_MULT_000}, 168 + {0x00ff, TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY}, 169 + {0x0002, TB_ADDR_RX_SLC_CU_ITER_TMR}, 170 + {0x0013, TB_ADDR_RX_SIGDET_HL_FILT_TMR}, 171 + {0x0000, TB_ADDR_RX_SAMP_DAC_CTRL}, 172 + {0x1004, TB_ADDR_RX_DIAG_SIGDET_TUNE}, 173 + {0x4041, TB_ADDR_RX_DIAG_LFPSDET_TUNE2}, 174 + {0x0480, TB_ADDR_RX_DIAG_BS_TM}, 175 + {0x8006, TB_ADDR_RX_DIAG_DFE_CTRL1}, 176 + {0x003f, TB_ADDR_RX_DIAG_ILL_IQE_TRIM4}, 177 + {0x543f, TB_ADDR_RX_DIAG_ILL_E_TRIM0}, 178 + {0x543f, TB_ADDR_RX_DIAG_ILL_IQ_TRIM0}, 179 + {0x0000, TB_ADDR_RX_DIAG_ILL_IQE_TRIM6}, 180 + {0x8000, TB_ADDR_RX_DIAG_RXFE_TM3}, 181 + {0x0003, TB_ADDR_RX_DIAG_RXFE_TM4}, 182 + {0x2408, TB_ADDR_RX_DIAG_LFPSDET_TUNE}, 183 + {0x05ca, TB_ADDR_RX_DIAG_DFE_CTRL3}, 184 + {0x0258, TB_ADDR_RX_DIAG_SC2C_DELAY}, 185 + {0x1fff, TB_ADDR_RX_REE_VGA_GAIN_NODFE}, 186 + 187 + {0x02c6, TB_ADDR_XCVR_PSM_CAL_TMR}, 188 + {0x0002, TB_ADDR_XCVR_PSM_A0BYP_TMR}, 189 + {0x02c6, TB_ADDR_XCVR_PSM_A0IN_TMR}, 190 + {0x0010, TB_ADDR_XCVR_PSM_A1IN_TMR}, 191 + {0x0010, TB_ADDR_XCVR_PSM_A2IN_TMR}, 192 + {0x0010, TB_ADDR_XCVR_PSM_A3IN_TMR}, 193 + {0x0010, TB_ADDR_XCVR_PSM_A4IN_TMR}, 194 + {0x0010, TB_ADDR_XCVR_PSM_A5IN_TMR}, 195 + 196 + {0x0002, TB_ADDR_XCVR_PSM_A0OUT_TMR}, 197 + {0x0002, TB_ADDR_XCVR_PSM_A1OUT_TMR}, 198 + {0x0002, TB_ADDR_XCVR_PSM_A2OUT_TMR}, 199 + {0x0002, TB_ADDR_XCVR_PSM_A3OUT_TMR}, 200 + {0x0002, TB_ADDR_XCVR_PSM_A4OUT_TMR}, 201 + {0x0002, TB_ADDR_XCVR_PSM_A5OUT_TMR}, 202 + /* Change rx detect parameter */ 203 + {0x0960, TB_ADDR_TX_RCVDET_EN_TMR}, 204 + {0x01e0, TB_ADDR_TX_RCVDET_ST_TMR}, 205 + {0x0090, TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR}, 206 + }; 207 + 208 + static int cdns_salvo_phy_init(struct phy *phy) 209 + { 210 + struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy); 211 + struct cdns_salvo_data *data = salvo_phy->data; 212 + int ret, i; 213 + u16 value; 214 + 215 + ret = clk_prepare_enable(salvo_phy->clk); 216 + if (ret) 217 + return ret; 218 + 219 + for (i = 0; i < data->init_sequence_length; i++) { 220 + struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i; 221 + 222 + cdns_salvo_write(salvo_phy, reg_pair->off, reg_pair->val); 223 + } 224 + 225 + /* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */ 226 + value = cdns_salvo_read(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL); 227 + value |= RXDET_IN_P3_32KHZ; 228 + cdns_salvo_write(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL, 229 + RXDET_IN_P3_32KHZ); 230 + 231 + udelay(10); 232 + 233 + clk_disable_unprepare(salvo_phy->clk); 234 + 235 + return ret; 236 + } 237 + 238 + static int cdns_salvo_phy_power_on(struct phy *phy) 239 + { 240 + struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy); 241 + 242 + return clk_prepare_enable(salvo_phy->clk); 243 + } 244 + 245 + static int cdns_salvo_phy_power_off(struct phy *phy) 246 + { 247 + struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy); 248 + 249 + clk_disable_unprepare(salvo_phy->clk); 250 + 251 + return 0; 252 + } 253 + 254 + static struct phy_ops cdns_salvo_phy_ops = { 255 + .init = cdns_salvo_phy_init, 256 + .power_on = cdns_salvo_phy_power_on, 257 + .power_off = cdns_salvo_phy_power_off, 258 + .owner = THIS_MODULE, 259 + }; 260 + 261 + static int cdns_salvo_phy_probe(struct platform_device *pdev) 262 + { 263 + struct phy_provider *phy_provider; 264 + struct device *dev = &pdev->dev; 265 + struct cdns_salvo_phy *salvo_phy; 266 + struct resource *res; 267 + const struct of_device_id *match; 268 + struct cdns_salvo_data *data; 269 + 270 + match = of_match_device(cdns_salvo_phy_of_match, dev); 271 + if (!match) 272 + return -EINVAL; 273 + 274 + data = (struct cdns_salvo_data *)match->data; 275 + salvo_phy = devm_kzalloc(dev, sizeof(*salvo_phy), GFP_KERNEL); 276 + if (!salvo_phy) 277 + return -ENOMEM; 278 + 279 + salvo_phy->data = data; 280 + salvo_phy->clk = devm_clk_get_optional(dev, "salvo_phy_clk"); 281 + if (IS_ERR(salvo_phy->clk)) 282 + return PTR_ERR(salvo_phy->clk); 283 + 284 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 285 + salvo_phy->base = devm_ioremap_resource(dev, res); 286 + if (IS_ERR(salvo_phy->base)) 287 + return PTR_ERR(salvo_phy->base); 288 + 289 + salvo_phy->phy = devm_phy_create(dev, NULL, &cdns_salvo_phy_ops); 290 + if (IS_ERR(salvo_phy->phy)) 291 + return PTR_ERR(salvo_phy->phy); 292 + 293 + phy_set_drvdata(salvo_phy->phy, salvo_phy); 294 + 295 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 296 + return PTR_ERR_OR_ZERO(phy_provider); 297 + } 298 + 299 + static const struct cdns_salvo_data cdns_nxp_salvo_data = { 300 + 2, 301 + cdns_nxp_sequence_pair, 302 + ARRAY_SIZE(cdns_nxp_sequence_pair), 303 + }; 304 + 305 + static const struct of_device_id cdns_salvo_phy_of_match[] = { 306 + { 307 + .compatible = "nxp,salvo-phy", 308 + .data = &cdns_nxp_salvo_data, 309 + }, 310 + {} 311 + }; 312 + MODULE_DEVICE_TABLE(of, cdns_salvo_phy_of_match); 313 + 314 + static struct platform_driver cdns_salvo_phy_driver = { 315 + .probe = cdns_salvo_phy_probe, 316 + .driver = { 317 + .name = "cdns-salvo-phy", 318 + .of_match_table = cdns_salvo_phy_of_match, 319 + } 320 + }; 321 + module_platform_driver(cdns_salvo_phy_driver); 322 + 323 + MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>"); 324 + MODULE_LICENSE("GPL v2"); 325 + MODULE_DESCRIPTION("Cadence SALVO PHY Driver");
+14 -13
drivers/phy/cadence/phy-cadence-sierra.c
··· 685 685 static 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 - {0x00A5, SIERRA_DET_STANDEC_C_PREG}, 688 + {0x55A5, SIERRA_DET_STANDEC_C_PREG}, 689 689 {0x69ad, SIERRA_DET_STANDEC_D_PREG}, 690 690 {0x0241, SIERRA_DET_STANDEC_E_PREG}, 691 - {0x0010, SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG}, 691 + {0x0110, SIERRA_PSM_LANECAL_DLY_A1_RESETS_PREG}, 692 692 {0x0014, SIERRA_PSM_A0IN_TMR_PREG}, 693 693 {0xCF00, SIERRA_PSM_DIAG_PREG}, 694 694 {0x001F, SIERRA_PSC_TX_A0_PREG}, ··· 696 696 {0x0003, SIERRA_PSC_TX_A2_PREG}, 697 697 {0x0003, SIERRA_PSC_TX_A3_PREG}, 698 698 {0x0FFF, SIERRA_PSC_RX_A0_PREG}, 699 - {0x0619, SIERRA_PSC_RX_A1_PREG}, 699 + {0x0003, SIERRA_PSC_RX_A1_PREG}, 700 700 {0x0003, SIERRA_PSC_RX_A2_PREG}, 701 701 {0x0001, SIERRA_PSC_RX_A3_PREG}, 702 702 {0x0001, SIERRA_PLLCTRL_SUBRATE_PREG}, ··· 705 705 {0x00CA, SIERRA_CLKPATH_BIASTRIM_PREG}, 706 706 {0x2512, SIERRA_DFE_BIASTRIM_PREG}, 707 707 {0x0000, SIERRA_DRVCTRL_ATTEN_PREG}, 708 - {0x873E, SIERRA_CLKPATHCTRL_TMR_PREG}, 709 - {0x03CF, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG}, 710 - {0x01CE, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG}, 708 + {0x823E, SIERRA_CLKPATHCTRL_TMR_PREG}, 709 + {0x078F, SIERRA_RX_CREQ_FLTR_A_MODE1_PREG}, 710 + {0x078F, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG}, 711 711 {0x7B3C, SIERRA_CREQ_CCLKDET_MODE01_PREG}, 712 - {0x033F, SIERRA_RX_CTLE_MAINTENANCE_PREG}, 712 + {0x023C, SIERRA_RX_CTLE_MAINTENANCE_PREG}, 713 713 {0x3232, SIERRA_CREQ_FSMCLK_SEL_PREG}, 714 714 {0x0000, SIERRA_CREQ_EQ_CTRL_PREG}, 715 - {0x8000, SIERRA_CREQ_SPARE_PREG}, 715 + {0x0000, SIERRA_CREQ_SPARE_PREG}, 716 716 {0xCC44, SIERRA_CREQ_EQ_OPEN_EYE_THRESH_PREG}, 717 - {0x8453, SIERRA_CTLELUT_CTRL_PREG}, 718 - {0x4110, SIERRA_DFE_ECMP_RATESEL_PREG}, 719 - {0x4110, SIERRA_DFE_SMP_RATESEL_PREG}, 720 - {0x0002, SIERRA_DEQ_PHALIGN_CTRL}, 717 + {0x8452, SIERRA_CTLELUT_CTRL_PREG}, 718 + {0x4121, SIERRA_DFE_ECMP_RATESEL_PREG}, 719 + {0x4121, SIERRA_DFE_SMP_RATESEL_PREG}, 720 + {0x0003, SIERRA_DEQ_PHALIGN_CTRL}, 721 721 {0x3200, SIERRA_DEQ_CONCUR_CTRL1_PREG}, 722 722 {0x5064, SIERRA_DEQ_CONCUR_CTRL2_PREG}, 723 723 {0x0030, SIERRA_DEQ_EPIPWR_CTRL2_PREG}, ··· 725 725 {0x5A5A, SIERRA_DEQ_ERRCMP_CTRL_PREG}, 726 726 {0x02F5, SIERRA_DEQ_OFFSET_CTRL_PREG}, 727 727 {0x02F5, SIERRA_DEQ_GAIN_CTRL_PREG}, 728 - {0x9A8A, SIERRA_DEQ_VGATUNE_CTRL_PREG}, 728 + {0x9999, SIERRA_DEQ_VGATUNE_CTRL_PREG}, 729 729 {0x0014, SIERRA_DEQ_GLUT0}, 730 730 {0x0014, SIERRA_DEQ_GLUT1}, 731 731 {0x0014, SIERRA_DEQ_GLUT2}, ··· 772 772 {0x000F, SIERRA_LFPSFILT_NS_PREG}, 773 773 {0x0009, SIERRA_LFPSFILT_RD_PREG}, 774 774 {0x0001, SIERRA_LFPSFILT_MP_PREG}, 775 + {0x6013, SIERRA_SIGDET_SUPPORT_PREG}, 775 776 {0x8013, SIERRA_SDFILT_H2L_A_PREG}, 776 777 {0x8009, SIERRA_SDFILT_L2H_PREG}, 777 778 {0x0024, SIERRA_RXBUFFER_CTLECTRL_PREG},
+15
drivers/phy/intel/Kconfig
··· 2 2 # 3 3 # Phy drivers for Intel Lightning Mountain(LGM) platform 4 4 # 5 + config PHY_INTEL_COMBO 6 + bool "Intel ComboPHY driver" 7 + depends on X86 || COMPILE_TEST 8 + depends on OF && HAS_IOMEM 9 + select MFD_SYSCON 10 + select GENERIC_PHY 11 + select REGMAP 12 + help 13 + Enable this to support Intel ComboPhy. 14 + 15 + This driver configures ComboPhy subsystem on Intel gateway 16 + chipsets which provides PHYs for various controllers, EMAC, 17 + SATA and PCIe. 18 + 5 19 config PHY_INTEL_EMMC 6 20 tristate "Intel EMMC PHY driver" 21 + depends on X86 || COMPILE_TEST 7 22 select GENERIC_PHY 8 23 help 9 24 Enable this to support the Intel EMMC PHY
+1
drivers/phy/intel/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 + obj-$(CONFIG_PHY_INTEL_COMBO) += phy-intel-combo.o 2 3 obj-$(CONFIG_PHY_INTEL_EMMC) += phy-intel-emmc.o
+632
drivers/phy/intel/phy-intel-combo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Intel Combo-PHY driver 4 + * 5 + * Copyright (C) 2019-2020 Intel Corporation. 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/clk.h> 10 + #include <linux/iopoll.h> 11 + #include <linux/mfd/syscon.h> 12 + #include <linux/module.h> 13 + #include <linux/mutex.h> 14 + #include <linux/of.h> 15 + #include <linux/phy/phy.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + #include <linux/reset.h> 19 + 20 + #include <dt-bindings/phy/phy.h> 21 + 22 + #define PCIE_PHY_GEN_CTRL 0x00 23 + #define PCIE_PHY_CLK_PAD BIT(17) 24 + 25 + #define PAD_DIS_CFG 0x174 26 + 27 + #define PCS_XF_ATE_OVRD_IN_2 0x3008 28 + #define ADAPT_REQ_MSK GENMASK(5, 4) 29 + 30 + #define PCS_XF_RX_ADAPT_ACK 0x3010 31 + #define RX_ADAPT_ACK_BIT BIT(0) 32 + 33 + #define CR_ADDR(addr, lane) (((addr) + (lane) * 0x100) << 2) 34 + #define REG_COMBO_MODE(x) ((x) * 0x200) 35 + #define REG_CLK_DISABLE(x) ((x) * 0x200 + 0x124) 36 + 37 + #define COMBO_PHY_ID(x) ((x)->parent->id) 38 + #define PHY_ID(x) ((x)->id) 39 + 40 + #define CLK_100MHZ 100000000 41 + #define CLK_156_25MHZ 156250000 42 + 43 + static const unsigned long intel_iphy_clk_rates[] = { 44 + CLK_100MHZ, CLK_156_25MHZ, CLK_100MHZ, 45 + }; 46 + 47 + enum { 48 + PHY_0, 49 + PHY_1, 50 + PHY_MAX_NUM 51 + }; 52 + 53 + /* 54 + * Clock Register bit fields to enable clocks 55 + * for ComboPhy according to the mode. 56 + */ 57 + enum intel_phy_mode { 58 + PHY_PCIE_MODE = 0, 59 + PHY_XPCS_MODE, 60 + PHY_SATA_MODE, 61 + }; 62 + 63 + /* ComboPhy mode Register values */ 64 + enum intel_combo_mode { 65 + PCIE0_PCIE1_MODE = 0, 66 + PCIE_DL_MODE, 67 + RXAUI_MODE, 68 + XPCS0_XPCS1_MODE, 69 + SATA0_SATA1_MODE, 70 + }; 71 + 72 + enum aggregated_mode { 73 + PHY_SL_MODE, 74 + PHY_DL_MODE, 75 + }; 76 + 77 + struct intel_combo_phy; 78 + 79 + struct intel_cbphy_iphy { 80 + struct phy *phy; 81 + struct intel_combo_phy *parent; 82 + struct reset_control *app_rst; 83 + u32 id; 84 + }; 85 + 86 + struct intel_combo_phy { 87 + struct device *dev; 88 + struct clk *core_clk; 89 + unsigned long clk_rate; 90 + void __iomem *app_base; 91 + void __iomem *cr_base; 92 + struct regmap *syscfg; 93 + struct regmap *hsiocfg; 94 + u32 id; 95 + u32 bid; 96 + struct reset_control *phy_rst; 97 + struct reset_control *core_rst; 98 + struct intel_cbphy_iphy iphy[PHY_MAX_NUM]; 99 + enum intel_phy_mode phy_mode; 100 + enum aggregated_mode aggr_mode; 101 + u32 init_cnt; 102 + struct mutex lock; 103 + }; 104 + 105 + static int intel_cbphy_iphy_enable(struct intel_cbphy_iphy *iphy, bool set) 106 + { 107 + struct intel_combo_phy *cbphy = iphy->parent; 108 + u32 mask = BIT(cbphy->phy_mode * 2 + iphy->id); 109 + u32 val; 110 + 111 + /* Register: 0 is enable, 1 is disable */ 112 + val = set ? 0 : mask; 113 + 114 + return regmap_update_bits(cbphy->hsiocfg, REG_CLK_DISABLE(cbphy->bid), 115 + mask, val); 116 + } 117 + 118 + static int intel_cbphy_pcie_refclk_cfg(struct intel_cbphy_iphy *iphy, bool set) 119 + { 120 + struct intel_combo_phy *cbphy = iphy->parent; 121 + u32 mask = BIT(cbphy->id * 2 + iphy->id); 122 + u32 val; 123 + 124 + /* Register: 0 is enable, 1 is disable */ 125 + val = set ? 0 : mask; 126 + 127 + return regmap_update_bits(cbphy->syscfg, PAD_DIS_CFG, mask, val); 128 + } 129 + 130 + static inline void combo_phy_w32_off_mask(void __iomem *base, unsigned int reg, 131 + u32 mask, u32 val) 132 + { 133 + u32 reg_val; 134 + 135 + reg_val = readl(base + reg); 136 + reg_val &= ~mask; 137 + reg_val |= FIELD_PREP(mask, val); 138 + writel(reg_val, base + reg); 139 + } 140 + 141 + static int intel_cbphy_iphy_cfg(struct intel_cbphy_iphy *iphy, 142 + int (*phy_cfg)(struct intel_cbphy_iphy *)) 143 + { 144 + struct intel_combo_phy *cbphy = iphy->parent; 145 + int ret; 146 + 147 + ret = phy_cfg(iphy); 148 + if (ret) 149 + return ret; 150 + 151 + if (cbphy->aggr_mode != PHY_DL_MODE) 152 + return 0; 153 + 154 + return phy_cfg(&cbphy->iphy[PHY_1]); 155 + } 156 + 157 + static int intel_cbphy_pcie_en_pad_refclk(struct intel_cbphy_iphy *iphy) 158 + { 159 + struct intel_combo_phy *cbphy = iphy->parent; 160 + int ret; 161 + 162 + ret = intel_cbphy_pcie_refclk_cfg(iphy, true); 163 + if (ret) { 164 + dev_err(cbphy->dev, "Failed to enable PCIe pad refclk\n"); 165 + return ret; 166 + } 167 + 168 + if (cbphy->init_cnt) 169 + return 0; 170 + 171 + combo_phy_w32_off_mask(cbphy->app_base, PCIE_PHY_GEN_CTRL, 172 + PCIE_PHY_CLK_PAD, 0); 173 + 174 + /* Delay for stable clock PLL */ 175 + usleep_range(50, 100); 176 + 177 + return 0; 178 + } 179 + 180 + static int intel_cbphy_pcie_dis_pad_refclk(struct intel_cbphy_iphy *iphy) 181 + { 182 + struct intel_combo_phy *cbphy = iphy->parent; 183 + int ret; 184 + 185 + ret = intel_cbphy_pcie_refclk_cfg(iphy, false); 186 + if (ret) { 187 + dev_err(cbphy->dev, "Failed to disable PCIe pad refclk\n"); 188 + return ret; 189 + } 190 + 191 + if (cbphy->init_cnt) 192 + return 0; 193 + 194 + combo_phy_w32_off_mask(cbphy->app_base, PCIE_PHY_GEN_CTRL, 195 + PCIE_PHY_CLK_PAD, 1); 196 + 197 + return 0; 198 + } 199 + 200 + static int intel_cbphy_set_mode(struct intel_combo_phy *cbphy) 201 + { 202 + enum intel_combo_mode cb_mode = PHY_PCIE_MODE; 203 + enum aggregated_mode aggr = cbphy->aggr_mode; 204 + struct device *dev = cbphy->dev; 205 + enum intel_phy_mode mode; 206 + int ret; 207 + 208 + mode = cbphy->phy_mode; 209 + 210 + switch (mode) { 211 + case PHY_PCIE_MODE: 212 + cb_mode = (aggr == PHY_DL_MODE) ? PCIE_DL_MODE : PCIE0_PCIE1_MODE; 213 + break; 214 + 215 + case PHY_XPCS_MODE: 216 + cb_mode = (aggr == PHY_DL_MODE) ? RXAUI_MODE : XPCS0_XPCS1_MODE; 217 + break; 218 + 219 + case PHY_SATA_MODE: 220 + if (aggr == PHY_DL_MODE) { 221 + dev_err(dev, "Mode:%u not support dual lane!\n", mode); 222 + return -EINVAL; 223 + } 224 + 225 + cb_mode = SATA0_SATA1_MODE; 226 + break; 227 + } 228 + 229 + ret = regmap_write(cbphy->hsiocfg, REG_COMBO_MODE(cbphy->bid), cb_mode); 230 + if (ret) 231 + dev_err(dev, "Failed to set ComboPhy mode: %d\n", ret); 232 + 233 + return ret; 234 + } 235 + 236 + static void intel_cbphy_rst_assert(struct intel_combo_phy *cbphy) 237 + { 238 + reset_control_assert(cbphy->core_rst); 239 + reset_control_assert(cbphy->phy_rst); 240 + } 241 + 242 + static void intel_cbphy_rst_deassert(struct intel_combo_phy *cbphy) 243 + { 244 + reset_control_deassert(cbphy->core_rst); 245 + reset_control_deassert(cbphy->phy_rst); 246 + /* Delay to ensure reset process is done */ 247 + usleep_range(10, 20); 248 + } 249 + 250 + static int intel_cbphy_iphy_power_on(struct intel_cbphy_iphy *iphy) 251 + { 252 + struct intel_combo_phy *cbphy = iphy->parent; 253 + int ret; 254 + 255 + if (!cbphy->init_cnt) { 256 + ret = clk_prepare_enable(cbphy->core_clk); 257 + if (ret) { 258 + dev_err(cbphy->dev, "Clock enable failed!\n"); 259 + return ret; 260 + } 261 + 262 + ret = clk_set_rate(cbphy->core_clk, cbphy->clk_rate); 263 + if (ret) { 264 + dev_err(cbphy->dev, "Clock freq set to %lu failed!\n", 265 + cbphy->clk_rate); 266 + goto clk_err; 267 + } 268 + 269 + intel_cbphy_rst_assert(cbphy); 270 + intel_cbphy_rst_deassert(cbphy); 271 + ret = intel_cbphy_set_mode(cbphy); 272 + if (ret) 273 + goto clk_err; 274 + } 275 + 276 + ret = intel_cbphy_iphy_enable(iphy, true); 277 + if (ret) { 278 + dev_err(cbphy->dev, "Failed enabling PHY core\n"); 279 + goto clk_err; 280 + } 281 + 282 + ret = reset_control_deassert(iphy->app_rst); 283 + if (ret) { 284 + dev_err(cbphy->dev, "PHY(%u:%u) reset deassert failed!\n", 285 + COMBO_PHY_ID(iphy), PHY_ID(iphy)); 286 + goto clk_err; 287 + } 288 + 289 + /* Delay to ensure reset process is done */ 290 + udelay(1); 291 + 292 + return 0; 293 + 294 + clk_err: 295 + clk_disable_unprepare(cbphy->core_clk); 296 + 297 + return ret; 298 + } 299 + 300 + static int intel_cbphy_iphy_power_off(struct intel_cbphy_iphy *iphy) 301 + { 302 + struct intel_combo_phy *cbphy = iphy->parent; 303 + int ret; 304 + 305 + ret = reset_control_assert(iphy->app_rst); 306 + if (ret) { 307 + dev_err(cbphy->dev, "PHY(%u:%u) reset assert failed!\n", 308 + COMBO_PHY_ID(iphy), PHY_ID(iphy)); 309 + return ret; 310 + } 311 + 312 + ret = intel_cbphy_iphy_enable(iphy, false); 313 + if (ret) { 314 + dev_err(cbphy->dev, "Failed disabling PHY core\n"); 315 + return ret; 316 + } 317 + 318 + if (cbphy->init_cnt) 319 + return 0; 320 + 321 + clk_disable_unprepare(cbphy->core_clk); 322 + intel_cbphy_rst_assert(cbphy); 323 + 324 + return 0; 325 + } 326 + 327 + static int intel_cbphy_init(struct phy *phy) 328 + { 329 + struct intel_cbphy_iphy *iphy = phy_get_drvdata(phy); 330 + struct intel_combo_phy *cbphy = iphy->parent; 331 + int ret; 332 + 333 + mutex_lock(&cbphy->lock); 334 + ret = intel_cbphy_iphy_cfg(iphy, intel_cbphy_iphy_power_on); 335 + if (ret) 336 + goto err; 337 + 338 + if (cbphy->phy_mode == PHY_PCIE_MODE) { 339 + ret = intel_cbphy_iphy_cfg(iphy, intel_cbphy_pcie_en_pad_refclk); 340 + if (ret) 341 + goto err; 342 + } 343 + 344 + cbphy->init_cnt++; 345 + 346 + err: 347 + mutex_unlock(&cbphy->lock); 348 + 349 + return ret; 350 + } 351 + 352 + static int intel_cbphy_exit(struct phy *phy) 353 + { 354 + struct intel_cbphy_iphy *iphy = phy_get_drvdata(phy); 355 + struct intel_combo_phy *cbphy = iphy->parent; 356 + int ret; 357 + 358 + mutex_lock(&cbphy->lock); 359 + cbphy->init_cnt--; 360 + if (cbphy->phy_mode == PHY_PCIE_MODE) { 361 + ret = intel_cbphy_iphy_cfg(iphy, intel_cbphy_pcie_dis_pad_refclk); 362 + if (ret) 363 + goto err; 364 + } 365 + 366 + ret = intel_cbphy_iphy_cfg(iphy, intel_cbphy_iphy_power_off); 367 + 368 + err: 369 + mutex_unlock(&cbphy->lock); 370 + 371 + return ret; 372 + } 373 + 374 + static int intel_cbphy_calibrate(struct phy *phy) 375 + { 376 + struct intel_cbphy_iphy *iphy = phy_get_drvdata(phy); 377 + struct intel_combo_phy *cbphy = iphy->parent; 378 + void __iomem *cr_base = cbphy->cr_base; 379 + int val, ret, id; 380 + 381 + if (cbphy->phy_mode != PHY_XPCS_MODE) 382 + return 0; 383 + 384 + id = PHY_ID(iphy); 385 + 386 + /* trigger auto RX adaptation */ 387 + combo_phy_w32_off_mask(cr_base, CR_ADDR(PCS_XF_ATE_OVRD_IN_2, id), 388 + ADAPT_REQ_MSK, 3); 389 + /* Wait RX adaptation to finish */ 390 + ret = readl_poll_timeout(cr_base + CR_ADDR(PCS_XF_RX_ADAPT_ACK, id), 391 + val, val & RX_ADAPT_ACK_BIT, 10, 5000); 392 + if (ret) 393 + dev_err(cbphy->dev, "RX Adaptation failed!\n"); 394 + else 395 + dev_dbg(cbphy->dev, "RX Adaptation success!\n"); 396 + 397 + /* Stop RX adaptation */ 398 + combo_phy_w32_off_mask(cr_base, CR_ADDR(PCS_XF_ATE_OVRD_IN_2, id), 399 + ADAPT_REQ_MSK, 0); 400 + 401 + return ret; 402 + } 403 + 404 + static int intel_cbphy_fwnode_parse(struct intel_combo_phy *cbphy) 405 + { 406 + struct device *dev = cbphy->dev; 407 + struct platform_device *pdev = to_platform_device(dev); 408 + struct fwnode_handle *fwnode = dev_fwnode(dev); 409 + struct fwnode_reference_args ref; 410 + int ret; 411 + u32 val; 412 + 413 + cbphy->core_clk = devm_clk_get(dev, NULL); 414 + if (IS_ERR(cbphy->core_clk)) { 415 + ret = PTR_ERR(cbphy->core_clk); 416 + if (ret != -EPROBE_DEFER) 417 + dev_err(dev, "Get clk failed:%d!\n", ret); 418 + return ret; 419 + } 420 + 421 + cbphy->core_rst = devm_reset_control_get_optional(dev, "core"); 422 + if (IS_ERR(cbphy->core_rst)) { 423 + ret = PTR_ERR(cbphy->core_rst); 424 + if (ret != -EPROBE_DEFER) 425 + dev_err(dev, "Get core reset control err: %d!\n", ret); 426 + return ret; 427 + } 428 + 429 + cbphy->phy_rst = devm_reset_control_get_optional(dev, "phy"); 430 + if (IS_ERR(cbphy->phy_rst)) { 431 + ret = PTR_ERR(cbphy->phy_rst); 432 + if (ret != -EPROBE_DEFER) 433 + dev_err(dev, "Get PHY reset control err: %d!\n", ret); 434 + return ret; 435 + } 436 + 437 + cbphy->iphy[0].app_rst = devm_reset_control_get_optional(dev, "iphy0"); 438 + if (IS_ERR(cbphy->iphy[0].app_rst)) { 439 + ret = PTR_ERR(cbphy->iphy[0].app_rst); 440 + if (ret != -EPROBE_DEFER) 441 + dev_err(dev, "Get phy0 reset control err: %d!\n", ret); 442 + return ret; 443 + } 444 + 445 + cbphy->iphy[1].app_rst = devm_reset_control_get_optional(dev, "iphy1"); 446 + if (IS_ERR(cbphy->iphy[1].app_rst)) { 447 + ret = PTR_ERR(cbphy->iphy[1].app_rst); 448 + if (ret != -EPROBE_DEFER) 449 + dev_err(dev, "Get phy1 reset control err: %d!\n", ret); 450 + return ret; 451 + } 452 + 453 + cbphy->app_base = devm_platform_ioremap_resource_byname(pdev, "app"); 454 + if (IS_ERR(cbphy->app_base)) 455 + return PTR_ERR(cbphy->app_base); 456 + 457 + cbphy->cr_base = devm_platform_ioremap_resource_byname(pdev, "core"); 458 + if (IS_ERR(cbphy->cr_base)) 459 + return PTR_ERR(cbphy->cr_base); 460 + 461 + /* 462 + * syscfg and hsiocfg variables stores the handle of the registers set 463 + * in which ComboPhy subsytem specific registers are subset. Using 464 + * Register map framework to access the registers set. 465 + */ 466 + ret = fwnode_property_get_reference_args(fwnode, "intel,syscfg", NULL, 467 + 1, 0, &ref); 468 + if (ret < 0) 469 + return ret; 470 + 471 + cbphy->id = ref.args[0]; 472 + cbphy->syscfg = device_node_to_regmap(to_of_node(ref.fwnode)); 473 + fwnode_handle_put(ref.fwnode); 474 + 475 + ret = fwnode_property_get_reference_args(fwnode, "intel,hsio", NULL, 1, 476 + 0, &ref); 477 + if (ret < 0) 478 + return ret; 479 + 480 + cbphy->bid = ref.args[0]; 481 + cbphy->hsiocfg = device_node_to_regmap(to_of_node(ref.fwnode)); 482 + fwnode_handle_put(ref.fwnode); 483 + 484 + ret = fwnode_property_read_u32_array(fwnode, "intel,phy-mode", &val, 1); 485 + if (ret) 486 + return ret; 487 + 488 + switch (val) { 489 + case PHY_TYPE_PCIE: 490 + cbphy->phy_mode = PHY_PCIE_MODE; 491 + break; 492 + 493 + case PHY_TYPE_SATA: 494 + cbphy->phy_mode = PHY_SATA_MODE; 495 + break; 496 + 497 + case PHY_TYPE_XPCS: 498 + cbphy->phy_mode = PHY_XPCS_MODE; 499 + break; 500 + 501 + default: 502 + dev_err(dev, "Invalid PHY mode: %u\n", val); 503 + return -EINVAL; 504 + } 505 + 506 + cbphy->clk_rate = intel_iphy_clk_rates[cbphy->phy_mode]; 507 + 508 + if (fwnode_property_present(fwnode, "intel,aggregation")) 509 + cbphy->aggr_mode = PHY_DL_MODE; 510 + else 511 + cbphy->aggr_mode = PHY_SL_MODE; 512 + 513 + return 0; 514 + } 515 + 516 + static const struct phy_ops intel_cbphy_ops = { 517 + .init = intel_cbphy_init, 518 + .exit = intel_cbphy_exit, 519 + .calibrate = intel_cbphy_calibrate, 520 + .owner = THIS_MODULE, 521 + }; 522 + 523 + static struct phy *intel_cbphy_xlate(struct device *dev, 524 + struct of_phandle_args *args) 525 + { 526 + struct intel_combo_phy *cbphy = dev_get_drvdata(dev); 527 + u32 iphy_id; 528 + 529 + if (args->args_count < 1) { 530 + dev_err(dev, "Invalid number of arguments\n"); 531 + return ERR_PTR(-EINVAL); 532 + } 533 + 534 + iphy_id = args->args[0]; 535 + if (iphy_id >= PHY_MAX_NUM) { 536 + dev_err(dev, "Invalid phy instance %d\n", iphy_id); 537 + return ERR_PTR(-EINVAL); 538 + } 539 + 540 + if (cbphy->aggr_mode == PHY_DL_MODE && iphy_id == PHY_1) { 541 + dev_err(dev, "Invalid. ComboPhy is in Dual lane mode %d\n", iphy_id); 542 + return ERR_PTR(-EINVAL); 543 + } 544 + 545 + return cbphy->iphy[iphy_id].phy; 546 + } 547 + 548 + static int intel_cbphy_create(struct intel_combo_phy *cbphy) 549 + { 550 + struct phy_provider *phy_provider; 551 + struct device *dev = cbphy->dev; 552 + struct intel_cbphy_iphy *iphy; 553 + int i; 554 + 555 + for (i = 0; i < PHY_MAX_NUM; i++) { 556 + iphy = &cbphy->iphy[i]; 557 + iphy->parent = cbphy; 558 + iphy->id = i; 559 + 560 + /* In dual lane mode skip phy creation for the second phy */ 561 + if (cbphy->aggr_mode == PHY_DL_MODE && iphy->id == PHY_1) 562 + continue; 563 + 564 + iphy->phy = devm_phy_create(dev, NULL, &intel_cbphy_ops); 565 + if (IS_ERR(iphy->phy)) { 566 + dev_err(dev, "PHY[%u:%u]: create PHY instance failed!\n", 567 + COMBO_PHY_ID(iphy), PHY_ID(iphy)); 568 + 569 + return PTR_ERR(iphy->phy); 570 + } 571 + 572 + phy_set_drvdata(iphy->phy, iphy); 573 + } 574 + 575 + dev_set_drvdata(dev, cbphy); 576 + phy_provider = devm_of_phy_provider_register(dev, intel_cbphy_xlate); 577 + if (IS_ERR(phy_provider)) 578 + dev_err(dev, "Register PHY provider failed!\n"); 579 + 580 + return PTR_ERR_OR_ZERO(phy_provider); 581 + } 582 + 583 + static int intel_cbphy_probe(struct platform_device *pdev) 584 + { 585 + struct device *dev = &pdev->dev; 586 + struct intel_combo_phy *cbphy; 587 + int ret; 588 + 589 + cbphy = devm_kzalloc(dev, sizeof(*cbphy), GFP_KERNEL); 590 + if (!cbphy) 591 + return -ENOMEM; 592 + 593 + cbphy->dev = dev; 594 + cbphy->init_cnt = 0; 595 + mutex_init(&cbphy->lock); 596 + ret = intel_cbphy_fwnode_parse(cbphy); 597 + if (ret) 598 + return ret; 599 + 600 + platform_set_drvdata(pdev, cbphy); 601 + 602 + return intel_cbphy_create(cbphy); 603 + } 604 + 605 + static int intel_cbphy_remove(struct platform_device *pdev) 606 + { 607 + struct intel_combo_phy *cbphy = platform_get_drvdata(pdev); 608 + 609 + intel_cbphy_rst_assert(cbphy); 610 + clk_disable_unprepare(cbphy->core_clk); 611 + return 0; 612 + } 613 + 614 + static const struct of_device_id of_intel_cbphy_match[] = { 615 + { .compatible = "intel,combo-phy" }, 616 + { .compatible = "intel,combophy-lgm" }, 617 + {} 618 + }; 619 + 620 + static struct platform_driver intel_cbphy_driver = { 621 + .probe = intel_cbphy_probe, 622 + .remove = intel_cbphy_remove, 623 + .driver = { 624 + .name = "intel-combo-phy", 625 + .of_match_table = of_intel_cbphy_match, 626 + } 627 + }; 628 + 629 + module_platform_driver(intel_cbphy_driver); 630 + 631 + MODULE_DESCRIPTION("Intel Combo-phy driver"); 632 + MODULE_LICENSE("GPL v2");
-2
drivers/phy/motorola/phy-cpcap-usb.c
··· 122 122 struct cpcap_phy_ddata { 123 123 struct regmap *reg; 124 124 struct device *dev; 125 - struct clk *refclk; 126 125 struct usb_phy phy; 127 126 struct delayed_work detect_work; 128 127 struct pinctrl *pins; ··· 706 707 707 708 usb_remove_phy(&ddata->phy); 708 709 cancel_delayed_work_sync(&ddata->detect_work); 709 - clk_unprepare(ddata->refclk); 710 710 regulator_disable(ddata->vusb); 711 711 712 712 return 0;
+17
drivers/phy/qualcomm/Kconfig
··· 18 18 depends on OF 19 19 select GENERIC_PHY 20 20 21 + config PHY_QCOM_IPQ4019_USB 22 + tristate "Qualcomm IPQ4019 USB PHY driver" 23 + depends on OF && (ARCH_QCOM || COMPILE_TEST) 24 + select GENERIC_PHY 25 + help 26 + Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. 27 + 21 28 config PHY_QCOM_IPQ806X_SATA 22 29 tristate "Qualcomm IPQ806x SATA SerDes/PHY driver" 23 30 depends on ARCH_QCOM ··· 91 84 help 92 85 Support for the USB high-speed ULPI compliant phy on Qualcomm 93 86 chipsets. 87 + 88 + config PHY_QCOM_USB_SNPS_FEMTO_V2 89 + tristate "Qualcomm SNPS FEMTO USB HS PHY V2 module" 90 + depends on OF && (ARCH_QCOM || COMPILE_TEST) 91 + select GENERIC_PHY 92 + help 93 + Enable support for the USB high-speed SNPS Femto phy on Qualcomm 94 + chipsets. This PHY has differences in the register map compared 95 + to the V1 variants. The PHY is paired with a Synopsys DWC3 USB 96 + controller on Qualcomm SOCs. 94 97 95 98 config PHY_QCOM_USB_HSIC 96 99 tristate "Qualcomm USB HSIC ULPI PHY module"
+2
drivers/phy/qualcomm/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_PHY_ATH79_USB) += phy-ath79-usb.o 3 3 obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o 4 + obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o 4 5 obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o 5 6 obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o 6 7 obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o ··· 13 12 obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o 14 13 obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o 15 14 obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o 15 + obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2)+= phy-qcom-snps-femto-v2.o
+148
drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2018 John Crispin <john@phrozen.org> 4 + * 5 + * Based on code from 6 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 7 + * 8 + */ 9 + 10 + #include <linux/delay.h> 11 + #include <linux/err.h> 12 + #include <linux/io.h> 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/mutex.h> 16 + #include <linux/of_platform.h> 17 + #include <linux/of_device.h> 18 + #include <linux/phy/phy.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/reset.h> 21 + 22 + struct ipq4019_usb_phy { 23 + struct device *dev; 24 + struct phy *phy; 25 + void __iomem *base; 26 + struct reset_control *por_rst; 27 + struct reset_control *srif_rst; 28 + }; 29 + 30 + static int ipq4019_ss_phy_power_off(struct phy *_phy) 31 + { 32 + struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); 33 + 34 + reset_control_assert(phy->por_rst); 35 + msleep(10); 36 + 37 + return 0; 38 + } 39 + 40 + static int ipq4019_ss_phy_power_on(struct phy *_phy) 41 + { 42 + struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); 43 + 44 + ipq4019_ss_phy_power_off(_phy); 45 + 46 + reset_control_deassert(phy->por_rst); 47 + 48 + return 0; 49 + } 50 + 51 + static struct phy_ops ipq4019_usb_ss_phy_ops = { 52 + .power_on = ipq4019_ss_phy_power_on, 53 + .power_off = ipq4019_ss_phy_power_off, 54 + }; 55 + 56 + static int ipq4019_hs_phy_power_off(struct phy *_phy) 57 + { 58 + struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); 59 + 60 + reset_control_assert(phy->por_rst); 61 + msleep(10); 62 + 63 + reset_control_assert(phy->srif_rst); 64 + msleep(10); 65 + 66 + return 0; 67 + } 68 + 69 + static int ipq4019_hs_phy_power_on(struct phy *_phy) 70 + { 71 + struct ipq4019_usb_phy *phy = phy_get_drvdata(_phy); 72 + 73 + ipq4019_hs_phy_power_off(_phy); 74 + 75 + reset_control_deassert(phy->srif_rst); 76 + msleep(10); 77 + 78 + reset_control_deassert(phy->por_rst); 79 + 80 + return 0; 81 + } 82 + 83 + static struct phy_ops ipq4019_usb_hs_phy_ops = { 84 + .power_on = ipq4019_hs_phy_power_on, 85 + .power_off = ipq4019_hs_phy_power_off, 86 + }; 87 + 88 + static const struct of_device_id ipq4019_usb_phy_of_match[] = { 89 + { .compatible = "qcom,usb-hs-ipq4019-phy", .data = &ipq4019_usb_hs_phy_ops}, 90 + { .compatible = "qcom,usb-ss-ipq4019-phy", .data = &ipq4019_usb_ss_phy_ops}, 91 + { }, 92 + }; 93 + MODULE_DEVICE_TABLE(of, ipq4019_usb_phy_of_match); 94 + 95 + static int ipq4019_usb_phy_probe(struct platform_device *pdev) 96 + { 97 + struct device *dev = &pdev->dev; 98 + struct resource *res; 99 + struct phy_provider *phy_provider; 100 + struct ipq4019_usb_phy *phy; 101 + 102 + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); 103 + if (!phy) 104 + return -ENOMEM; 105 + 106 + phy->dev = &pdev->dev; 107 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 108 + phy->base = devm_ioremap_resource(&pdev->dev, res); 109 + if (IS_ERR(phy->base)) { 110 + dev_err(dev, "failed to remap register memory\n"); 111 + return PTR_ERR(phy->base); 112 + } 113 + 114 + phy->por_rst = devm_reset_control_get(phy->dev, "por_rst"); 115 + if (IS_ERR(phy->por_rst)) { 116 + if (PTR_ERR(phy->por_rst) != -EPROBE_DEFER) 117 + dev_err(dev, "POR reset is missing\n"); 118 + return PTR_ERR(phy->por_rst); 119 + } 120 + 121 + phy->srif_rst = devm_reset_control_get_optional(phy->dev, "srif_rst"); 122 + if (IS_ERR(phy->srif_rst)) 123 + return PTR_ERR(phy->srif_rst); 124 + 125 + phy->phy = devm_phy_create(dev, NULL, of_device_get_match_data(dev)); 126 + if (IS_ERR(phy->phy)) { 127 + dev_err(dev, "failed to create PHY\n"); 128 + return PTR_ERR(phy->phy); 129 + } 130 + phy_set_drvdata(phy->phy, phy); 131 + 132 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 133 + 134 + return PTR_ERR_OR_ZERO(phy_provider); 135 + } 136 + 137 + static struct platform_driver ipq4019_usb_phy_driver = { 138 + .probe = ipq4019_usb_phy_probe, 139 + .driver = { 140 + .of_match_table = ipq4019_usb_phy_of_match, 141 + .name = "ipq4019-usb-phy", 142 + } 143 + }; 144 + module_platform_driver(ipq4019_usb_phy_driver); 145 + 146 + MODULE_DESCRIPTION("QCOM/IPQ4019 USB phy driver"); 147 + MODULE_AUTHOR("John Crispin <john@phrozen.org>"); 148 + MODULE_LICENSE("GPL v2");
+232 -22
drivers/phy/qualcomm/phy-qcom-qmp.c
··· 119 119 QPHY_PCS_AUTONOMOUS_MODE_CTRL, 120 120 QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, 121 121 QPHY_PCS_LFPS_RXTERM_IRQ_STATUS, 122 + QPHY_PCS_POWER_DOWN_CONTROL, 123 + /* Keep last to ensure regs_layout arrays are properly initialized */ 124 + QPHY_LAYOUT_SIZE 122 125 }; 123 126 124 - static const unsigned int msm8996_ufsphy_regs_layout[] = { 127 + static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 125 128 [QPHY_START_CTRL] = 0x00, 126 129 [QPHY_PCS_READY_STATUS] = 0x168, 127 130 }; 128 131 129 - static const unsigned int pciephy_regs_layout[] = { 132 + static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = { 130 133 [QPHY_COM_SW_RESET] = 0x400, 131 134 [QPHY_COM_POWER_DOWN_CONTROL] = 0x404, 132 135 [QPHY_COM_START_CONTROL] = 0x408, ··· 145 142 [QPHY_PCS_STATUS] = 0x174, 146 143 }; 147 144 148 - static const unsigned int usb3phy_regs_layout[] = { 145 + static const unsigned int usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { 149 146 [QPHY_FLL_CNTRL1] = 0xc0, 150 147 [QPHY_FLL_CNTRL2] = 0xc4, 151 148 [QPHY_FLL_CNT_VAL_L] = 0xc8, ··· 159 156 [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178, 160 157 }; 161 158 162 - static const unsigned int qmp_v3_usb3phy_regs_layout[] = { 159 + static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { 163 160 [QPHY_SW_RESET] = 0x00, 164 161 [QPHY_START_CTRL] = 0x08, 165 162 [QPHY_PCS_STATUS] = 0x174, ··· 168 165 [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170, 169 166 }; 170 167 171 - static const unsigned int sdm845_qmp_pciephy_regs_layout[] = { 168 + static const unsigned int sdm845_qmp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = { 172 169 [QPHY_SW_RESET] = 0x00, 173 170 [QPHY_START_CTRL] = 0x08, 174 171 [QPHY_PCS_STATUS] = 0x174, 175 172 }; 176 173 177 - static const unsigned int sdm845_qhp_pciephy_regs_layout[] = { 174 + static const unsigned int sdm845_qhp_pciephy_regs_layout[QPHY_LAYOUT_SIZE] = { 178 175 [QPHY_SW_RESET] = 0x00, 179 176 [QPHY_START_CTRL] = 0x08, 180 177 [QPHY_PCS_STATUS] = 0x2ac, 181 178 }; 182 179 183 - static const unsigned int sdm845_ufsphy_regs_layout[] = { 180 + static const unsigned int qmp_v4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { 181 + [QPHY_SW_RESET] = 0x00, 182 + [QPHY_START_CTRL] = 0x44, 183 + [QPHY_PCS_STATUS] = 0x14, 184 + [QPHY_PCS_POWER_DOWN_CONTROL] = 0x40, 185 + }; 186 + 187 + static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 184 188 [QPHY_START_CTRL] = 0x00, 185 189 [QPHY_PCS_READY_STATUS] = 0x160, 186 190 }; 187 191 188 - static const unsigned int sm8150_ufsphy_regs_layout[] = { 189 - [QPHY_START_CTRL] = QPHY_V4_PHY_START, 190 - [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_READY_STATUS, 191 - [QPHY_SW_RESET] = QPHY_V4_SW_RESET, 192 + static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = { 193 + [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START, 194 + [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS, 195 + [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET, 192 196 }; 193 197 194 198 static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = { ··· 1282 1272 }; 1283 1273 1284 1274 static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = { 1285 - QMP_PHY_INIT_CFG(QPHY_V4_RX_SIGDET_CTRL2, 0x6d), 1286 - QMP_PHY_INIT_CFG(QPHY_V4_TX_LARGE_AMP_DRV_LVL, 0x0a), 1287 - QMP_PHY_INIT_CFG(QPHY_V4_TX_SMALL_AMP_DRV_LVL, 0x02), 1288 - QMP_PHY_INIT_CFG(QPHY_V4_TX_MID_TERM_CTRL1, 0x43), 1289 - QMP_PHY_INIT_CFG(QPHY_V4_DEBUG_BUS_CLKSEL, 0x1f), 1290 - QMP_PHY_INIT_CFG(QPHY_V4_RX_MIN_HIBERN8_TIME, 0xff), 1291 - QMP_PHY_INIT_CFG(QPHY_V4_MULTI_LANE_CTRL1, 0x02), 1275 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), 1276 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a), 1277 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), 1278 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), 1279 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f), 1280 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), 1281 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02), 1282 + }; 1283 + 1284 + static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = { 1285 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01), 1286 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31), 1287 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01), 1288 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde), 1289 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07), 1290 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde), 1291 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07), 1292 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a), 1293 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20), 1294 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), 1295 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), 1296 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), 1297 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), 1298 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), 1299 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), 1300 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a), 1301 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04), 1302 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14), 1303 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34), 1304 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34), 1305 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82), 1306 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82), 1307 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82), 1308 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab), 1309 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea), 1310 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02), 1311 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), 1312 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab), 1313 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea), 1314 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02), 1315 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24), 1316 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24), 1317 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02), 1318 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01), 1319 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08), 1320 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca), 1321 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), 1322 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca), 1323 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e), 1324 + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), 1325 + }; 1326 + 1327 + static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl[] = { 1328 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x00), 1329 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x00), 1330 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5), 1331 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12), 1332 + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20), 1333 + }; 1334 + 1335 + static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl[] = { 1336 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x05), 1337 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f), 1338 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f), 1339 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff), 1340 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f), 1341 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99), 1342 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04), 1343 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08), 1344 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05), 1345 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05), 1346 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54), 1347 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0e), 1348 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), 1349 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), 1350 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a), 1351 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), 1352 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), 1353 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77), 1354 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04), 1355 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), 1356 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf), 1357 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xbf), 1358 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x3f), 1359 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f), 1360 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x94), 1361 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc), 1362 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc), 1363 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c), 1364 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x0b), 1365 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb3), 1366 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04), 1367 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), 1368 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0), 1369 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c), 1370 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f), 1371 + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10), 1372 + }; 1373 + 1374 + static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl[] = { 1375 + /* Lock Det settings */ 1376 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0), 1377 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07), 1378 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13), 1379 + 1380 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21), 1381 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa), 1382 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a), 1383 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88), 1384 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13), 1385 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c), 1386 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b), 1387 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10), 1388 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), 1389 + QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), 1292 1390 }; 1293 1391 1294 1392 /* struct qmp_phy_cfg - per-PHY initialization config */ ··· 1563 1445 "aux", "cfg_ahb", "ref", "refgen", 1564 1446 }; 1565 1447 1448 + static const char * const qmp_v4_phy_clk_l[] = { 1449 + "aux", "ref_clk_src", "ref", "com_aux", 1450 + }; 1451 + 1566 1452 static const char * const sdm845_ufs_phy_clk_l[] = { 1567 1453 "ref", "ref_aux", 1568 1454 }; ··· 1578 1456 1579 1457 static const char * const msm8996_usb3phy_reset_l[] = { 1580 1458 "phy", "common", 1459 + }; 1460 + 1461 + static const char * const sc7180_usb3phy_reset_l[] = { 1462 + "phy", 1581 1463 }; 1582 1464 1583 1465 static const char * const sdm845_pciephy_reset_l[] = { ··· 1797 1671 .is_dual_lane_phy = true, 1798 1672 }; 1799 1673 1674 + static const struct qmp_phy_cfg sc7180_usb3phy_cfg = { 1675 + .type = PHY_TYPE_USB3, 1676 + .nlanes = 1, 1677 + 1678 + .serdes_tbl = qmp_v3_usb3_serdes_tbl, 1679 + .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl), 1680 + .tx_tbl = qmp_v3_usb3_tx_tbl, 1681 + .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl), 1682 + .rx_tbl = qmp_v3_usb3_rx_tbl, 1683 + .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl), 1684 + .pcs_tbl = qmp_v3_usb3_pcs_tbl, 1685 + .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl), 1686 + .clk_list = qmp_v3_phy_clk_l, 1687 + .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l), 1688 + .reset_list = sc7180_usb3phy_reset_l, 1689 + .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l), 1690 + .vreg_list = qmp_phy_vreg_l, 1691 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1692 + .regs = qmp_v3_usb3phy_regs_layout, 1693 + 1694 + .start_ctrl = SERDES_START | PCS_START, 1695 + .pwrdn_ctrl = SW_PWRDN, 1696 + 1697 + .has_pwrdn_delay = true, 1698 + .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN, 1699 + .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX, 1700 + 1701 + .has_phy_dp_com_ctrl = true, 1702 + .is_dual_lane_phy = true, 1703 + }; 1704 + 1800 1705 static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = { 1801 1706 .type = PHY_TYPE_USB3, 1802 1707 .nlanes = 1, ··· 1955 1798 .is_dual_lane_phy = true, 1956 1799 }; 1957 1800 1801 + static const struct qmp_phy_cfg sm8150_usb3phy_cfg = { 1802 + .type = PHY_TYPE_USB3, 1803 + .nlanes = 1, 1804 + 1805 + .serdes_tbl = sm8150_usb3_serdes_tbl, 1806 + .serdes_tbl_num = ARRAY_SIZE(sm8150_usb3_serdes_tbl), 1807 + .tx_tbl = sm8150_usb3_tx_tbl, 1808 + .tx_tbl_num = ARRAY_SIZE(sm8150_usb3_tx_tbl), 1809 + .rx_tbl = sm8150_usb3_rx_tbl, 1810 + .rx_tbl_num = ARRAY_SIZE(sm8150_usb3_rx_tbl), 1811 + .pcs_tbl = sm8150_usb3_pcs_tbl, 1812 + .pcs_tbl_num = ARRAY_SIZE(sm8150_usb3_pcs_tbl), 1813 + .clk_list = qmp_v4_phy_clk_l, 1814 + .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), 1815 + .reset_list = msm8996_usb3phy_reset_l, 1816 + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), 1817 + .vreg_list = qmp_phy_vreg_l, 1818 + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), 1819 + .regs = qmp_v4_usb3phy_regs_layout, 1820 + 1821 + .start_ctrl = SERDES_START | PCS_START, 1822 + .pwrdn_ctrl = SW_PWRDN, 1823 + 1824 + .has_pwrdn_delay = true, 1825 + .pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN, 1826 + .pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX, 1827 + 1828 + .has_phy_dp_com_ctrl = true, 1829 + .is_dual_lane_phy = true, 1830 + }; 1831 + 1958 1832 static void qcom_qmp_phy_configure(void __iomem *base, 1959 1833 const unsigned int *regs, 1960 1834 const struct qmp_phy_init_tbl tbl[], ··· 2068 1880 SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); 2069 1881 } 2070 1882 2071 - if (cfg->has_phy_com_ctrl) 1883 + if (cfg->has_phy_com_ctrl) { 2072 1884 qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL], 2073 1885 SW_PWRDN); 2074 - else 2075 - qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl); 1886 + } else { 1887 + if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) 1888 + qphy_setbits(pcs, 1889 + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 1890 + cfg->pwrdn_ctrl); 1891 + else 1892 + qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, 1893 + cfg->pwrdn_ctrl); 1894 + } 2076 1895 2077 1896 /* Serdes configuration */ 2078 1897 qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl, ··· 2305 2110 qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); 2306 2111 2307 2112 /* Put PHY into POWER DOWN state: active low */ 2308 - qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl); 2113 + if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) { 2114 + qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], 2115 + cfg->pwrdn_ctrl); 2116 + } else { 2117 + qphy_clrbits(qphy->pcs, QPHY_POWER_DOWN_CONTROL, 2118 + cfg->pwrdn_ctrl); 2119 + } 2309 2120 2310 2121 if (cfg->has_lane_rst) 2311 2122 reset_control_assert(qphy->lane_rst); ··· 2717 2516 .compatible = "qcom,ipq8074-qmp-pcie-phy", 2718 2517 .data = &ipq8074_pciephy_cfg, 2719 2518 }, { 2519 + .compatible = "qcom,sc7180-qmp-usb3-phy", 2520 + .data = &sc7180_usb3phy_cfg, 2521 + }, { 2720 2522 .compatible = "qcom,sdm845-qhp-pcie-phy", 2721 2523 .data = &sdm845_qhp_pciephy_cfg, 2722 2524 }, { ··· 2740 2536 }, { 2741 2537 .compatible = "qcom,sm8150-qmp-ufs-phy", 2742 2538 .data = &sm8150_ufsphy_cfg, 2539 + }, { 2540 + .compatible = "qcom,sm8250-qmp-ufs-phy", 2541 + .data = &sm8150_ufsphy_cfg, 2542 + }, { 2543 + .compatible = "qcom,sm8150-qmp-usb3-phy", 2544 + .data = &sm8150_usb3phy_cfg, 2743 2545 }, 2744 2546 { }, 2745 2547 };
+216 -22
drivers/phy/qualcomm/phy-qcom-qmp.h
··· 125 125 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC 126 126 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0 127 127 128 - /* Only for QMP V3 PHY - DP COM registers */ 128 + /* Only for QMP V3 & V4 PHY - DP COM registers */ 129 129 #define QPHY_V3_DP_COM_PHY_MODE_CTRL 0x00 130 130 #define QPHY_V3_DP_COM_SW_RESET 0x04 131 131 #define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08 ··· 314 314 #define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5 0x60 315 315 316 316 /* Only for QMP V4 PHY - QSERDES COM registers */ 317 + #define QSERDES_V4_COM_SSC_EN_CENTER 0x010 318 + #define QSERDES_V4_COM_SSC_PER1 0x01c 319 + #define QSERDES_V4_COM_SSC_PER2 0x020 320 + #define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0 0x024 321 + #define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0 0x028 322 + #define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1 0x030 323 + #define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1 0x034 324 + #define QSERDES_V4_COM_SYSCLK_BUF_ENABLE 0x050 317 325 #define QSERDES_V4_COM_PLL_IVCO 0x058 318 326 #define QSERDES_V4_COM_CMN_IPTRIM 0x060 319 327 #define QSERDES_V4_COM_CP_CTRL_MODE0 0x074 ··· 338 330 #define QSERDES_V4_COM_DEC_START_MODE0 0x0bc 339 331 #define QSERDES_V4_COM_LOCK_CMP2_MODE1 0x0b8 340 332 #define QSERDES_V4_COM_DEC_START_MODE1 0x0c4 333 + #define QSERDES_V4_COM_DIV_FRAC_START1_MODE0 0x0cc 334 + #define QSERDES_V4_COM_DIV_FRAC_START2_MODE0 0x0d0 335 + #define QSERDES_V4_COM_DIV_FRAC_START3_MODE0 0x0d4 336 + #define QSERDES_V4_COM_DIV_FRAC_START1_MODE1 0x0d8 337 + #define QSERDES_V4_COM_DIV_FRAC_START2_MODE1 0x0dc 338 + #define QSERDES_V4_COM_DIV_FRAC_START3_MODE1 0x0e0 341 339 #define QSERDES_V4_COM_VCO_TUNE_MAP 0x10c 340 + #define QSERDES_V4_COM_VCO_TUNE1_MODE0 0x110 341 + #define QSERDES_V4_COM_VCO_TUNE2_MODE0 0x114 342 + #define QSERDES_V4_COM_VCO_TUNE1_MODE1 0x118 343 + #define QSERDES_V4_COM_VCO_TUNE2_MODE1 0x11c 342 344 #define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124 343 345 #define QSERDES_V4_COM_HSCLK_SEL 0x158 344 346 #define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c 347 + #define QSERDES_V4_COM_CORECLK_DIV_MODE1 0x16c 348 + #define QSERDES_V4_COM_SVS_MODE_CLK_SEL 0x184 345 349 #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac 346 350 #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0 347 351 #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x1b4 ··· 361 341 #define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x1b8 362 342 363 343 /* Only for QMP V4 PHY - TX registers */ 344 + #define QSERDES_V4_TX_RES_CODE_LANE_TX 0x34 345 + #define QSERDES_V4_TX_RES_CODE_LANE_RX 0x38 364 346 #define QSERDES_V4_TX_LANE_MODE_1 0x84 347 + #define QSERDES_V4_TX_RCV_DETECT_LVL_2 0x9c 365 348 #define QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0xd8 366 349 #define QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0xdC 367 350 #define QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0xe0 368 351 #define QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0xe4 369 352 #define QSERDES_V4_TX_TRAN_DRVR_EMP_EN 0xb8 353 + #define QSERDES_V4_TX_PI_QEC_CTRL 0x104 370 354 371 355 /* Only for QMP V4 PHY - RX registers */ 372 356 #define QSERDES_V4_RX_UCDR_FO_GAIN 0x008 ··· 378 354 #define QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN 0x030 379 355 #define QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 380 356 #define QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c 357 + #define QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040 381 358 #define QSERDES_V4_RX_UCDR_PI_CONTROLS 0x044 382 359 #define QSERDES_V4_RX_UCDR_PI_CTRL2 0x048 360 + #define QSERDES_V4_RX_UCDR_SB2_THRESH1 0x04c 361 + #define QSERDES_V4_RX_UCDR_SB2_THRESH2 0x050 362 + #define QSERDES_V4_RX_UCDR_SB2_GAIN1 0x054 363 + #define QSERDES_V4_RX_UCDR_SB2_GAIN2 0x058 364 + #define QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE 0x060 383 365 #define QSERDES_V4_RX_AC_JTAG_ENABLE 0x068 384 366 #define QSERDES_V4_RX_AC_JTAG_MODE 0x078 385 367 #define QSERDES_V4_RX_RX_TERM_BW 0x080 368 + #define QSERDES_V4_RX_VGA_CAL_CNTRL1 0x0d4 369 + #define QSERDES_V4_RX_VGA_CAL_CNTRL2 0x0d8 370 + #define QSERDES_V4_RX_GM_CAL 0x0dc 386 371 #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2 0x0ec 387 372 #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3 0x0f0 388 373 #define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4 0x0f4 389 374 #define QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW 0x0f8 390 375 #define QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH 0x0fc 391 376 #define QSERDES_V4_RX_RX_IDAC_MEASURE_TIME 0x100 377 + #define QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110 392 378 #define QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114 393 379 #define QSERDES_V4_RX_SIGDET_CNTRL 0x11c 394 380 #define QSERDES_V4_RX_SIGDET_LVL 0x120 ··· 419 385 #define QSERDES_V4_RX_RX_MODE_10_HIGH2 0x1a0 420 386 #define QSERDES_V4_RX_RX_MODE_10_HIGH3 0x1a4 421 387 #define QSERDES_V4_RX_RX_MODE_10_HIGH4 0x1a8 388 + #define QSERDES_V4_RX_DFE_EN_TIMER 0x1b4 389 + #define QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET 0x1b8 422 390 #define QSERDES_V4_RX_DCC_CTRL1 0x1bc 391 + #define QSERDES_V4_RX_VTH_CODE 0x1c4 423 392 424 - /* Only for QMP V4 PHY - PCS registers */ 425 - #define QPHY_V4_PHY_START 0x000 426 - #define QPHY_V4_POWER_DOWN_CONTROL 0x004 427 - #define QPHY_V4_SW_RESET 0x008 428 - #define QPHY_V4_TIMER_20US_CORECLK_STEPS_MSB 0x00c 429 - #define QPHY_V4_TIMER_20US_CORECLK_STEPS_LSB 0x010 430 - #define QPHY_V4_PLL_CNTL 0x02c 431 - #define QPHY_V4_TX_LARGE_AMP_DRV_LVL 0x030 432 - #define QPHY_V4_TX_SMALL_AMP_DRV_LVL 0x038 433 - #define QPHY_V4_BIST_FIXED_PAT_CTRL 0x060 434 - #define QPHY_V4_TX_HSGEAR_CAPABILITY 0x074 435 - #define QPHY_V4_RX_HSGEAR_CAPABILITY 0x0b4 436 - #define QPHY_V4_DEBUG_BUS_CLKSEL 0x124 437 - #define QPHY_V4_LINECFG_DISABLE 0x148 438 - #define QPHY_V4_RX_MIN_HIBERN8_TIME 0x150 439 - #define QPHY_V4_RX_SIGDET_CTRL2 0x158 440 - #define QPHY_V4_TX_PWM_GEAR_BAND 0x160 441 - #define QPHY_V4_TX_HS_GEAR_BAND 0x168 442 - #define QPHY_V4_PCS_READY_STATUS 0x180 443 - #define QPHY_V4_TX_MID_TERM_CTRL1 0x1d8 444 - #define QPHY_V4_MULTI_LANE_CTRL1 0x1e0 393 + /* Only for QMP V4 PHY - UFS PCS registers */ 394 + #define QPHY_V4_PCS_UFS_PHY_START 0x000 395 + #define QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL 0x004 396 + #define QPHY_V4_PCS_UFS_SW_RESET 0x008 397 + #define QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c 398 + #define QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010 399 + #define QPHY_V4_PCS_UFS_PLL_CNTL 0x02c 400 + #define QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030 401 + #define QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038 402 + #define QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060 403 + #define QPHY_V4_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074 404 + #define QPHY_V4_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0b4 405 + #define QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL 0x124 406 + #define QPHY_V4_PCS_UFS_LINECFG_DISABLE 0x148 407 + #define QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME 0x150 408 + #define QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2 0x158 409 + #define QPHY_V4_PCS_UFS_TX_PWM_GEAR_BAND 0x160 410 + #define QPHY_V4_PCS_UFS_TX_HS_GEAR_BAND 0x168 411 + #define QPHY_V4_PCS_UFS_READY_STATUS 0x180 412 + #define QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1 0x1d8 413 + #define QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1 0x1e0 445 414 446 415 /* PCIE GEN3 COM registers */ 447 416 #define PCIE_GEN3_QHP_COM_SSC_EN_CENTER 0x14 ··· 559 522 #define PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG 0x15c 560 523 #define PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG5 0x16c 561 524 #define PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG 0x174 525 + 526 + /* Only for QMP V4 PHY - USB/PCIe PCS registers */ 527 + #define QPHY_V4_PCS_SW_RESET 0x000 528 + #define QPHY_V4_PCS_REVISION_ID0 0x004 529 + #define QPHY_V4_PCS_REVISION_ID1 0x008 530 + #define QPHY_V4_PCS_REVISION_ID2 0x00c 531 + #define QPHY_V4_PCS_REVISION_ID3 0x010 532 + #define QPHY_V4_PCS_PCS_STATUS1 0x014 533 + #define QPHY_V4_PCS_PCS_STATUS2 0x018 534 + #define QPHY_V4_PCS_PCS_STATUS3 0x01c 535 + #define QPHY_V4_PCS_PCS_STATUS4 0x020 536 + #define QPHY_V4_PCS_PCS_STATUS5 0x024 537 + #define QPHY_V4_PCS_PCS_STATUS6 0x028 538 + #define QPHY_V4_PCS_PCS_STATUS7 0x02c 539 + #define QPHY_V4_PCS_DEBUG_BUS_0_STATUS 0x030 540 + #define QPHY_V4_PCS_DEBUG_BUS_1_STATUS 0x034 541 + #define QPHY_V4_PCS_DEBUG_BUS_2_STATUS 0x038 542 + #define QPHY_V4_PCS_DEBUG_BUS_3_STATUS 0x03c 543 + #define QPHY_V4_PCS_POWER_DOWN_CONTROL 0x040 544 + #define QPHY_V4_PCS_START_CONTROL 0x044 545 + #define QPHY_V4_PCS_INSIG_SW_CTRL1 0x048 546 + #define QPHY_V4_PCS_INSIG_SW_CTRL2 0x04c 547 + #define QPHY_V4_PCS_INSIG_SW_CTRL3 0x050 548 + #define QPHY_V4_PCS_INSIG_SW_CTRL4 0x054 549 + #define QPHY_V4_PCS_INSIG_SW_CTRL5 0x058 550 + #define QPHY_V4_PCS_INSIG_SW_CTRL6 0x05c 551 + #define QPHY_V4_PCS_INSIG_SW_CTRL7 0x060 552 + #define QPHY_V4_PCS_INSIG_SW_CTRL8 0x064 553 + #define QPHY_V4_PCS_INSIG_MX_CTRL1 0x068 554 + #define QPHY_V4_PCS_INSIG_MX_CTRL2 0x06c 555 + #define QPHY_V4_PCS_INSIG_MX_CTRL3 0x070 556 + #define QPHY_V4_PCS_INSIG_MX_CTRL4 0x074 557 + #define QPHY_V4_PCS_INSIG_MX_CTRL5 0x078 558 + #define QPHY_V4_PCS_INSIG_MX_CTRL7 0x07c 559 + #define QPHY_V4_PCS_INSIG_MX_CTRL8 0x080 560 + #define QPHY_V4_PCS_OUTSIG_SW_CTRL1 0x084 561 + #define QPHY_V4_PCS_OUTSIG_MX_CTRL1 0x088 562 + #define QPHY_V4_PCS_CLAMP_ENABLE 0x08c 563 + #define QPHY_V4_PCS_POWER_STATE_CONFIG1 0x090 564 + #define QPHY_V4_PCS_POWER_STATE_CONFIG2 0x094 565 + #define QPHY_V4_PCS_FLL_CNTRL1 0x098 566 + #define QPHY_V4_PCS_FLL_CNTRL2 0x09c 567 + #define QPHY_V4_PCS_FLL_CNT_VAL_L 0x0a0 568 + #define QPHY_V4_PCS_FLL_CNT_VAL_H_TOL 0x0a4 569 + #define QPHY_V4_PCS_FLL_MAN_CODE 0x0a8 570 + #define QPHY_V4_PCS_TEST_CONTROL1 0x0ac 571 + #define QPHY_V4_PCS_TEST_CONTROL2 0x0b0 572 + #define QPHY_V4_PCS_TEST_CONTROL3 0x0b4 573 + #define QPHY_V4_PCS_TEST_CONTROL4 0x0b8 574 + #define QPHY_V4_PCS_TEST_CONTROL5 0x0bc 575 + #define QPHY_V4_PCS_TEST_CONTROL6 0x0c0 576 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG1 0x0c4 577 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG2 0x0c8 578 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG3 0x0cc 579 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG4 0x0d0 580 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG5 0x0d4 581 + #define QPHY_V4_PCS_LOCK_DETECT_CONFIG6 0x0d8 582 + #define QPHY_V4_PCS_REFGEN_REQ_CONFIG1 0x0dc 583 + #define QPHY_V4_PCS_REFGEN_REQ_CONFIG2 0x0e0 584 + #define QPHY_V4_PCS_REFGEN_REQ_CONFIG3 0x0e4 585 + #define QPHY_V4_PCS_BIST_CTRL 0x0e8 586 + #define QPHY_V4_PCS_PRBS_POLY0 0x0ec 587 + #define QPHY_V4_PCS_PRBS_POLY1 0x0f0 588 + #define QPHY_V4_PCS_FIXED_PAT0 0x0f4 589 + #define QPHY_V4_PCS_FIXED_PAT1 0x0f8 590 + #define QPHY_V4_PCS_FIXED_PAT2 0x0fc 591 + #define QPHY_V4_PCS_FIXED_PAT3 0x100 592 + #define QPHY_V4_PCS_FIXED_PAT4 0x104 593 + #define QPHY_V4_PCS_FIXED_PAT5 0x108 594 + #define QPHY_V4_PCS_FIXED_PAT6 0x10c 595 + #define QPHY_V4_PCS_FIXED_PAT7 0x110 596 + #define QPHY_V4_PCS_FIXED_PAT8 0x114 597 + #define QPHY_V4_PCS_FIXED_PAT9 0x118 598 + #define QPHY_V4_PCS_FIXED_PAT10 0x11c 599 + #define QPHY_V4_PCS_FIXED_PAT11 0x120 600 + #define QPHY_V4_PCS_FIXED_PAT12 0x124 601 + #define QPHY_V4_PCS_FIXED_PAT13 0x128 602 + #define QPHY_V4_PCS_FIXED_PAT14 0x12c 603 + #define QPHY_V4_PCS_FIXED_PAT15 0x130 604 + #define QPHY_V4_PCS_TXMGN_CONFIG 0x134 605 + #define QPHY_V4_PCS_G12S1_TXMGN_V0 0x138 606 + #define QPHY_V4_PCS_G12S1_TXMGN_V1 0x13c 607 + #define QPHY_V4_PCS_G12S1_TXMGN_V2 0x140 608 + #define QPHY_V4_PCS_G12S1_TXMGN_V3 0x144 609 + #define QPHY_V4_PCS_G12S1_TXMGN_V4 0x148 610 + #define QPHY_V4_PCS_G12S1_TXMGN_V0_RS 0x14c 611 + #define QPHY_V4_PCS_G12S1_TXMGN_V1_RS 0x150 612 + #define QPHY_V4_PCS_G12S1_TXMGN_V2_RS 0x154 613 + #define QPHY_V4_PCS_G12S1_TXMGN_V3_RS 0x158 614 + #define QPHY_V4_PCS_G12S1_TXMGN_V4_RS 0x15c 615 + #define QPHY_V4_PCS_G3S2_TXMGN_MAIN 0x160 616 + #define QPHY_V4_PCS_G3S2_TXMGN_MAIN_RS 0x164 617 + #define QPHY_V4_PCS_G12S1_TXDEEMPH_M6DB 0x168 618 + #define QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB 0x16c 619 + #define QPHY_V4_PCS_G3S2_PRE_GAIN 0x170 620 + #define QPHY_V4_PCS_G3S2_POST_GAIN 0x174 621 + #define QPHY_V4_PCS_G3S2_PRE_POST_OFFSET 0x178 622 + #define QPHY_V4_PCS_G3S2_PRE_GAIN_RS 0x17c 623 + #define QPHY_V4_PCS_G3S2_POST_GAIN_RS 0x180 624 + #define QPHY_V4_PCS_G3S2_PRE_POST_OFFSET_RS 0x184 625 + #define QPHY_V4_PCS_RX_SIGDET_LVL 0x188 626 + #define QPHY_V4_PCS_RX_SIGDET_DTCT_CNTRL 0x18c 627 + #define QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 628 + #define QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 629 + #define QPHY_V4_PCS_RATE_SLEW_CNTRL1 0x198 630 + #define QPHY_V4_PCS_RATE_SLEW_CNTRL2 0x19c 631 + #define QPHY_V4_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x1a0 632 + #define QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x1a4 633 + #define QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x1a8 634 + #define QPHY_V4_PCS_TSYNC_RSYNC_TIME 0x1ac 635 + #define QPHY_V4_PCS_CDR_RESET_TIME 0x1b0 636 + #define QPHY_V4_PCS_TSYNC_DLY_TIME 0x1b4 637 + #define QPHY_V4_PCS_ELECIDLE_DLY_SEL 0x1b8 638 + #define QPHY_V4_PCS_CMN_ACK_OUT_SEL 0x1bc 639 + #define QPHY_V4_PCS_ALIGN_DETECT_CONFIG1 0x1c0 640 + #define QPHY_V4_PCS_ALIGN_DETECT_CONFIG2 0x1c4 641 + #define QPHY_V4_PCS_ALIGN_DETECT_CONFIG3 0x1c8 642 + #define QPHY_V4_PCS_ALIGN_DETECT_CONFIG4 0x1cc 643 + #define QPHY_V4_PCS_PCS_TX_RX_CONFIG 0x1d0 644 + #define QPHY_V4_PCS_RX_IDLE_DTCT_CNTRL 0x1d4 645 + #define QPHY_V4_PCS_RX_DCC_CAL_CONFIG 0x1d8 646 + #define QPHY_V4_PCS_EQ_CONFIG1 0x1dc 647 + #define QPHY_V4_PCS_EQ_CONFIG2 0x1e0 648 + #define QPHY_V4_PCS_EQ_CONFIG3 0x1e4 649 + #define QPHY_V4_PCS_EQ_CONFIG4 0x1e8 650 + #define QPHY_V4_PCS_EQ_CONFIG5 0x1ec 651 + #define QPHY_V4_PCS_USB3_POWER_STATE_CONFIG1 0x300 652 + #define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_STATUS 0x304 653 + #define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL 0x308 654 + #define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL2 0x30c 655 + #define QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_SOURCE_STATUS 0x310 656 + #define QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR 0x314 657 + #define QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x318 658 + #define QPHY_V4_PCS_USB3_LFPS_TX_ECSTART 0x31c 659 + #define QPHY_V4_PCS_USB3_LFPS_PER_TIMER_VAL 0x320 660 + #define QPHY_V4_PCS_USB3_LFPS_TX_END_CNT_U3_START 0x324 661 + #define QPHY_V4_PCS_USB3_RXEQTRAINING_LOCK_TIME 0x328 662 + #define QPHY_V4_PCS_USB3_RXEQTRAINING_WAIT_TIME 0x32c 663 + #define QPHY_V4_PCS_USB3_RXEQTRAINING_CTLE_TIME 0x330 664 + #define QPHY_V4_PCS_USB3_RXEQTRAINING_WAIT_TIME_S2 0x334 665 + #define QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x338 666 + #define QPHY_V4_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x33c 667 + #define QPHY_V4_PCS_USB3_RCVR_DTCT_DLY_U3_H 0x340 668 + #define QPHY_V4_PCS_USB3_ARCVR_DTCT_EN_PERIOD 0x344 669 + #define QPHY_V4_PCS_USB3_ARCVR_DTCT_CM_DLY 0x348 670 + #define QPHY_V4_PCS_USB3_TXONESZEROS_RUN_LENGTH 0x34c 671 + #define QPHY_V4_PCS_USB3_ALFPS_DEGLITCH_VAL 0x350 672 + #define QPHY_V4_PCS_USB3_SIGDET_STARTUP_TIMER_VAL 0x354 673 + #define QPHY_V4_PCS_USB3_TEST_CONTROL 0x358 674 + 675 + /* Only for QMP V4 PHY - PCS_MISC registers */ 676 + #define QPHY_V4_PCS_MISC_TYPEC_CTRL 0x00 677 + #define QPHY_V4_PCS_MISC_TYPEC_PWRDN_CTRL 0x04 678 + #define QPHY_V4_PCS_MISC_PCS_MISC_CONFIG1 0x08 679 + #define QPHY_V4_PCS_MISC_CLAMP_ENABLE 0x0c 680 + #define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10 681 + #define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14 562 682 563 683 #endif
+287
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk.h> 7 + #include <linux/delay.h> 8 + #include <linux/err.h> 9 + #include <linux/io.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/of_device.h> 14 + #include <linux/phy/phy.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + #include <linux/regulator/consumer.h> 18 + #include <linux/reset.h> 19 + #include <linux/slab.h> 20 + 21 + #define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c) 22 + #define SLEEPM BIT(0) 23 + #define OPMODE_MASK GENMASK(4, 3) 24 + #define OPMODE_NORMAL (0x00) 25 + #define OPMODE_NONDRIVING BIT(3) 26 + #define TERMSEL BIT(5) 27 + 28 + #define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40) 29 + #define XCVRSEL BIT(0) 30 + 31 + #define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50) 32 + #define POR BIT(1) 33 + 34 + #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) 35 + #define RETENABLEN BIT(3) 36 + #define FSEL_MASK GENMASK(7, 5) 37 + #define FSEL_DEFAULT (0x3 << 4) 38 + 39 + #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58) 40 + #define VBUSVLDEXTSEL0 BIT(4) 41 + #define PLLBTUNE BIT(5) 42 + 43 + #define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2 (0x5c) 44 + #define VREGBYPASS BIT(0) 45 + 46 + #define USB2_PHY_USB_PHY_HS_PHY_CTRL1 (0x60) 47 + #define VBUSVLDEXT0 BIT(0) 48 + 49 + #define USB2_PHY_USB_PHY_HS_PHY_CTRL2 (0x64) 50 + #define USB2_AUTO_RESUME BIT(0) 51 + #define USB2_SUSPEND_N BIT(2) 52 + #define USB2_SUSPEND_N_SEL BIT(3) 53 + 54 + #define USB2_PHY_USB_PHY_CFG0 (0x94) 55 + #define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0) 56 + #define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1) 57 + 58 + #define USB2_PHY_USB_PHY_REFCLK_CTRL (0xa0) 59 + #define REFCLK_SEL_MASK GENMASK(1, 0) 60 + #define REFCLK_SEL_DEFAULT (0x2 << 0) 61 + 62 + static const char * const qcom_snps_hsphy_vreg_names[] = { 63 + "vdda-pll", "vdda33", "vdda18", 64 + }; 65 + 66 + #define SNPS_HS_NUM_VREGS ARRAY_SIZE(qcom_snps_hsphy_vreg_names) 67 + 68 + /** 69 + * struct qcom_snps_hsphy - snps hs phy attributes 70 + * 71 + * @phy: generic phy 72 + * @base: iomapped memory space for snps hs phy 73 + * 74 + * @cfg_ahb_clk: AHB2PHY interface clock 75 + * @ref_clk: phy reference clock 76 + * @iface_clk: phy interface clock 77 + * @phy_reset: phy reset control 78 + * @vregs: regulator supplies bulk data 79 + * @phy_initialized: if PHY has been initialized correctly 80 + */ 81 + struct qcom_snps_hsphy { 82 + struct phy *phy; 83 + void __iomem *base; 84 + 85 + struct clk *cfg_ahb_clk; 86 + struct clk *ref_clk; 87 + struct reset_control *phy_reset; 88 + struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS]; 89 + 90 + bool phy_initialized; 91 + }; 92 + 93 + static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset, 94 + u32 mask, u32 val) 95 + { 96 + u32 reg; 97 + 98 + reg = readl_relaxed(base + offset); 99 + reg &= ~mask; 100 + reg |= val & mask; 101 + writel_relaxed(reg, base + offset); 102 + 103 + /* Ensure above write is completed */ 104 + readl_relaxed(base + offset); 105 + } 106 + 107 + static int qcom_snps_hsphy_init(struct phy *phy) 108 + { 109 + struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); 110 + int ret; 111 + 112 + dev_vdbg(&phy->dev, "%s(): Initializing SNPS HS phy\n", __func__); 113 + 114 + ret = regulator_bulk_enable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 115 + if (ret) 116 + return ret; 117 + 118 + ret = clk_prepare_enable(hsphy->cfg_ahb_clk); 119 + if (ret) { 120 + dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); 121 + goto poweroff_phy; 122 + } 123 + 124 + ret = reset_control_assert(hsphy->phy_reset); 125 + if (ret) { 126 + dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret); 127 + goto disable_ahb_clk; 128 + } 129 + 130 + usleep_range(100, 150); 131 + 132 + ret = reset_control_deassert(hsphy->phy_reset); 133 + if (ret) { 134 + dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret); 135 + goto disable_ahb_clk; 136 + } 137 + 138 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, 139 + UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 140 + UTMI_PHY_CMN_CTRL_OVERRIDE_EN); 141 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5, 142 + POR, POR); 143 + qcom_snps_hsphy_write_mask(hsphy->base, 144 + USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, 145 + FSEL_MASK, 0); 146 + qcom_snps_hsphy_write_mask(hsphy->base, 147 + USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, 148 + PLLBTUNE, PLLBTUNE); 149 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_REFCLK_CTRL, 150 + REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK); 151 + qcom_snps_hsphy_write_mask(hsphy->base, 152 + USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, 153 + VBUSVLDEXTSEL0, VBUSVLDEXTSEL0); 154 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1, 155 + VBUSVLDEXT0, VBUSVLDEXT0); 156 + 157 + qcom_snps_hsphy_write_mask(hsphy->base, 158 + USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2, 159 + VREGBYPASS, VREGBYPASS); 160 + 161 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2, 162 + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, 163 + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); 164 + 165 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, 166 + SLEEPM, SLEEPM); 167 + 168 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5, 169 + POR, 0); 170 + 171 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2, 172 + USB2_SUSPEND_N_SEL, 0); 173 + 174 + qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, 175 + UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0); 176 + 177 + hsphy->phy_initialized = true; 178 + 179 + return 0; 180 + 181 + disable_ahb_clk: 182 + clk_disable_unprepare(hsphy->cfg_ahb_clk); 183 + poweroff_phy: 184 + regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 185 + 186 + return ret; 187 + } 188 + 189 + static int qcom_snps_hsphy_exit(struct phy *phy) 190 + { 191 + struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); 192 + 193 + reset_control_assert(hsphy->phy_reset); 194 + clk_disable_unprepare(hsphy->cfg_ahb_clk); 195 + regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); 196 + hsphy->phy_initialized = false; 197 + 198 + return 0; 199 + } 200 + 201 + static const struct phy_ops qcom_snps_hsphy_gen_ops = { 202 + .init = qcom_snps_hsphy_init, 203 + .exit = qcom_snps_hsphy_exit, 204 + .owner = THIS_MODULE, 205 + }; 206 + 207 + static const struct of_device_id qcom_snps_hsphy_of_match_table[] = { 208 + { .compatible = "qcom,sm8150-usb-hs-phy", }, 209 + { .compatible = "qcom,usb-snps-hs-7nm-phy", }, 210 + { .compatible = "qcom,usb-snps-femto-v2-phy", }, 211 + { } 212 + }; 213 + MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_of_match_table); 214 + 215 + static int qcom_snps_hsphy_probe(struct platform_device *pdev) 216 + { 217 + struct device *dev = &pdev->dev; 218 + struct qcom_snps_hsphy *hsphy; 219 + struct phy_provider *phy_provider; 220 + struct phy *generic_phy; 221 + int ret, i; 222 + int num; 223 + 224 + hsphy = devm_kzalloc(dev, sizeof(*hsphy), GFP_KERNEL); 225 + if (!hsphy) 226 + return -ENOMEM; 227 + 228 + hsphy->base = devm_platform_ioremap_resource(pdev, 0); 229 + if (IS_ERR(hsphy->base)) 230 + return PTR_ERR(hsphy->base); 231 + 232 + hsphy->ref_clk = devm_clk_get(dev, "ref"); 233 + if (IS_ERR(hsphy->ref_clk)) { 234 + ret = PTR_ERR(hsphy->ref_clk); 235 + if (ret != -EPROBE_DEFER) 236 + dev_err(dev, "failed to get ref clk, %d\n", ret); 237 + return ret; 238 + } 239 + 240 + hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); 241 + if (IS_ERR(hsphy->phy_reset)) { 242 + dev_err(dev, "failed to get phy core reset\n"); 243 + return PTR_ERR(hsphy->phy_reset); 244 + } 245 + 246 + num = ARRAY_SIZE(hsphy->vregs); 247 + for (i = 0; i < num; i++) 248 + hsphy->vregs[i].supply = qcom_snps_hsphy_vreg_names[i]; 249 + 250 + ret = devm_regulator_bulk_get(dev, num, hsphy->vregs); 251 + if (ret) { 252 + if (ret != -EPROBE_DEFER) 253 + dev_err(dev, "failed to get regulator supplies: %d\n", 254 + ret); 255 + return ret; 256 + } 257 + 258 + generic_phy = devm_phy_create(dev, NULL, &qcom_snps_hsphy_gen_ops); 259 + if (IS_ERR(generic_phy)) { 260 + ret = PTR_ERR(generic_phy); 261 + dev_err(dev, "failed to create phy, %d\n", ret); 262 + return ret; 263 + } 264 + hsphy->phy = generic_phy; 265 + 266 + dev_set_drvdata(dev, hsphy); 267 + phy_set_drvdata(generic_phy, hsphy); 268 + 269 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 270 + if (!IS_ERR(phy_provider)) 271 + dev_dbg(dev, "Registered Qcom-SNPS HS phy\n"); 272 + 273 + return PTR_ERR_OR_ZERO(phy_provider); 274 + } 275 + 276 + static struct platform_driver qcom_snps_hsphy_driver = { 277 + .probe = qcom_snps_hsphy_probe, 278 + .driver = { 279 + .name = "qcom-snps-hs-femto-v2-phy", 280 + .of_match_table = qcom_snps_hsphy_of_match_table, 281 + }, 282 + }; 283 + 284 + module_platform_driver(qcom_snps_hsphy_driver); 285 + 286 + MODULE_DESCRIPTION("Qualcomm SNPS FEMTO USB HS PHY V2 driver"); 287 + MODULE_LICENSE("GPL v2");
+4
drivers/phy/samsung/phy-s5pv210-usb2.c
··· 139 139 udelay(10); 140 140 rst &= ~rstbits; 141 141 writel(rst, drv->reg_phy + S5PV210_UPHYRST); 142 + /* The following delay is necessary for the reset sequence to be 143 + * completed 144 + */ 145 + udelay(80); 142 146 } else { 143 147 pwr = readl(drv->reg_phy + S5PV210_UPHYPWR); 144 148 pwr |= phypwr;
+102 -2
drivers/phy/ti/phy-am654-serdes.c
··· 77 77 .val_bits = 32, 78 78 .reg_stride = 4, 79 79 .fast_io = true, 80 + .max_register = 0x1ffc, 80 81 }; 81 82 82 83 static const struct reg_field cmu_master_cdn_o = REG_FIELD(CMU_R07C, 24, 24); ··· 201 200 return 0; 202 201 } 203 202 204 - static int serdes_am654_init(struct phy *x) 203 + #define SERDES_AM654_CFG(offset, a, b, val) \ 204 + regmap_update_bits(phy->regmap, (offset),\ 205 + GENMASK((a), (b)), (val) << (b)) 206 + 207 + static int serdes_am654_usb3_init(struct serdes_am654 *phy) 205 208 { 206 - struct serdes_am654 *phy = phy_get_drvdata(x); 209 + SERDES_AM654_CFG(0x0000, 31, 24, 0x17); 210 + SERDES_AM654_CFG(0x0004, 15, 8, 0x02); 211 + SERDES_AM654_CFG(0x0004, 7, 0, 0x0e); 212 + SERDES_AM654_CFG(0x0008, 23, 16, 0x2e); 213 + SERDES_AM654_CFG(0x0008, 31, 24, 0x2e); 214 + SERDES_AM654_CFG(0x0060, 7, 0, 0x4b); 215 + SERDES_AM654_CFG(0x0060, 15, 8, 0x98); 216 + SERDES_AM654_CFG(0x0060, 23, 16, 0x60); 217 + SERDES_AM654_CFG(0x00d0, 31, 24, 0x45); 218 + SERDES_AM654_CFG(0x00e8, 15, 8, 0x0e); 219 + SERDES_AM654_CFG(0x0220, 7, 0, 0x34); 220 + SERDES_AM654_CFG(0x0220, 15, 8, 0x34); 221 + SERDES_AM654_CFG(0x0220, 31, 24, 0x37); 222 + SERDES_AM654_CFG(0x0224, 7, 0, 0x37); 223 + SERDES_AM654_CFG(0x0224, 15, 8, 0x37); 224 + SERDES_AM654_CFG(0x0228, 23, 16, 0x37); 225 + SERDES_AM654_CFG(0x0228, 31, 24, 0x37); 226 + SERDES_AM654_CFG(0x022c, 7, 0, 0x37); 227 + SERDES_AM654_CFG(0x022c, 15, 8, 0x37); 228 + SERDES_AM654_CFG(0x0230, 15, 8, 0x2a); 229 + SERDES_AM654_CFG(0x0230, 23, 16, 0x2a); 230 + SERDES_AM654_CFG(0x0240, 23, 16, 0x10); 231 + SERDES_AM654_CFG(0x0240, 31, 24, 0x34); 232 + SERDES_AM654_CFG(0x0244, 7, 0, 0x40); 233 + SERDES_AM654_CFG(0x0244, 23, 16, 0x34); 234 + SERDES_AM654_CFG(0x0248, 15, 8, 0x0d); 235 + SERDES_AM654_CFG(0x0258, 15, 8, 0x16); 236 + SERDES_AM654_CFG(0x0258, 23, 16, 0x84); 237 + SERDES_AM654_CFG(0x0258, 31, 24, 0xf2); 238 + SERDES_AM654_CFG(0x025c, 7, 0, 0x21); 239 + SERDES_AM654_CFG(0x0260, 7, 0, 0x27); 240 + SERDES_AM654_CFG(0x0260, 15, 8, 0x04); 241 + SERDES_AM654_CFG(0x0268, 15, 8, 0x04); 242 + SERDES_AM654_CFG(0x0288, 15, 8, 0x2c); 243 + SERDES_AM654_CFG(0x0330, 31, 24, 0xa0); 244 + SERDES_AM654_CFG(0x0338, 23, 16, 0x03); 245 + SERDES_AM654_CFG(0x0338, 31, 24, 0x00); 246 + SERDES_AM654_CFG(0x033c, 7, 0, 0x00); 247 + SERDES_AM654_CFG(0x0344, 31, 24, 0x18); 248 + SERDES_AM654_CFG(0x034c, 7, 0, 0x18); 249 + SERDES_AM654_CFG(0x039c, 23, 16, 0x3b); 250 + SERDES_AM654_CFG(0x0a04, 7, 0, 0x03); 251 + SERDES_AM654_CFG(0x0a14, 31, 24, 0x3c); 252 + SERDES_AM654_CFG(0x0a18, 15, 8, 0x3c); 253 + SERDES_AM654_CFG(0x0a38, 7, 0, 0x3e); 254 + SERDES_AM654_CFG(0x0a38, 15, 8, 0x3e); 255 + SERDES_AM654_CFG(0x0ae0, 7, 0, 0x07); 256 + SERDES_AM654_CFG(0x0b6c, 23, 16, 0xcd); 257 + SERDES_AM654_CFG(0x0b6c, 31, 24, 0x04); 258 + SERDES_AM654_CFG(0x0b98, 23, 16, 0x03); 259 + SERDES_AM654_CFG(0x1400, 7, 0, 0x3f); 260 + SERDES_AM654_CFG(0x1404, 23, 16, 0x6f); 261 + SERDES_AM654_CFG(0x1404, 31, 24, 0x6f); 262 + SERDES_AM654_CFG(0x140c, 7, 0, 0x6f); 263 + SERDES_AM654_CFG(0x140c, 15, 8, 0x6f); 264 + SERDES_AM654_CFG(0x1410, 15, 8, 0x27); 265 + SERDES_AM654_CFG(0x1414, 7, 0, 0x0c); 266 + SERDES_AM654_CFG(0x1414, 23, 16, 0x07); 267 + SERDES_AM654_CFG(0x1418, 23, 16, 0x40); 268 + SERDES_AM654_CFG(0x141c, 7, 0, 0x00); 269 + SERDES_AM654_CFG(0x141c, 15, 8, 0x1f); 270 + SERDES_AM654_CFG(0x1428, 31, 24, 0x08); 271 + SERDES_AM654_CFG(0x1434, 31, 24, 0x00); 272 + SERDES_AM654_CFG(0x1444, 7, 0, 0x94); 273 + SERDES_AM654_CFG(0x1460, 31, 24, 0x7f); 274 + SERDES_AM654_CFG(0x1464, 7, 0, 0x43); 275 + SERDES_AM654_CFG(0x1464, 23, 16, 0x6f); 276 + SERDES_AM654_CFG(0x1464, 31, 24, 0x43); 277 + SERDES_AM654_CFG(0x1484, 23, 16, 0x8f); 278 + SERDES_AM654_CFG(0x1498, 7, 0, 0x4f); 279 + SERDES_AM654_CFG(0x1498, 23, 16, 0x4f); 280 + SERDES_AM654_CFG(0x007c, 31, 24, 0x0d); 281 + SERDES_AM654_CFG(0x0b90, 15, 8, 0x0f); 282 + 283 + return 0; 284 + } 285 + 286 + static int serdes_am654_pcie_init(struct serdes_am654 *phy) 287 + { 207 288 int ret; 208 289 209 290 ret = regmap_field_write(phy->config_version, VERSION); ··· 303 220 return 0; 304 221 } 305 222 223 + static int serdes_am654_init(struct phy *x) 224 + { 225 + struct serdes_am654 *phy = phy_get_drvdata(x); 226 + 227 + switch (phy->type) { 228 + case PHY_TYPE_PCIE: 229 + return serdes_am654_pcie_init(phy); 230 + case PHY_TYPE_USB3: 231 + return serdes_am654_usb3_init(phy); 232 + default: 233 + return -EINVAL; 234 + } 235 + } 236 + 306 237 static int serdes_am654_reset(struct phy *x) 307 238 { 308 239 struct serdes_am654 *phy = phy_get_drvdata(x); 309 240 int ret; 241 + 242 + serdes_am654_disable_pll(phy); 243 + serdes_am654_disable_txrx(phy); 310 244 311 245 ret = regmap_field_write(phy->por_en, 0x1); 312 246 if (ret)
+60 -5
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> 23 24 24 25 #define WIZ_SERDES_CTRL 0x404 25 26 #define WIZ_SERDES_TOP_CTRL 0x408 ··· 78 77 REG_FIELD(WIZ_LANECTL(2), 30, 31), 79 78 REG_FIELD(WIZ_LANECTL(3), 30, 31), 80 79 }; 80 + 81 + enum p_enable { P_ENABLE = 2, P_ENABLE_FORCE = 1, P_ENABLE_DISABLE = 0 }; 81 82 82 83 static const struct reg_field p_align[WIZ_MAX_LANES] = { 83 84 REG_FIELD(WIZ_LANECTL(0), 29, 29), ··· 223 220 struct reset_controller_dev wiz_phy_reset_dev; 224 221 struct gpio_desc *gpio_typec_dir; 225 222 int typec_dir_delay; 223 + u32 lane_phy_type[WIZ_MAX_LANES]; 226 224 }; 227 225 228 226 static int wiz_reset(struct wiz *wiz) ··· 246 242 static int wiz_mode_select(struct wiz *wiz) 247 243 { 248 244 u32 num_lanes = wiz->num_lanes; 245 + enum wiz_lane_standard_mode mode; 249 246 int ret; 250 247 int i; 251 248 252 249 for (i = 0; i < num_lanes; i++) { 253 - ret = regmap_field_write(wiz->p_standard_mode[i], 254 - LANE_MODE_GEN4); 250 + if (wiz->lane_phy_type[i] == PHY_TYPE_DP) 251 + mode = LANE_MODE_GEN1; 252 + else 253 + mode = LANE_MODE_GEN4; 254 + 255 + ret = regmap_field_write(wiz->p_standard_mode[i], mode); 255 256 if (ret) 256 257 return ret; 257 258 } ··· 716 707 return ret; 717 708 } 718 709 719 - ret = regmap_field_write(wiz->p_enable[id - 1], false); 710 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE); 720 711 return ret; 721 712 } 722 713 ··· 743 734 return ret; 744 735 } 745 736 746 - ret = regmap_field_write(wiz->p_enable[id - 1], true); 737 + if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP) 738 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE); 739 + else 740 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE); 741 + 747 742 return ret; 748 743 } 749 744 ··· 773 760 {} 774 761 }; 775 762 MODULE_DEVICE_TABLE(of, wiz_id_table); 763 + 764 + static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz) 765 + { 766 + struct device_node *serdes, *subnode; 767 + 768 + serdes = of_get_child_by_name(dev->of_node, "serdes"); 769 + if (!serdes) { 770 + dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__); 771 + return -EINVAL; 772 + } 773 + 774 + for_each_child_of_node(serdes, subnode) { 775 + u32 reg, num_lanes = 1, phy_type = PHY_NONE; 776 + int ret, i; 777 + 778 + ret = of_property_read_u32(subnode, "reg", &reg); 779 + if (ret) { 780 + dev_err(dev, 781 + "%s: Reading \"reg\" from \"%s\" failed: %d\n", 782 + __func__, subnode->name, ret); 783 + return ret; 784 + } 785 + of_property_read_u32(subnode, "cdns,num-lanes", &num_lanes); 786 + of_property_read_u32(subnode, "cdns,phy-type", &phy_type); 787 + 788 + dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__, 789 + reg, reg + num_lanes - 1, phy_type); 790 + 791 + for (i = reg; i < reg + num_lanes; i++) 792 + wiz->lane_phy_type[i] = phy_type; 793 + } 794 + 795 + return 0; 796 + } 776 797 777 798 static int wiz_probe(struct platform_device *pdev) 778 799 { ··· 841 794 } 842 795 843 796 base = devm_ioremap(dev, res.start, resource_size(&res)); 844 - if (!base) 797 + if (!base) { 798 + ret = -ENOMEM; 845 799 goto err_addr_to_resource; 800 + } 846 801 847 802 regmap = devm_regmap_init_mmio(dev, base, &wiz_regmap_config); 848 803 if (IS_ERR(regmap)) { ··· 861 812 862 813 if (num_lanes > WIZ_MAX_LANES) { 863 814 dev_err(dev, "Cannot support %d lanes\n", num_lanes); 815 + ret = -ENODEV; 864 816 goto err_addr_to_resource; 865 817 } 866 818 ··· 893 843 goto err_addr_to_resource; 894 844 } 895 845 } 846 + 847 + ret = wiz_get_lane_phy_types(dev, wiz); 848 + if (ret) 849 + return ret; 896 850 897 851 wiz->dev = dev; 898 852 wiz->regmap = regmap; ··· 951 897 serdes_pdev = of_platform_device_create(child_node, NULL, dev); 952 898 if (!serdes_pdev) { 953 899 dev_WARN(dev, "Unable to create SERDES platform device\n"); 900 + ret = -ENOMEM; 954 901 goto err_pdev_create; 955 902 } 956 903 wiz->serdes_pdev = serdes_pdev;
+56 -4
drivers/phy/ti/phy-omap-usb2.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * omap-usb2.c - USB PHY, talking to musb controller in OMAP. 3 + * omap-usb2.c - USB PHY, talking to USB controller on TI SoCs. 4 4 * 5 - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com 5 + * Copyright (C) 2012-2020 Texas Instruments Incorporated - http://www.ti.com 6 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 7 */ 8 8 ··· 23 23 #include <linux/regmap.h> 24 24 #include <linux/of_platform.h> 25 25 26 - #define USB2PHY_DISCON_BYP_LATCH (1 << 31) 27 - #define USB2PHY_ANA_CONFIG1 0x4c 26 + #define USB2PHY_ANA_CONFIG1 0x4c 27 + #define USB2PHY_DISCON_BYP_LATCH BIT(31) 28 28 29 + /* SoC Specific USB2_OTG register definitions */ 29 30 #define AM654_USB2_OTG_PD BIT(8) 30 31 #define AM654_USB2_VBUS_DET_EN BIT(5) 31 32 #define AM654_USB2_VBUSVALID_DET_EN BIT(4) 33 + 34 + #define OMAP_DEV_PHY_PD BIT(0) 35 + #define OMAP_USB2_PHY_PD BIT(28) 36 + 37 + #define AM437X_USB2_PHY_PD BIT(0) 38 + #define AM437X_USB2_OTG_PD BIT(1) 39 + #define AM437X_USB2_OTGVDET_EN BIT(19) 40 + #define AM437X_USB2_OTGSESSEND_EN BIT(20) 41 + 42 + /* Driver Flags */ 43 + #define OMAP_USB2_HAS_START_SRP BIT(0) 44 + #define OMAP_USB2_HAS_SET_VBUS BIT(1) 45 + #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(2) 46 + 47 + struct omap_usb { 48 + struct usb_phy phy; 49 + struct phy_companion *comparator; 50 + void __iomem *pll_ctrl_base; 51 + void __iomem *phy_base; 52 + struct device *dev; 53 + struct device *control_dev; 54 + struct clk *wkupclk; 55 + struct clk *optclk; 56 + u8 flags; 57 + struct regmap *syscon_phy_power; /* ctrl. reg. acces */ 58 + unsigned int power_reg; /* power reg. index within syscon */ 59 + u32 mask; 60 + u32 power_on; 61 + u32 power_off; 62 + }; 63 + 64 + #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) 65 + 66 + struct usb_phy_data { 67 + const char *label; 68 + u8 flags; 69 + u32 mask; 70 + u32 power_on; 71 + u32 power_off; 72 + }; 73 + 74 + static inline u32 omap_usb_readl(void __iomem *addr, unsigned int offset) 75 + { 76 + return __raw_readl(addr + offset); 77 + } 78 + 79 + static inline void omap_usb_writel(void __iomem *addr, unsigned int offset, 80 + u32 data) 81 + { 82 + __raw_writel(data, addr + offset); 83 + } 32 84 33 85 /** 34 86 * omap_usb2_set_comparator - links the comparator present in the sytem with
-1
drivers/thunderbolt/Kconfig
··· 2 2 menuconfig USB4 3 3 tristate "Unified support for USB4 and Thunderbolt" 4 4 depends on PCI 5 - depends on X86 || COMPILE_TEST 6 5 select APPLE_PROPERTIES if EFI_STUB && X86 7 6 select CRC32 8 7 select CRYPTO
+22
drivers/thunderbolt/icm.c
··· 1633 1633 icm_veto_end(tb); 1634 1634 } 1635 1635 1636 + static bool icm_tgl_is_supported(struct tb *tb) 1637 + { 1638 + /* 1639 + * If the firmware is not running use software CM. This platform 1640 + * should fully support both. 1641 + */ 1642 + return icm_firmware_running(tb->nhi); 1643 + } 1644 + 1636 1645 static void icm_handle_notification(struct work_struct *work) 1637 1646 { 1638 1647 struct icm_notification *n = container_of(work, typeof(*n), work); ··· 2269 2260 case PCI_DEVICE_ID_INTEL_ICL_NHI0: 2270 2261 case PCI_DEVICE_ID_INTEL_ICL_NHI1: 2271 2262 icm->is_supported = icm_fr_is_supported; 2263 + icm->driver_ready = icm_icl_driver_ready; 2264 + icm->set_uuid = icm_icl_set_uuid; 2265 + icm->device_connected = icm_icl_device_connected; 2266 + icm->device_disconnected = icm_tr_device_disconnected; 2267 + icm->xdomain_connected = icm_tr_xdomain_connected; 2268 + icm->xdomain_disconnected = icm_tr_xdomain_disconnected; 2269 + icm->rtd3_veto = icm_icl_rtd3_veto; 2270 + tb->cm_ops = &icm_icl_ops; 2271 + break; 2272 + 2273 + case PCI_DEVICE_ID_INTEL_TGL_NHI0: 2274 + case PCI_DEVICE_ID_INTEL_TGL_NHI1: 2275 + icm->is_supported = icm_tgl_is_supported; 2272 2276 icm->driver_ready = icm_icl_driver_ready; 2273 2277 icm->set_uuid = icm_icl_set_uuid; 2274 2278 icm->device_connected = icm_icl_device_connected;
+5
drivers/thunderbolt/nhi.c
··· 1270 1270 .driver_data = (kernel_ulong_t)&icl_nhi_ops }, 1271 1271 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICL_NHI1), 1272 1272 .driver_data = (kernel_ulong_t)&icl_nhi_ops }, 1273 + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL_NHI0), 1274 + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, 1275 + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL_NHI1), 1276 + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, 1273 1277 1274 1278 /* Any USB4 compliant host */ 1275 1279 { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_USB4, ~0) }, ··· 1289 1285 .id_table = nhi_ids, 1290 1286 .probe = nhi_probe, 1291 1287 .remove = nhi_remove, 1288 + .shutdown = nhi_remove, 1292 1289 .driver.pm = &nhi_pm_ops, 1293 1290 }; 1294 1291
+2
drivers/thunderbolt/nhi.h
··· 73 73 #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef 74 74 #define PCI_DEVICE_ID_INTEL_ICL_NHI1 0x8a0d 75 75 #define PCI_DEVICE_ID_INTEL_ICL_NHI0 0x8a17 76 + #define PCI_DEVICE_ID_INTEL_TGL_NHI0 0x9a1b 77 + #define PCI_DEVICE_ID_INTEL_TGL_NHI1 0x9a1d 76 78 77 79 #define PCI_CLASS_SERIAL_USB_USB4 0x0c0340 78 80
-7
drivers/thunderbolt/switch.c
··· 348 348 return ret; 349 349 } 350 350 351 - static int tb_switch_nvm_no_read(void *priv, unsigned int offset, void *val, 352 - size_t bytes) 353 - { 354 - return -EPERM; 355 - } 356 - 357 351 static int tb_switch_nvm_write(void *priv, unsigned int offset, void *val, 358 352 size_t bytes) 359 353 { ··· 393 399 config.read_only = true; 394 400 } else { 395 401 config.name = "nvm_non_active"; 396 - config.reg_read = tb_switch_nvm_no_read; 397 402 config.reg_write = tb_switch_nvm_write; 398 403 config.root_only = true; 399 404 }
+1 -2
drivers/usb/cdns3/cdns3-ti.c
··· 138 138 error = pm_runtime_get_sync(dev); 139 139 if (error < 0) { 140 140 dev_err(dev, "pm_runtime_get_sync failed: %d\n", error); 141 - goto err_get; 141 + goto err; 142 142 } 143 143 144 144 /* assert RESET */ ··· 185 185 186 186 err: 187 187 pm_runtime_put_sync(data->dev); 188 - err_get: 189 188 pm_runtime_disable(data->dev); 190 189 191 190 return error;
+5 -42
drivers/usb/cdns3/core.c
··· 82 82 cdns3_drd_exit(cdns); 83 83 } 84 84 85 - static enum usb_role cdsn3_hw_role_state_machine(struct cdns3 *cdns); 86 - 87 85 /** 88 86 * cdns3_core_init_role - initialize role of operation 89 87 * @cdns: Pointer to cdns3 structure ··· 191 193 } 192 194 193 195 /** 194 - * cdsn3_hw_role_state_machine - role switch state machine based on hw events. 196 + * cdns3_hw_role_state_machine - role switch state machine based on hw events. 195 197 * @cdns: Pointer to controller structure. 196 198 * 197 199 * Returns next role to be entered based on hw events. 198 200 */ 199 - static enum usb_role cdsn3_hw_role_state_machine(struct cdns3 *cdns) 201 + static enum usb_role cdns3_hw_role_state_machine(struct cdns3 *cdns) 200 202 { 201 203 enum usb_role role; 202 204 int id, vbus; ··· 289 291 enum usb_role real_role, current_role; 290 292 int ret = 0; 291 293 292 - /* Do nothing if role based on syfs. */ 293 - if (cdns->role_override) 294 - return 0; 295 - 296 294 pm_runtime_get_sync(cdns->dev); 297 295 298 296 current_role = cdns->role; 299 - real_role = cdsn3_hw_role_state_machine(cdns); 297 + real_role = cdns3_hw_role_state_machine(cdns); 300 298 301 299 /* Do nothing if nothing changed */ 302 300 if (current_role == real_role) ··· 346 352 int ret = 0; 347 353 348 354 pm_runtime_get_sync(cdns->dev); 349 - 350 - /* 351 - * FIXME: switch role framework should be extended to meet 352 - * requirements. Driver assumes that role can be controlled 353 - * by SW or HW. Temporary workaround is to use USB_ROLE_NONE to 354 - * switch from SW to HW control. 355 - * 356 - * For dr_mode == USB_DR_MODE_OTG: 357 - * if user sets USB_ROLE_HOST or USB_ROLE_DEVICE then driver 358 - * sets role_override flag and forces that role. 359 - * if user sets USB_ROLE_NONE, driver clears role_override and lets 360 - * HW state machine take over. 361 - * 362 - * For dr_mode != USB_DR_MODE_OTG: 363 - * Assumptions: 364 - * 1. Restricted user control between NONE and dr_mode. 365 - * 2. Driver doesn't need to rely on role_override flag. 366 - * 3. Driver needs to ensure that HW state machine is never called 367 - * if dr_mode != USB_DR_MODE_OTG. 368 - */ 369 - if (role == USB_ROLE_NONE) 370 - cdns->role_override = 0; 371 - else 372 - cdns->role_override = 1; 373 - 374 - /* 375 - * HW state might have changed so driver need to trigger 376 - * HW state machine if dr_mode == USB_DR_MODE_OTG. 377 - */ 378 - if (!cdns->role_override && cdns->dr_mode == USB_DR_MODE_OTG) { 379 - cdns3_hw_role_switch(cdns); 380 - goto pm_put; 381 - } 382 355 383 356 if (cdns->role == role) 384 357 goto pm_put; ··· 489 528 sw_desc.get = cdns3_role_get; 490 529 sw_desc.allow_userspace_control = true; 491 530 sw_desc.driver_data = cdns; 531 + if (device_property_read_bool(dev, "usb-role-switch")) 532 + sw_desc.fwnode = dev->fwnode; 492 533 493 534 cdns->role_sw = usb_role_switch_register(dev, &sw_desc); 494 535 if (IS_ERR(cdns->role_sw)) {
-2
drivers/usb/cdns3/core.h
··· 62 62 * This field based on firmware setting, kernel configuration 63 63 * and hardware configuration. 64 64 * @role_sw: pointer to role switch object. 65 - * @role_override: set 1 if role rely on SW. 66 65 */ 67 66 struct cdns3 { 68 67 struct device *dev; ··· 89 90 struct mutex mutex; 90 91 enum usb_dr_mode dr_mode; 91 92 struct usb_role_switch *role_sw; 92 - int role_override; 93 93 }; 94 94 95 95 int cdns3_hw_role_switch(struct cdns3 *cdns);
+2 -2
drivers/usb/cdns3/drd.c
··· 329 329 cdns->otg_v1_regs = NULL; 330 330 cdns->otg_regs = regs; 331 331 writel(1, &cdns->otg_v0_regs->simulate); 332 - dev_info(cdns->dev, "DRD version v0 (%08x)\n", 332 + dev_dbg(cdns->dev, "DRD version v0 (%08x)\n", 333 333 readl(&cdns->otg_v0_regs->version)); 334 334 } else { 335 335 cdns->otg_v0_regs = NULL; ··· 337 337 cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd; 338 338 cdns->version = CDNS3_CONTROLLER_V1; 339 339 writel(1, &cdns->otg_v1_regs->simulate); 340 - dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", 340 + dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", 341 341 readl(&cdns->otg_v1_regs->did), 342 342 readl(&cdns->otg_v1_regs->rid)); 343 343 }
-7
drivers/usb/cdns3/ep0.c
··· 332 332 case TEST_K: 333 333 case TEST_SE0_NAK: 334 334 case TEST_PACKET: 335 - cdns3_ep0_complete_setup(priv_dev, 0, 1); 336 - /** 337 - * Little delay to give the controller some time 338 - * for sending status stage. 339 - * This time should be less then 3ms. 340 - */ 341 - mdelay(1); 342 335 cdns3_set_register_bit(&priv_dev->regs->usb_cmd, 343 336 USB_CMD_STMODE | 344 337 USB_STS_TMODE_SEL(tmode - 1));
+8 -7
drivers/usb/cdns3/gadget.c
··· 512 512 } 513 513 514 514 static struct usb_request *cdns3_wa2_gadget_giveback(struct cdns3_device *priv_dev, 515 - struct cdns3_endpoint *priv_ep, 516 - struct cdns3_request *priv_req) 515 + struct cdns3_endpoint *priv_ep, 516 + struct cdns3_request *priv_req) 517 517 { 518 518 if (priv_ep->flags & EP_QUIRK_EXTRA_BUF_EN && 519 519 priv_req->flags & REQUEST_INTERNAL) { ··· 552 552 } 553 553 554 554 static int cdns3_wa2_gadget_ep_queue(struct cdns3_device *priv_dev, 555 - struct cdns3_endpoint *priv_ep, 556 - struct cdns3_request *priv_req) 555 + struct cdns3_endpoint *priv_ep, 556 + struct cdns3_request *priv_req) 557 557 { 558 558 int deferred = 0; 559 559 ··· 1905 1905 } 1906 1906 1907 1907 static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev, 1908 - struct cdns3_endpoint *priv_ep) 1908 + struct cdns3_endpoint *priv_ep) 1909 1909 { 1910 1910 if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER) 1911 1911 return; ··· 1926 1926 } 1927 1927 1928 1928 static void cdns3_configure_dmult(struct cdns3_device *priv_dev, 1929 - struct cdns3_endpoint *priv_ep) 1929 + struct cdns3_endpoint *priv_ep) 1930 1930 { 1931 1931 struct cdns3_usb_regs __iomem *regs = priv_dev->regs; 1932 1932 ··· 2965 2965 2966 2966 priv_ep->flags = 0; 2967 2967 2968 - dev_info(priv_dev->dev, "Initialized %s support: %s %s\n", 2968 + dev_dbg(priv_dev->dev, "Initialized %s support: %s %s\n", 2969 2969 priv_ep->name, 2970 2970 priv_ep->endpoint.caps.type_bulk ? "BULK, INT" : "", 2971 2971 priv_ep->endpoint.caps.type_iso ? "ISO" : ""); ··· 3069 3069 priv_dev->gadget.name = "usb-ss-gadget"; 3070 3070 priv_dev->gadget.sg_supported = 1; 3071 3071 priv_dev->gadget.quirk_avoids_skb_reserve = 1; 3072 + priv_dev->gadget.irq = cdns->dev_irq; 3072 3073 3073 3074 spin_lock_init(&priv_dev->lock); 3074 3075 INIT_WORK(&priv_dev->pending_status_wq,
+26 -11
drivers/usb/chipidea/Kconfig
··· 18 18 19 19 if USB_CHIPIDEA 20 20 21 - config USB_CHIPIDEA_OF 22 - tristate 23 - depends on OF 24 - default USB_CHIPIDEA 25 - 26 - config USB_CHIPIDEA_PCI 27 - tristate 28 - depends on USB_PCI 29 - depends on NOP_USB_XCEIV 30 - default USB_CHIPIDEA 31 - 32 21 config USB_CHIPIDEA_UDC 33 22 bool "ChipIdea device controller" 34 23 depends on USB_GADGET ··· 32 43 help 33 44 Say Y here to enable host controller functionality of the 34 45 ChipIdea driver. 46 + 47 + config USB_CHIPIDEA_PCI 48 + tristate "Enable PCI glue driver" if EMBEDDED 49 + depends on USB_PCI 50 + depends on NOP_USB_XCEIV 51 + default USB_CHIPIDEA 52 + 53 + config USB_CHIPIDEA_MSM 54 + tristate "Enable MSM hsusb glue driver" if EMBEDDED 55 + default USB_CHIPIDEA 56 + 57 + config USB_CHIPIDEA_IMX 58 + tristate "Enable i.MX USB glue driver" if EMBEDDED 59 + depends on OF 60 + default USB_CHIPIDEA 61 + 62 + config USB_CHIPIDEA_GENERIC 63 + tristate "Enable generic USB2 glue driver" if EMBEDDED 64 + default USB_CHIPIDEA 65 + 66 + config USB_CHIPIDEA_TEGRA 67 + tristate "Enable Tegra UDC glue driver" if EMBEDDED 68 + depends on OF 69 + depends on USB_CHIPIDEA_UDC 70 + default USB_CHIPIDEA 71 + 35 72 endif
+5 -8
drivers/usb/chipidea/Makefile
··· 8 8 9 9 # Glue/Bridge layers go here 10 10 11 - obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_usb2.o 12 - obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_msm.o 13 - obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o 14 - 15 - obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o 16 - 17 - obj-$(CONFIG_USB_CHIPIDEA_OF) += usbmisc_imx.o ci_hdrc_imx.o 18 - obj-$(CONFIG_USB_CHIPIDEA_OF) += ci_hdrc_tegra.o 11 + obj-$(CONFIG_USB_CHIPIDEA_GENERIC) += ci_hdrc_usb2.o 12 + obj-$(CONFIG_USB_CHIPIDEA_MSM) += ci_hdrc_msm.o 13 + obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o 14 + obj-$(CONFIG_USB_CHIPIDEA_IMX) += ci_hdrc_imx.o usbmisc_imx.o 15 + obj-$(CONFIG_USB_CHIPIDEA_TEGRA) += ci_hdrc_tegra.o
+1
drivers/usb/chipidea/ci.h
··· 25 25 #define TD_PAGE_COUNT 5 26 26 #define CI_HDRC_PAGE_SIZE 4096ul /* page size for TD's */ 27 27 #define ENDPT_MAX 32 28 + #define CI_MAX_BUF_SIZE (TD_PAGE_COUNT * CI_HDRC_PAGE_SIZE) 28 29 29 30 /****************************************************************************** 30 31 * REGISTERS
+12 -1
drivers/usb/chipidea/ci_hdrc_imx.c
··· 271 271 struct device *dev = ci->dev->parent; 272 272 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); 273 273 int ret = 0; 274 + struct imx_usbmisc_data *mdata = data->usbmisc_data; 274 275 275 276 switch (event) { 276 277 case CI_HDRC_IMX_HSIC_ACTIVE_EVENT: ··· 285 284 } 286 285 break; 287 286 case CI_HDRC_IMX_HSIC_SUSPEND_EVENT: 288 - ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data); 287 + ret = imx_usbmisc_hsic_set_connect(mdata); 289 288 if (ret) 290 289 dev_err(dev, 291 290 "hsic_set_connect failed, err=%d\n", ret); 291 + break; 292 + case CI_HDRC_CONTROLLER_VBUS_EVENT: 293 + if (ci->vbus_active) 294 + ret = imx_usbmisc_charger_detection(mdata, true); 295 + else 296 + ret = imx_usbmisc_charger_detection(mdata, false); 297 + if (ci->usb_phy) 298 + schedule_work(&ci->usb_phy->chg_work); 292 299 break; 293 300 default: 294 301 break; ··· 423 414 } 424 415 425 416 pdata.usb_phy = data->phy; 417 + if (data->usbmisc_data) 418 + data->usbmisc_data->usb_phy = data->phy; 426 419 427 420 if ((of_device_is_compatible(np, "fsl,imx53-usb") || 428 421 of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
+2
drivers/usb/chipidea/ci_hdrc_imx.h
··· 24 24 unsigned int hsic:1; /* HSIC controlller */ 25 25 unsigned int ext_id:1; /* ID from exteranl event */ 26 26 unsigned int ext_vbus:1; /* Vbus from exteranl event */ 27 + struct usb_phy *usb_phy; 27 28 }; 28 29 29 30 int imx_usbmisc_init(struct imx_usbmisc_data *data); ··· 32 31 int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled); 33 32 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data); 34 33 int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on); 34 + int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect); 35 35 36 36 #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
+18 -12
drivers/usb/chipidea/ci_hdrc_usb2.c
··· 28 28 .flags = CI_HDRC_DISABLE_STREAMING, 29 29 }; 30 30 31 - static struct ci_hdrc_platform_data ci_zynq_pdata = { 31 + static const struct ci_hdrc_platform_data ci_zynq_pdata = { 32 32 .capoffset = DEF_CAPOFFSET, 33 33 }; 34 34 35 + static const struct ci_hdrc_platform_data ci_zevio_pdata = { 36 + .capoffset = DEF_CAPOFFSET, 37 + .flags = CI_HDRC_REGS_SHARED | CI_HDRC_FORCE_FULLSPEED, 38 + }; 39 + 35 40 static const struct of_device_id ci_hdrc_usb2_of_match[] = { 36 - { .compatible = "chipidea,usb2"}, 37 - { .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata}, 41 + { .compatible = "chipidea,usb2" }, 42 + { .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata }, 43 + { .compatible = "lsi,zevio-usb", .data = &ci_zevio_pdata }, 38 44 { } 39 45 }; 40 46 MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match); ··· 70 64 if (!priv) 71 65 return -ENOMEM; 72 66 73 - priv->clk = devm_clk_get(dev, NULL); 74 - if (!IS_ERR(priv->clk)) { 75 - ret = clk_prepare_enable(priv->clk); 76 - if (ret) { 77 - dev_err(dev, "failed to enable the clock: %d\n", ret); 78 - return ret; 79 - } 67 + priv->clk = devm_clk_get_optional(dev, NULL); 68 + if (IS_ERR(priv->clk)) 69 + return PTR_ERR(priv->clk); 70 + 71 + ret = clk_prepare_enable(priv->clk); 72 + if (ret) { 73 + dev_err(dev, "failed to enable the clock: %d\n", ret); 74 + return ret; 80 75 } 81 76 82 77 ci_pdata->name = dev_name(dev); ··· 101 94 return 0; 102 95 103 96 clk_err: 104 - if (!IS_ERR(priv->clk)) 105 - clk_disable_unprepare(priv->clk); 97 + clk_disable_unprepare(priv->clk); 106 98 return ret; 107 99 } 108 100
-67
drivers/usb/chipidea/ci_hdrc_zevio.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> 4 - * 5 - * Based off drivers/usb/chipidea/ci_hdrc_msm.c 6 - */ 7 - 8 - #include <linux/module.h> 9 - #include <linux/platform_device.h> 10 - #include <linux/usb/gadget.h> 11 - #include <linux/usb/chipidea.h> 12 - 13 - #include "ci.h" 14 - 15 - static struct ci_hdrc_platform_data ci_hdrc_zevio_platdata = { 16 - .name = "ci_hdrc_zevio", 17 - .flags = CI_HDRC_REGS_SHARED | CI_HDRC_FORCE_FULLSPEED, 18 - .capoffset = DEF_CAPOFFSET, 19 - }; 20 - 21 - static int ci_hdrc_zevio_probe(struct platform_device *pdev) 22 - { 23 - struct platform_device *ci_pdev; 24 - 25 - dev_dbg(&pdev->dev, "ci_hdrc_zevio_probe\n"); 26 - 27 - ci_pdev = ci_hdrc_add_device(&pdev->dev, 28 - pdev->resource, pdev->num_resources, 29 - &ci_hdrc_zevio_platdata); 30 - 31 - if (IS_ERR(ci_pdev)) { 32 - dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n"); 33 - return PTR_ERR(ci_pdev); 34 - } 35 - 36 - platform_set_drvdata(pdev, ci_pdev); 37 - 38 - return 0; 39 - } 40 - 41 - static int ci_hdrc_zevio_remove(struct platform_device *pdev) 42 - { 43 - struct platform_device *ci_pdev = platform_get_drvdata(pdev); 44 - 45 - ci_hdrc_remove_device(ci_pdev); 46 - 47 - return 0; 48 - } 49 - 50 - static const struct of_device_id ci_hdrc_zevio_dt_ids[] = { 51 - { .compatible = "lsi,zevio-usb", }, 52 - { /* sentinel */ } 53 - }; 54 - 55 - static struct platform_driver ci_hdrc_zevio_driver = { 56 - .probe = ci_hdrc_zevio_probe, 57 - .remove = ci_hdrc_zevio_remove, 58 - .driver = { 59 - .name = "zevio_usb", 60 - .of_match_table = ci_hdrc_zevio_dt_ids, 61 - }, 62 - }; 63 - 64 - MODULE_DEVICE_TABLE(of, ci_hdrc_zevio_dt_ids); 65 - module_platform_driver(ci_hdrc_zevio_driver); 66 - 67 - MODULE_LICENSE("GPL v2");
+13 -35
drivers/usb/chipidea/core.c
··· 3 3 * core.c - ChipIdea USB IP core family device controller 4 4 * 5 5 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. 6 + * Copyright (C) 2020 NXP 6 7 * 7 8 * Author: David Lopo 8 - */ 9 - 10 - /* 11 - * Description: ChipIdea USB IP core family device controller 9 + * Peter Chen <peter.chen@nxp.com> 12 10 * 13 - * This driver is composed of several blocks: 14 - * - HW: hardware interface 15 - * - DBG: debug facilities (optional) 16 - * - UTIL: utilities 17 - * - ISR: interrupts handling 18 - * - ENDPT: endpoint operations (Gadget API) 19 - * - GADGET: gadget operations (Gadget API) 20 - * - BUS: bus glue code, bus abstraction layer 21 - * 22 - * Compile Options 23 - * - STALL_IN: non-empty bulk-in pipes cannot be halted 24 - * if defined mass storage compliance succeeds but with warnings 25 - * => case 4: Hi > Dn 26 - * => case 5: Hi > Di 27 - * => case 8: Hi <> Do 28 - * if undefined usbtest 13 fails 29 - * - TRACE: enable function tracing (depends on DEBUG) 30 - * 31 - * Main Features 32 - * - Chapter 9 & Mass Storage Compliance with Gadget File Storage 33 - * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined) 34 - * - Normal & LPM support 35 - * 36 - * USBTEST Report 37 - * - OK: 0-12, 13 (STALL_IN defined) & 14 38 - * - Not Supported: 15 & 16 (ISO) 39 - * 40 - * TODO List 41 - * - Suspend & Remote Wakeup 11 + * Main Features: 12 + * - Four transfers are supported, usbtest is passed 13 + * - USB Certification for gadget: CH9 and Mass Storage are passed 14 + * - Low power mode 15 + * - USB wakeup 42 16 */ 43 17 #include <linux/delay.h> 44 18 #include <linux/device.h> ··· 246 272 ci->rev = ci_get_revision(ci); 247 273 248 274 dev_dbg(ci->dev, 249 - "ChipIdea HDRC found, revision: %d, lpm: %d; cap: %p op: %p\n", 275 + "revision: %d, lpm: %d; cap: %px op: %px\n", 250 276 ci->rev, ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op); 251 277 252 278 /* setup lock mode ? */ ··· 640 666 static struct usb_role_switch_desc ci_role_switch = { 641 667 .set = ci_usb_role_switch_set, 642 668 .get = ci_usb_role_switch_get, 669 + .allow_userspace_control = true, 643 670 }; 644 671 645 672 static int ci_get_platdata(struct device *dev, ··· 1124 1149 1125 1150 if (!ci_otg_is_fsm_mode(ci)) { 1126 1151 /* only update vbus status for peripheral */ 1127 - if (ci->role == CI_ROLE_GADGET) 1152 + if (ci->role == CI_ROLE_GADGET) { 1153 + /* Pull down DP for possible charger detection */ 1154 + hw_write(ci, OP_USBCMD, USBCMD_RS, 0); 1128 1155 ci_handle_vbus_change(ci); 1156 + } 1129 1157 1130 1158 ret = ci_role_start(ci, ci->role); 1131 1159 if (ret) {
+137 -33
drivers/usb/chipidea/udc.c
··· 338 338 *****************************************************************************/ 339 339 340 340 static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, 341 - unsigned length) 341 + unsigned int length, struct scatterlist *s) 342 342 { 343 343 int i; 344 344 u32 temp; ··· 366 366 node->ptr->token |= cpu_to_le32(mul << __ffs(TD_MULTO)); 367 367 } 368 368 369 - temp = (u32) (hwreq->req.dma + hwreq->req.actual); 369 + if (s) { 370 + temp = (u32) (sg_dma_address(s) + hwreq->req.actual); 371 + node->td_remaining_size = CI_MAX_BUF_SIZE - length; 372 + } else { 373 + temp = (u32) (hwreq->req.dma + hwreq->req.actual); 374 + } 375 + 370 376 if (length) { 371 377 node->ptr->page[0] = cpu_to_le32(temp); 372 378 for (i = 1; i < TD_PAGE_COUNT; i++) { ··· 406 400 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num; 407 401 } 408 402 403 + static int prepare_td_for_non_sg(struct ci_hw_ep *hwep, 404 + struct ci_hw_req *hwreq) 405 + { 406 + unsigned int rest = hwreq->req.length; 407 + int pages = TD_PAGE_COUNT; 408 + int ret = 0; 409 + 410 + if (rest == 0) { 411 + ret = add_td_to_list(hwep, hwreq, 0, NULL); 412 + if (ret < 0) 413 + return ret; 414 + } 415 + 416 + /* 417 + * The first buffer could be not page aligned. 418 + * In that case we have to span into one extra td. 419 + */ 420 + if (hwreq->req.dma % PAGE_SIZE) 421 + pages--; 422 + 423 + while (rest > 0) { 424 + unsigned int count = min(hwreq->req.length - hwreq->req.actual, 425 + (unsigned int)(pages * CI_HDRC_PAGE_SIZE)); 426 + 427 + ret = add_td_to_list(hwep, hwreq, count, NULL); 428 + if (ret < 0) 429 + return ret; 430 + 431 + rest -= count; 432 + } 433 + 434 + if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX 435 + && (hwreq->req.length % hwep->ep.maxpacket == 0)) { 436 + ret = add_td_to_list(hwep, hwreq, 0, NULL); 437 + if (ret < 0) 438 + return ret; 439 + } 440 + 441 + return ret; 442 + } 443 + 444 + static int prepare_td_per_sg(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, 445 + struct scatterlist *s) 446 + { 447 + unsigned int rest = sg_dma_len(s); 448 + int ret = 0; 449 + 450 + hwreq->req.actual = 0; 451 + while (rest > 0) { 452 + unsigned int count = min_t(unsigned int, rest, 453 + CI_MAX_BUF_SIZE); 454 + 455 + ret = add_td_to_list(hwep, hwreq, count, s); 456 + if (ret < 0) 457 + return ret; 458 + 459 + rest -= count; 460 + } 461 + 462 + return ret; 463 + } 464 + 465 + static void ci_add_buffer_entry(struct td_node *node, struct scatterlist *s) 466 + { 467 + int empty_td_slot_index = (CI_MAX_BUF_SIZE - node->td_remaining_size) 468 + / CI_HDRC_PAGE_SIZE; 469 + int i; 470 + 471 + node->ptr->token += 472 + cpu_to_le32(sg_dma_len(s) << __ffs(TD_TOTAL_BYTES)); 473 + 474 + for (i = empty_td_slot_index; i < TD_PAGE_COUNT; i++) { 475 + u32 page = (u32) sg_dma_address(s) + 476 + (i - empty_td_slot_index) * CI_HDRC_PAGE_SIZE; 477 + 478 + page &= ~TD_RESERVED_MASK; 479 + node->ptr->page[i] = cpu_to_le32(page); 480 + } 481 + } 482 + 483 + static int prepare_td_for_sg(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) 484 + { 485 + struct usb_request *req = &hwreq->req; 486 + struct scatterlist *s = req->sg; 487 + int ret = 0, i = 0; 488 + struct td_node *node = NULL; 489 + 490 + if (!s || req->zero || req->length == 0) { 491 + dev_err(hwep->ci->dev, "not supported operation for sg\n"); 492 + return -EINVAL; 493 + } 494 + 495 + while (i++ < req->num_mapped_sgs) { 496 + if (sg_dma_address(s) % PAGE_SIZE) { 497 + dev_err(hwep->ci->dev, "not page aligned sg buffer\n"); 498 + return -EINVAL; 499 + } 500 + 501 + if (node && (node->td_remaining_size >= sg_dma_len(s))) { 502 + ci_add_buffer_entry(node, s); 503 + node->td_remaining_size -= sg_dma_len(s); 504 + } else { 505 + ret = prepare_td_per_sg(hwep, hwreq, s); 506 + if (ret) 507 + return ret; 508 + 509 + node = list_entry(hwreq->tds.prev, 510 + struct td_node, td); 511 + } 512 + 513 + s = sg_next(s); 514 + } 515 + 516 + return ret; 517 + } 518 + 409 519 /** 410 520 * _hardware_enqueue: configures a request at hardware level 411 521 * @hwep: endpoint ··· 533 411 { 534 412 struct ci_hdrc *ci = hwep->ci; 535 413 int ret = 0; 536 - unsigned rest = hwreq->req.length; 537 - int pages = TD_PAGE_COUNT; 538 414 struct td_node *firstnode, *lastnode; 539 415 540 416 /* don't queue twice */ ··· 546 426 if (ret) 547 427 return ret; 548 428 549 - /* 550 - * The first buffer could be not page aligned. 551 - * In that case we have to span into one extra td. 552 - */ 553 - if (hwreq->req.dma % PAGE_SIZE) 554 - pages--; 429 + if (hwreq->req.num_mapped_sgs) 430 + ret = prepare_td_for_sg(hwep, hwreq); 431 + else 432 + ret = prepare_td_for_non_sg(hwep, hwreq); 555 433 556 - if (rest == 0) { 557 - ret = add_td_to_list(hwep, hwreq, 0); 558 - if (ret < 0) 559 - goto done; 560 - } 561 - 562 - while (rest > 0) { 563 - unsigned count = min(hwreq->req.length - hwreq->req.actual, 564 - (unsigned)(pages * CI_HDRC_PAGE_SIZE)); 565 - ret = add_td_to_list(hwep, hwreq, count); 566 - if (ret < 0) 567 - goto done; 568 - 569 - rest -= count; 570 - } 571 - 572 - if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX 573 - && (hwreq->req.length % hwep->ep.maxpacket == 0)) { 574 - ret = add_td_to_list(hwep, hwreq, 0); 575 - if (ret < 0) 576 - goto done; 577 - } 434 + if (ret) 435 + return ret; 578 436 579 437 firstnode = list_first_entry(&hwreq->tds, struct td_node, td); 580 438 ··· 1659 1561 { 1660 1562 struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); 1661 1563 unsigned long flags; 1564 + int ret = 0; 1662 1565 1663 1566 spin_lock_irqsave(&ci->lock, flags); 1664 1567 ci->vbus_active = is_active; ··· 1669 1570 usb_phy_set_charger_state(ci->usb_phy, is_active ? 1670 1571 USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); 1671 1572 1573 + if (ci->platdata->notify_event) 1574 + ret = ci->platdata->notify_event(ci, 1575 + CI_HDRC_CONTROLLER_VBUS_EVENT); 1576 + 1672 1577 if (ci->driver) 1673 1578 ci_hdrc_gadget_connect(_gadget, is_active); 1674 1579 1675 - return 0; 1580 + return ret; 1676 1581 } 1677 1582 1678 1583 static int ci_udc_wakeup(struct usb_gadget *_gadget) ··· 2039 1936 ci->gadget.max_speed = USB_SPEED_HIGH; 2040 1937 ci->gadget.name = ci->platdata->name; 2041 1938 ci->gadget.otg_caps = otg_caps; 1939 + ci->gadget.sg_supported = 1; 2042 1940 2043 1941 if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA) 2044 1942 ci->gadget.quirk_avoids_skb_reserve = 1;
+2 -4
drivers/usb/chipidea/udc.h
··· 61 61 struct list_head td; 62 62 dma_addr_t dma; 63 63 struct ci_hw_td *ptr; 64 + int td_remaining_size; 64 65 }; 65 66 66 67 /** 67 68 * struct ci_hw_req - usb request representation 68 69 * @req: request structure for gadget drivers 69 70 * @queue: link to QH list 70 - * @ptr: transfer descriptor for this request 71 - * @dma: dma address for the transfer descriptor 72 - * @zptr: transfer descriptor for the zero packet 73 - * @zdma: dma address of the zero packet's transfer descriptor 71 + * @tds: link to TD list 74 72 */ 75 73 struct ci_hw_req { 76 74 struct usb_request req;
+329 -5
drivers/usb/chipidea/usbmisc_imx.c
··· 8 8 #include <linux/err.h> 9 9 #include <linux/io.h> 10 10 #include <linux/delay.h> 11 + #include <linux/usb/otg.h> 11 12 12 13 #include "ci_hdrc_imx.h" 13 14 ··· 100 99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) 101 100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) 102 101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) 102 + #define MX7D_USBNC_AUTO_RESUME BIT(2) 103 + /* The default DM/DP value is pull-down */ 104 + #define MX7D_USBNC_USB_CTRL2_OPMODE(v) (v << 6) 105 + #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING MX7D_USBNC_USB_CTRL2_OPMODE(1) 106 + #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK (BIT(7) | BIT(6)) 107 + #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN BIT(8) 108 + #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL BIT(12) 109 + #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN BIT(13) 110 + #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL BIT(14) 111 + #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN BIT(15) 112 + #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK (BIT(12) | BIT(13) | \ 113 + BIT(14) | BIT(15)) 114 + 115 + #define MX7D_USB_OTG_PHY_CFG1 0x30 116 + #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL BIT(0) 117 + #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 BIT(1) 118 + #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 BIT(2) 119 + #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB BIT(3) 120 + #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0 BIT(16) 121 + 122 + #define MX7D_USB_OTG_PHY_CFG2 0x34 123 + 124 + #define MX7D_USB_OTG_PHY_STATUS 0x3c 125 + #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0 BIT(0) 126 + #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1 BIT(1) 127 + #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD BIT(3) 128 + #define MX7D_USB_OTG_PHY_STATUS_CHRGDET BIT(29) 103 129 104 130 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ 105 131 MX6_BM_ID_WAKEUP) ··· 142 114 int (*hsic_set_connect)(struct imx_usbmisc_data *data); 143 115 /* It's called during suspend/resume */ 144 116 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); 117 + /* usb charger detection */ 118 + int (*charger_detection)(struct imx_usbmisc_data *data); 145 119 }; 146 120 147 121 struct imx_usbmisc { ··· 639 609 reg |= MX6_BM_PWR_POLARITY; 640 610 writel(reg, usbmisc->base); 641 611 642 - reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 643 - reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 644 - writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 645 - usbmisc->base + MX7D_USBNC_USB_CTRL2); 612 + /* SoC non-burst setting */ 613 + reg = readl(usbmisc->base); 614 + writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 615 + 616 + if (!data->hsic) { 617 + reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 618 + reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 619 + writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID 620 + | MX7D_USBNC_AUTO_RESUME, 621 + usbmisc->base + MX7D_USBNC_USB_CTRL2); 622 + } 623 + 624 + spin_unlock_irqrestore(&usbmisc->lock, flags); 625 + 626 + usbmisc_imx7d_set_wakeup(data, false); 627 + 628 + return 0; 629 + } 630 + 631 + static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data) 632 + { 633 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 634 + struct usb_phy *usb_phy = data->usb_phy; 635 + int val; 636 + unsigned long flags; 637 + 638 + /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */ 639 + spin_lock_irqsave(&usbmisc->lock, flags); 640 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 641 + writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 642 + MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 643 + MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL, 644 + usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 645 + spin_unlock_irqrestore(&usbmisc->lock, flags); 646 + 647 + usleep_range(1000, 2000); 648 + 649 + /* 650 + * Per BC 1.2, check voltage of D+: 651 + * DCP: if greater than VDAT_REF; 652 + * CDP: if less than VDAT_REF. 653 + */ 654 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 655 + if (val & MX7D_USB_OTG_PHY_STATUS_CHRGDET) { 656 + dev_dbg(data->dev, "It is a dedicate charging port\n"); 657 + usb_phy->chg_type = DCP_TYPE; 658 + } else { 659 + dev_dbg(data->dev, "It is a charging downstream port\n"); 660 + usb_phy->chg_type = CDP_TYPE; 661 + } 662 + 663 + return 0; 664 + } 665 + 666 + static void imx7_disable_charger_detector(struct imx_usbmisc_data *data) 667 + { 668 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 669 + unsigned long flags; 670 + u32 val; 671 + 672 + spin_lock_irqsave(&usbmisc->lock, flags); 673 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 674 + val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB | 675 + MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 676 + MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 677 + MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL); 678 + writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 679 + 680 + /* Set OPMODE to be 2'b00 and disable its override */ 681 + val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 682 + val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 683 + writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 684 + 685 + val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 686 + writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 687 + usbmisc->base + MX7D_USBNC_USB_CTRL2); 688 + spin_unlock_irqrestore(&usbmisc->lock, flags); 689 + } 690 + 691 + static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data) 692 + { 693 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 694 + unsigned long flags; 695 + u32 val; 696 + int i, data_pin_contact_count = 0; 697 + 698 + /* Enable Data Contact Detect (DCD) per the USB BC 1.2 */ 699 + spin_lock_irqsave(&usbmisc->lock, flags); 700 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 701 + writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 702 + usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 703 + spin_unlock_irqrestore(&usbmisc->lock, flags); 704 + 705 + for (i = 0; i < 100; i = i + 1) { 706 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 707 + if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) { 708 + if (data_pin_contact_count++ > 5) 709 + /* Data pin makes contact */ 710 + break; 711 + usleep_range(5000, 10000); 712 + } else { 713 + data_pin_contact_count = 0; 714 + usleep_range(5000, 6000); 715 + } 716 + } 717 + 718 + /* Disable DCD after finished data contact check */ 719 + spin_lock_irqsave(&usbmisc->lock, flags); 720 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 721 + writel(val & ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 722 + usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 723 + spin_unlock_irqrestore(&usbmisc->lock, flags); 724 + 725 + if (i == 100) { 726 + dev_err(data->dev, 727 + "VBUS is coming from a dedicated power supply.\n"); 728 + return -ENXIO; 729 + } 730 + 731 + return 0; 732 + } 733 + 734 + static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data) 735 + { 736 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 737 + struct usb_phy *usb_phy = data->usb_phy; 738 + unsigned long flags; 739 + u32 val; 740 + 741 + /* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */ 742 + spin_lock_irqsave(&usbmisc->lock, flags); 743 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 744 + val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL; 745 + writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 746 + MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0, 747 + usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 748 + spin_unlock_irqrestore(&usbmisc->lock, flags); 749 + 750 + usleep_range(1000, 2000); 751 + 752 + /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */ 753 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 754 + if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) { 755 + dev_dbg(data->dev, "It is a standard downstream port\n"); 756 + usb_phy->chg_type = SDP_TYPE; 757 + } 758 + 759 + return 0; 760 + } 761 + 762 + /** 763 + * Whole charger detection process: 764 + * 1. OPMODE override to be non-driving 765 + * 2. Data contact check 766 + * 3. Primary detection 767 + * 4. Secondary detection 768 + * 5. Disable charger detection 769 + */ 770 + static int imx7d_charger_detection(struct imx_usbmisc_data *data) 771 + { 772 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 773 + struct usb_phy *usb_phy = data->usb_phy; 774 + unsigned long flags; 775 + u32 val; 776 + int ret; 777 + 778 + /* Check if vbus is valid */ 779 + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 780 + if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) { 781 + dev_err(data->dev, "vbus is error\n"); 782 + return -EINVAL; 783 + } 784 + 785 + /* 786 + * Keep OPMODE to be non-driving mode during the whole 787 + * charger detection process. 788 + */ 789 + spin_lock_irqsave(&usbmisc->lock, flags); 790 + val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 791 + val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 792 + val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING; 793 + writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 794 + 795 + val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 796 + writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 797 + usbmisc->base + MX7D_USBNC_USB_CTRL2); 798 + spin_unlock_irqrestore(&usbmisc->lock, flags); 799 + 800 + ret = imx7d_charger_data_contact_detect(data); 801 + if (ret) 802 + return ret; 803 + 804 + ret = imx7d_charger_primary_detection(data); 805 + if (!ret && usb_phy->chg_type != SDP_TYPE) 806 + ret = imx7d_charger_secondary_detection(data); 807 + 808 + imx7_disable_charger_detector(data); 809 + 810 + return ret; 811 + } 812 + 813 + static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) 814 + { 815 + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 816 + unsigned long flags; 817 + u32 reg; 818 + 819 + if (data->index >= 1) 820 + return -EINVAL; 821 + 822 + spin_lock_irqsave(&usbmisc->lock, flags); 823 + reg = readl(usbmisc->base); 824 + if (data->disable_oc) { 825 + reg |= MX6_BM_OVER_CUR_DIS; 826 + } else { 827 + reg &= ~MX6_BM_OVER_CUR_DIS; 828 + 829 + /* 830 + * If the polarity is not configured keep it as setup by the 831 + * bootloader. 832 + */ 833 + if (data->oc_pol_configured && data->oc_pol_active_low) 834 + reg |= MX6_BM_OVER_CUR_POLARITY; 835 + else if (data->oc_pol_configured) 836 + reg &= ~MX6_BM_OVER_CUR_POLARITY; 837 + } 838 + /* If the polarity is not set keep it as setup by the bootlader */ 839 + if (data->pwr_pol == 1) 840 + reg |= MX6_BM_PWR_POLARITY; 841 + 842 + writel(reg, usbmisc->base); 843 + 844 + /* SoC non-burst setting */ 845 + reg = readl(usbmisc->base); 846 + writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 847 + 848 + if (data->hsic) { 849 + reg = readl(usbmisc->base); 850 + writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base); 851 + 852 + reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 853 + reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 854 + writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 855 + 856 + /* 857 + * For non-HSIC controller, the autoresume is enabled 858 + * at MXS PHY driver (usbphy_ctrl bit18). 859 + */ 860 + reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 861 + writel(reg | MX7D_USBNC_AUTO_RESUME, 862 + usbmisc->base + MX7D_USBNC_USB_CTRL2); 863 + } else { 864 + reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 865 + reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 866 + writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 867 + usbmisc->base + MX7D_USBNC_USB_CTRL2); 868 + } 646 869 647 870 spin_unlock_irqrestore(&usbmisc->lock, flags); 648 871 ··· 942 659 static const struct usbmisc_ops imx7d_usbmisc_ops = { 943 660 .init = usbmisc_imx7d_init, 944 661 .set_wakeup = usbmisc_imx7d_set_wakeup, 662 + .charger_detection = imx7d_charger_detection, 663 + }; 664 + 665 + static const struct usbmisc_ops imx7ulp_usbmisc_ops = { 666 + .init = usbmisc_imx7ulp_init, 667 + .set_wakeup = usbmisc_imx7d_set_wakeup, 668 + .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 669 + .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 945 670 }; 946 671 947 672 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) ··· 1028 737 return usbmisc->ops->hsic_set_clk(data, on); 1029 738 } 1030 739 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk); 740 + 741 + int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) 742 + { 743 + struct imx_usbmisc *usbmisc; 744 + struct usb_phy *usb_phy; 745 + int ret = 0; 746 + 747 + if (!data) 748 + return -EINVAL; 749 + 750 + usbmisc = dev_get_drvdata(data->dev); 751 + usb_phy = data->usb_phy; 752 + if (!usbmisc->ops->charger_detection) 753 + return -ENOTSUPP; 754 + 755 + if (connect) { 756 + ret = usbmisc->ops->charger_detection(data); 757 + if (ret) { 758 + dev_err(data->dev, 759 + "Error occurs during detection: %d\n", 760 + ret); 761 + usb_phy->chg_state = USB_CHARGER_ABSENT; 762 + } else { 763 + usb_phy->chg_state = USB_CHARGER_PRESENT; 764 + } 765 + } else { 766 + usb_phy->chg_state = USB_CHARGER_ABSENT; 767 + usb_phy->chg_type = UNKNOWN_TYPE; 768 + } 769 + return ret; 770 + } 771 + EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection); 772 + 1031 773 static const struct of_device_id usbmisc_imx_dt_ids[] = { 1032 774 { 1033 775 .compatible = "fsl,imx25-usbmisc", ··· 1104 780 }, 1105 781 { 1106 782 .compatible = "fsl,imx7ulp-usbmisc", 1107 - .data = &imx7d_usbmisc_ops, 783 + .data = &imx7ulp_usbmisc_ops, 1108 784 }, 1109 785 { /* sentinel */ } 1110 786 };
+1 -1
drivers/usb/class/cdc-acm.c
··· 584 584 } 585 585 586 586 if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) { 587 - for (i = 0; i < ACM_NR; i++) 587 + for (i = 0; i < acm->rx_buflimit; i++) 588 588 if (test_and_clear_bit(i, &acm->urbs_in_error_delay)) 589 589 acm_submit_read_urb(acm, i, GFP_NOIO); 590 590 }
+4 -1
drivers/usb/class/usblp.c
··· 468 468 usb_autopm_put_interface(usblp->intf); 469 469 470 470 if (!usblp->present) /* finish cleanup from disconnect */ 471 - usblp_cleanup(usblp); 471 + usblp_cleanup(usblp); /* any URBs must be dead */ 472 + 472 473 mutex_unlock(&usblp_mutex); 473 474 return 0; 474 475 } ··· 1376 1375 1377 1376 usblp_unlink_urbs(usblp); 1378 1377 mutex_unlock(&usblp->mut); 1378 + usb_poison_anchored_urbs(&usblp->urbs); 1379 1379 1380 1380 if (!usblp->used) 1381 1381 usblp_cleanup(usblp); 1382 + 1382 1383 mutex_unlock(&usblp_mutex); 1383 1384 } 1384 1385
+4 -3
drivers/usb/core/hcd-pci.c
··· 159 159 * usb_hcd_pci_probe - initialize PCI-based HCDs 160 160 * @dev: USB Host Controller being probed 161 161 * @id: pci hotplug id connecting controller to HCD framework 162 + * @driver: USB HC driver handle 162 163 * Context: !in_interrupt() 163 164 * 164 165 * Allocates basic PCI resources for this USB host controller, and ··· 170 169 * 171 170 * Return: 0 if successful. 172 171 */ 173 - int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 172 + int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id, 173 + const struct hc_driver *driver) 174 174 { 175 - struct hc_driver *driver; 176 175 struct usb_hcd *hcd; 177 176 int retval; 178 177 int hcd_irq = 0; ··· 182 181 183 182 if (!id) 184 183 return -EINVAL; 185 - driver = (struct hc_driver *)id->driver_data; 184 + 186 185 if (!driver) 187 186 return -EINVAL; 188 187
+1 -1
drivers/usb/core/hub.c
··· 93 93 MODULE_PARM_DESC(old_scheme_first, 94 94 "start with the old device initialization scheme"); 95 95 96 - static bool use_both_schemes = 1; 96 + static bool use_both_schemes = true; 97 97 module_param(use_both_schemes, bool, S_IRUGO | S_IWUSR); 98 98 MODULE_PARM_DESC(use_both_schemes, 99 99 "try the other device initialization scheme if the "
+1 -1
drivers/usb/core/hub.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * usb hub driver head file 4 4 *
+1 -1
drivers/usb/core/otg_whitelist.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * drivers/usb/core/otg_whitelist.h 4 4 *
+4 -2
drivers/usb/core/sysfs.c
··· 1262 1262 1263 1263 if (!alt->string && !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) 1264 1264 alt->string = usb_cache_string(udev, alt->desc.iInterface); 1265 - if (alt->string && device_create_file(&intf->dev, &dev_attr_interface)) 1266 - ; /* We don't actually care if the function fails. */ 1265 + if (alt->string && device_create_file(&intf->dev, &dev_attr_interface)) { 1266 + /* This is not a serious error */ 1267 + dev_dbg(&intf->dev, "interface string descriptor file not created\n"); 1268 + } 1267 1269 intf->sysfs_files_created = 1; 1268 1270 } 1269 1271
+1 -1
drivers/usb/core/usb.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Released under the GPLv2 only. 4 4 */
+19 -4
drivers/usb/dwc2/core.c
··· 524 524 greset |= GRSTCTL_CSFTRST; 525 525 dwc2_writel(hsotg, greset, GRSTCTL); 526 526 527 - if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_CSFTRST, 10000)) { 528 - dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL GRSTCTL_CSFTRST\n", 529 - __func__); 530 - return -EBUSY; 527 + if ((hsotg->hw_params.snpsid & DWC2_CORE_REV_MASK) < 528 + (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { 529 + if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, 530 + GRSTCTL_CSFTRST, 10000)) { 531 + dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST\n", 532 + __func__); 533 + return -EBUSY; 534 + } 535 + } else { 536 + if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, 537 + GRSTCTL_CSFTRST_DONE, 10000)) { 538 + dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST_DONE\n", 539 + __func__); 540 + return -EBUSY; 541 + } 542 + greset = dwc2_readl(hsotg, GRSTCTL); 543 + greset &= ~GRSTCTL_CSFTRST; 544 + greset |= GRSTCTL_CSFTRST_DONE; 545 + dwc2_writel(hsotg, greset, GRSTCTL); 531 546 } 532 547 533 548 /* Wait for AHB master IDLE state */
+5 -1
drivers/usb/dwc2/core.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * core.h - DesignWare HS OTG Controller common declarations 4 4 * ··· 1103 1103 #define DWC2_CORE_REV_3_00a 0x4f54300a 1104 1104 #define DWC2_CORE_REV_3_10a 0x4f54310a 1105 1105 #define DWC2_CORE_REV_4_00a 0x4f54400a 1106 + #define DWC2_CORE_REV_4_20a 0x4f54420a 1106 1107 #define DWC2_FS_IOT_REV_1_00a 0x5531100a 1107 1108 #define DWC2_HS_IOT_REV_1_00a 0x5532100a 1109 + #define DWC2_CORE_REV_MASK 0x0000ffff 1108 1110 1109 1111 /* DWC OTG HW Core ID */ 1110 1112 #define DWC2_OTG_ID 0x4f540000 ··· 1310 1308 void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg); 1311 1309 1312 1310 bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg); 1311 + 1312 + int dwc2_check_core_version(struct dwc2_hsotg *hsotg); 1313 1313 1314 1314 /* 1315 1315 * Common core Functions.
+5 -2
drivers/usb/dwc2/core_intr.c
··· 416 416 if (ret && (ret != -ENOTSUPP)) 417 417 dev_err(hsotg->dev, "exit power_down failed\n"); 418 418 419 + /* Change to L0 state */ 420 + hsotg->lx_state = DWC2_L0; 419 421 call_gadget(hsotg, resume); 422 + } else { 423 + /* Change to L0 state */ 424 + hsotg->lx_state = DWC2_L0; 420 425 } 421 - /* Change to L0 state */ 422 - hsotg->lx_state = DWC2_L0; 423 426 } else { 424 427 if (hsotg->params.power_down) 425 428 return;
+1 -1
drivers/usb/dwc2/debug.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * debug.h - Designware USB2 DRD controller debug header 4 4 *
+1 -1
drivers/usb/dwc2/hcd.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * hcd.h - DesignWare HS OTG Controller host-mode declarations 4 4 *
+2 -1
drivers/usb/dwc2/hw.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * hw.h - DesignWare HS OTG Controller hardware definitions 4 4 * ··· 126 126 #define GRSTCTL HSOTG_REG(0x010) 127 127 #define GRSTCTL_AHBIDLE BIT(31) 128 128 #define GRSTCTL_DMAREQ BIT(30) 129 + #define GRSTCTL_CSFTRST_DONE BIT(29) 129 130 #define GRSTCTL_TXFNUM_MASK (0x1f << 6) 130 131 #define GRSTCTL_TXFNUM_SHIFT 6 131 132 #define GRSTCTL_TXFNUM_LIMIT 0x1f
-19
drivers/usb/dwc2/params.c
··· 782 782 u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; 783 783 u32 grxfsiz; 784 784 785 - /* 786 - * Attempt to ensure this device is really a DWC_otg Controller. 787 - * Read and verify the GSNPSID register contents. The value should be 788 - * 0x45f4xxxx, 0x5531xxxx or 0x5532xxxx 789 - */ 790 - 791 - hw->snpsid = dwc2_readl(hsotg, GSNPSID); 792 - if ((hw->snpsid & GSNPSID_ID_MASK) != DWC2_OTG_ID && 793 - (hw->snpsid & GSNPSID_ID_MASK) != DWC2_FS_IOT_ID && 794 - (hw->snpsid & GSNPSID_ID_MASK) != DWC2_HS_IOT_ID) { 795 - dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", 796 - hw->snpsid); 797 - return -ENODEV; 798 - } 799 - 800 - dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n", 801 - hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, 802 - hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); 803 - 804 785 hwcfg1 = dwc2_readl(hsotg, GHWCFG1); 805 786 hwcfg2 = dwc2_readl(hsotg, GHWCFG2); 806 787 hwcfg3 = dwc2_readl(hsotg, GHWCFG3);
+39
drivers/usb/dwc2/platform.c
··· 363 363 } 364 364 365 365 /** 366 + * Check core version 367 + * 368 + * @hsotg: Programming view of the DWC_otg controller 369 + * 370 + */ 371 + int dwc2_check_core_version(struct dwc2_hsotg *hsotg) 372 + { 373 + struct dwc2_hw_params *hw = &hsotg->hw_params; 374 + 375 + /* 376 + * Attempt to ensure this device is really a DWC_otg Controller. 377 + * Read and verify the GSNPSID register contents. The value should be 378 + * 0x45f4xxxx, 0x5531xxxx or 0x5532xxxx 379 + */ 380 + 381 + hw->snpsid = dwc2_readl(hsotg, GSNPSID); 382 + if ((hw->snpsid & GSNPSID_ID_MASK) != DWC2_OTG_ID && 383 + (hw->snpsid & GSNPSID_ID_MASK) != DWC2_FS_IOT_ID && 384 + (hw->snpsid & GSNPSID_ID_MASK) != DWC2_HS_IOT_ID) { 385 + dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", 386 + hw->snpsid); 387 + return -ENODEV; 388 + } 389 + 390 + dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n", 391 + hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, 392 + hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); 393 + return 0; 394 + } 395 + 396 + /** 366 397 * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg 367 398 * driver 368 399 * ··· 474 443 hsotg->need_phy_for_wake = 475 444 of_property_read_bool(dev->dev.of_node, 476 445 "snps,need-phy-for-wake"); 446 + 447 + /* 448 + * Before performing any core related operations 449 + * check core version. 450 + */ 451 + retval = dwc2_check_core_version(hsotg); 452 + if (retval) 453 + goto error; 477 454 478 455 /* 479 456 * Reset before dwc2_get_hwparams() then it could get power-on real
+32 -30
drivers/usb/dwc3/core.c
··· 85 85 * specified or set to OTG, then set the mode to peripheral. 86 86 */ 87 87 if (mode == USB_DR_MODE_OTG && 88 - dwc->revision >= DWC3_REVISION_330A) 88 + (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) || 89 + !device_property_read_bool(dwc->dev, "usb-role-switch")) && 90 + !DWC3_VER_IS_PRIOR(DWC3, 330A)) 89 91 mode = USB_DR_MODE_PERIPHERAL; 90 92 } 91 93 ··· 123 121 if (dwc->dr_mode != USB_DR_MODE_OTG) 124 122 return; 125 123 124 + pm_runtime_get_sync(dwc->dev); 125 + 126 126 if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) 127 127 dwc3_otg_update(dwc, 0); 128 128 129 129 if (!dwc->desired_dr_role) 130 - return; 130 + goto out; 131 131 132 132 if (dwc->desired_dr_role == dwc->current_dr_role) 133 - return; 133 + goto out; 134 134 135 135 if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) 136 - return; 136 + goto out; 137 137 138 138 switch (dwc->current_dr_role) { 139 139 case DWC3_GCTL_PRTCAP_HOST: ··· 194 190 break; 195 191 } 196 192 193 + out: 194 + pm_runtime_mark_last_busy(dwc->dev); 195 + pm_runtime_put_autosuspend(dwc->dev); 197 196 } 198 197 199 198 void dwc3_set_mode(struct dwc3 *dwc, u32 mode) ··· 264 257 * take a little more than 50ms. Set the polling rate at 20ms 265 258 * for 10 times instead. 266 259 */ 267 - if (dwc3_is_usb31(dwc) && dwc->revision >= DWC3_USB31_REVISION_190A) 260 + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) 268 261 retries = 10; 269 262 270 263 do { ··· 272 265 if (!(reg & DWC3_DCTL_CSFTRST)) 273 266 goto done; 274 267 275 - if (dwc3_is_usb31(dwc) && 276 - dwc->revision >= DWC3_USB31_REVISION_190A) 268 + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) 277 269 msleep(20); 278 270 else 279 271 udelay(1); ··· 289 283 * is cleared, we must wait at least 50ms before accessing the PHY 290 284 * domain (synchronization delay). 291 285 */ 292 - if (dwc3_is_usb31(dwc) && dwc->revision <= DWC3_USB31_REVISION_180A) 286 + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A)) 293 287 msleep(50); 294 288 295 289 return 0; ··· 304 298 u32 reg; 305 299 u32 dft; 306 300 307 - if (dwc->revision < DWC3_REVISION_250A) 301 + if (DWC3_VER_IS_PRIOR(DWC3, 250A)) 308 302 return; 309 303 310 304 if (dwc->fladj == 0) ··· 585 579 * will be '0' when the core is reset. Application needs to set it 586 580 * to '1' after the core initialization is completed. 587 581 */ 588 - if (dwc->revision > DWC3_REVISION_194A) 582 + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) 589 583 reg |= DWC3_GUSB3PIPECTL_SUSPHY; 590 584 591 585 /* ··· 676 670 * be '0' when the core is reset. Application needs to set it to 677 671 * '1' after the core initialization is completed. 678 672 */ 679 - if (dwc->revision > DWC3_REVISION_194A) 673 + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) 680 674 reg |= DWC3_GUSB2PHYCFG_SUSPHY; 681 675 682 676 /* ··· 725 719 u32 reg; 726 720 727 721 reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); 722 + dwc->ip = DWC3_GSNPS_ID(reg); 728 723 729 724 /* This should read as U3 followed by revision number */ 730 - if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) { 731 - /* Detected DWC_usb3 IP */ 725 + if (DWC3_IP_IS(DWC3)) { 732 726 dwc->revision = reg; 733 - } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) { 734 - /* Detected DWC_usb31 IP */ 727 + } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) { 735 728 dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); 736 - dwc->revision |= DWC3_REVISION_IS_DWC31; 737 729 dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE); 738 730 } else { 739 731 return false; ··· 764 760 */ 765 761 if ((dwc->dr_mode == USB_DR_MODE_HOST || 766 762 dwc->dr_mode == USB_DR_MODE_OTG) && 767 - (dwc->revision >= DWC3_REVISION_210A && 768 - dwc->revision <= DWC3_REVISION_250A)) 763 + DWC3_VER_IS_WITHIN(DWC3, 210A, 250A)) 769 764 reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; 770 765 else 771 766 reg &= ~DWC3_GCTL_DSBLCLKGTNG; ··· 807 804 * and falls back to high-speed mode which causes 808 805 * the device to enter a Connect/Disconnect loop 809 806 */ 810 - if (dwc->revision < DWC3_REVISION_190A) 807 + if (DWC3_VER_IS_PRIOR(DWC3, 190A)) 811 808 reg |= DWC3_GCTL_U2RSTECN; 812 809 813 810 dwc3_writel(dwc->regs, DWC3_GCTL, reg); ··· 960 957 goto err0a; 961 958 962 959 if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && 963 - dwc->revision > DWC3_REVISION_194A) { 960 + !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) { 964 961 if (!dwc->dis_u3_susphy_quirk) { 965 962 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); 966 963 reg |= DWC3_GUSB3PIPECTL_SUSPHY; ··· 1007 1004 * the DWC_usb3 controller. It is NOT available in the 1008 1005 * DWC_usb31 controller. 1009 1006 */ 1010 - if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { 1007 + if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) { 1011 1008 reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); 1012 1009 reg |= DWC3_GUCTL2_RST_ACTBITLATER; 1013 1010 dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); 1014 1011 } 1015 1012 1016 - if (dwc->revision >= DWC3_REVISION_250A) { 1013 + if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) { 1017 1014 reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); 1018 1015 1019 1016 /* 1020 1017 * Enable hardware control of sending remote wakeup 1021 1018 * in HS when the device is in the L1 state. 1022 1019 */ 1023 - if (dwc->revision >= DWC3_REVISION_290A) 1020 + if (!DWC3_VER_IS_PRIOR(DWC3, 290A)) 1024 1021 reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; 1025 1022 1026 1023 if (dwc->dis_tx_ipgap_linecheck_quirk) ··· 1052 1049 * Must config both number of packets and max burst settings to enable 1053 1050 * RX and/or TX threshold. 1054 1051 */ 1055 - if (dwc3_is_usb31(dwc) && dwc->dr_mode == USB_DR_MODE_HOST) { 1052 + if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { 1056 1053 u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; 1057 1054 u8 rx_maxburst = dwc->rx_max_burst_prd; 1058 1055 u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; ··· 1374 1371 /* check whether the core supports IMOD */ 1375 1372 bool dwc3_has_imod(struct dwc3 *dwc) 1376 1373 { 1377 - return ((dwc3_is_usb3(dwc) && 1378 - dwc->revision >= DWC3_REVISION_300A) || 1379 - (dwc3_is_usb31(dwc) && 1380 - dwc->revision >= DWC3_USB31_REVISION_120A)); 1374 + return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) || 1375 + DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) || 1376 + DWC3_IP_IS(DWC32); 1381 1377 } 1382 1378 1383 1379 static void dwc3_check_params(struct dwc3 *dwc) ··· 1397 1395 * affected version. 1398 1396 */ 1399 1397 if (!dwc->imod_interval && 1400 - (dwc->revision == DWC3_REVISION_300A)) 1398 + DWC3_VER_IS(DWC3, 300A)) 1401 1399 dwc->imod_interval = 1; 1402 1400 1403 1401 /* Check the maximum_speed parameter */ ··· 1419 1417 /* 1420 1418 * default to superspeed plus if we are capable. 1421 1419 */ 1422 - if (dwc3_is_usb31(dwc) && 1420 + if ((DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) && 1423 1421 (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == 1424 1422 DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) 1425 1423 dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
+53 -30
drivers/usb/dwc3/core.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * core.h - DesignWare USB3 DRD Core Header 4 4 * ··· 69 69 #define DWC3_GEVNTCOUNT_EHB BIT(31) 70 70 #define DWC3_GSNPSID_MASK 0xffff0000 71 71 #define DWC3_GSNPSREV_MASK 0xffff 72 + #define DWC3_GSNPS_ID(p) (((p) & DWC3_GSNPSID_MASK) >> 16) 72 73 73 74 /* DWC3 registers memory space boundries */ 74 75 #define DWC3_XHCI_REGS_START 0x0 ··· 366 365 #define DWC3_GHWPARAMS6_SRPSUPPORT BIT(10) 367 366 #define DWC3_GHWPARAMS6_EN_FPGA BIT(7) 368 367 368 + /* DWC_usb32 only */ 369 + #define DWC3_GHWPARAMS6_MDWIDTH(n) ((n) & (0x3 << 8)) 370 + 369 371 /* Global HWPARAMS7 Register */ 370 372 #define DWC3_GHWPARAMS7_RAM1_DEPTH(n) ((n) & 0xffff) 371 373 #define DWC3_GHWPARAMS7_RAM2_DEPTH(n) (((n) >> 16) & 0xffff) ··· 495 491 #define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09 496 492 #define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a 497 493 #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c 494 + #define DWC3_DGCMD_SET_ENDPOINT_PRIME 0x0d 498 495 #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 499 496 500 497 #define DWC3_DGCMD_STATUS(n) (((n) >> 12) & 0x0F) ··· 702 697 #define DWC3_EP_END_TRANSFER_PENDING BIT(4) 703 698 #define DWC3_EP_PENDING_REQUEST BIT(5) 704 699 #define DWC3_EP_DELAY_START BIT(6) 700 + #define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7) 701 + #define DWC3_EP_IGNORE_NEXT_NOSTREAM BIT(8) 702 + #define DWC3_EP_FORCE_RESTART_STREAM BIT(9) 703 + #define DWC3_EP_FIRST_STREAM_PRIMED BIT(10) 705 704 706 705 /* This last one is specific to EP0 */ 707 706 #define DWC3_EP0_DIR_IN BIT(31) ··· 958 949 * @nr_scratch: number of scratch buffers 959 950 * @u1u2: only used on revisions <1.83a for workaround 960 951 * @maximum_speed: maximum speed requested (mainly for testing purposes) 961 - * @revision: revision register contents 952 + * @ip: controller's ID 953 + * @revision: controller's version of an IP 962 954 * @version_type: VERSIONTYPE register contents, a sub release of a revision 963 955 * @dr_mode: requested mode of operation 964 956 * @current_dr_role: current role of operation when in dual-role mode ··· 1120 1110 u32 u1u2; 1121 1111 u32 maximum_speed; 1122 1112 1123 - /* 1124 - * All 3.1 IP version constants are greater than the 3.0 IP 1125 - * version constants. This works for most version checks in 1126 - * dwc3. However, in the future, this may not apply as 1127 - * features may be developed on newer versions of the 3.0 IP 1128 - * that are not in the 3.1 IP. 1129 - */ 1113 + u32 ip; 1114 + 1115 + #define DWC3_IP 0x5533 1116 + #define DWC31_IP 0x3331 1117 + #define DWC32_IP 0x3332 1118 + 1130 1119 u32 revision; 1131 1120 1121 + #define DWC3_REVISION_ANY 0x0 1132 1122 #define DWC3_REVISION_173A 0x5533173a 1133 1123 #define DWC3_REVISION_175A 0x5533175a 1134 1124 #define DWC3_REVISION_180A 0x5533180a ··· 1153 1143 #define DWC3_REVISION_310A 0x5533310a 1154 1144 #define DWC3_REVISION_330A 0x5533330a 1155 1145 1156 - /* 1157 - * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really 1158 - * just so dwc31 revisions are always larger than dwc3. 1159 - */ 1160 - #define DWC3_REVISION_IS_DWC31 0x80000000 1161 - #define DWC3_USB31_REVISION_110A (0x3131302a | DWC3_REVISION_IS_DWC31) 1162 - #define DWC3_USB31_REVISION_120A (0x3132302a | DWC3_REVISION_IS_DWC31) 1163 - #define DWC3_USB31_REVISION_160A (0x3136302a | DWC3_REVISION_IS_DWC31) 1164 - #define DWC3_USB31_REVISION_170A (0x3137302a | DWC3_REVISION_IS_DWC31) 1165 - #define DWC3_USB31_REVISION_180A (0x3138302a | DWC3_REVISION_IS_DWC31) 1166 - #define DWC3_USB31_REVISION_190A (0x3139302a | DWC3_REVISION_IS_DWC31) 1146 + #define DWC31_REVISION_ANY 0x0 1147 + #define DWC31_REVISION_110A 0x3131302a 1148 + #define DWC31_REVISION_120A 0x3132302a 1149 + #define DWC31_REVISION_160A 0x3136302a 1150 + #define DWC31_REVISION_170A 0x3137302a 1151 + #define DWC31_REVISION_180A 0x3138302a 1152 + #define DWC31_REVISION_190A 0x3139302a 1153 + 1154 + #define DWC32_REVISION_ANY 0x0 1155 + #define DWC32_REVISION_100A 0x3130302a 1167 1156 1168 1157 u32 version_type; 1169 1158 1159 + #define DWC31_VERSIONTYPE_ANY 0x0 1170 1160 #define DWC31_VERSIONTYPE_EA01 0x65613031 1171 1161 #define DWC31_VERSIONTYPE_EA02 0x65613032 1172 1162 #define DWC31_VERSIONTYPE_EA03 0x65613033 ··· 1308 1298 #define DEPEVT_STREAMEVT_FOUND 1 1309 1299 #define DEPEVT_STREAMEVT_NOTFOUND 2 1310 1300 1301 + /* Stream event parameter */ 1302 + #define DEPEVT_STREAM_PRIME 0xfffe 1303 + #define DEPEVT_STREAM_NOSTREAM 0x0 1304 + 1311 1305 /* Control-only Status */ 1312 1306 #define DEPEVT_STATUS_CONTROL_DATA 1 1313 1307 #define DEPEVT_STATUS_CONTROL_STATUS 2 ··· 1414 1400 void dwc3_set_mode(struct dwc3 *dwc, u32 mode); 1415 1401 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); 1416 1402 1417 - /* check whether we are on the DWC_usb3 core */ 1418 - static inline bool dwc3_is_usb3(struct dwc3 *dwc) 1419 - { 1420 - return !(dwc->revision & DWC3_REVISION_IS_DWC31); 1421 - } 1403 + #define DWC3_IP_IS(_ip) \ 1404 + (dwc->ip == _ip##_IP) 1422 1405 1423 - /* check whether we are on the DWC_usb31 core */ 1424 - static inline bool dwc3_is_usb31(struct dwc3 *dwc) 1425 - { 1426 - return !!(dwc->revision & DWC3_REVISION_IS_DWC31); 1427 - } 1406 + #define DWC3_VER_IS(_ip, _ver) \ 1407 + (DWC3_IP_IS(_ip) && dwc->revision == _ip##_REVISION_##_ver) 1408 + 1409 + #define DWC3_VER_IS_PRIOR(_ip, _ver) \ 1410 + (DWC3_IP_IS(_ip) && dwc->revision < _ip##_REVISION_##_ver) 1411 + 1412 + #define DWC3_VER_IS_WITHIN(_ip, _from, _to) \ 1413 + (DWC3_IP_IS(_ip) && \ 1414 + dwc->revision >= _ip##_REVISION_##_from && \ 1415 + (!(_ip##_REVISION_##_to) || \ 1416 + dwc->revision <= _ip##_REVISION_##_to)) 1417 + 1418 + #define DWC3_VER_TYPE_IS_WITHIN(_ip, _ver, _from, _to) \ 1419 + (DWC3_VER_IS(_ip, _ver) && \ 1420 + dwc->version_type >= _ip##_VERSIONTYPE_##_from && \ 1421 + (!(_ip##_VERSIONTYPE_##_to) || \ 1422 + dwc->version_type <= _ip##_VERSIONTYPE_##_to)) 1428 1423 1429 1424 bool dwc3_has_imod(struct dwc3 *dwc); 1430 1425
+3 -1
drivers/usb/dwc3/debug.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /** 3 3 * debug.h - DesignWare USB3 DRD Controller Debug Header 4 4 * ··· 68 68 return "All FIFO Flush"; 69 69 case DWC3_DGCMD_SET_ENDPOINT_NRDY: 70 70 return "Set Endpoint NRDY"; 71 + case DWC3_DGCMD_SET_ENDPOINT_PRIME: 72 + return "Set Endpoint Prime"; 71 73 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: 72 74 return "Run SoC Bus Loopback Test"; 73 75 default:
+12 -2
drivers/usb/dwc3/debugfs.c
··· 635 635 struct dwc3_ep *dep = s->private; 636 636 struct dwc3 *dwc = dep->dwc; 637 637 unsigned long flags; 638 + int mdwidth; 638 639 u32 val; 639 640 640 641 spin_lock_irqsave(&dwc->lock, flags); 641 642 val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); 642 643 643 644 /* Convert to bytes */ 644 - val *= DWC3_MDWIDTH(dwc->hwparams.hwparams0); 645 + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 646 + if (DWC3_IP_IS(DWC32)) 647 + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 648 + 649 + val *= mdwidth; 645 650 val >>= 3; 646 651 seq_printf(s, "%u\n", val); 647 652 spin_unlock_irqrestore(&dwc->lock, flags); ··· 659 654 struct dwc3_ep *dep = s->private; 660 655 struct dwc3 *dwc = dep->dwc; 661 656 unsigned long flags; 657 + int mdwidth; 662 658 u32 val; 663 659 664 660 spin_lock_irqsave(&dwc->lock, flags); 665 661 val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); 666 662 667 663 /* Convert to bytes */ 668 - val *= DWC3_MDWIDTH(dwc->hwparams.hwparams0); 664 + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 665 + if (DWC3_IP_IS(DWC32)) 666 + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 667 + 668 + val *= mdwidth; 669 669 val >>= 3; 670 670 seq_printf(s, "%u\n", val); 671 671 spin_unlock_irqrestore(&dwc->lock, flags);
+3 -3
drivers/usb/dwc3/drd.c
··· 56 56 spin_lock(&dwc->lock); 57 57 if (dwc->otg_restart_host) { 58 58 dwc3_otg_host_init(dwc); 59 - dwc->otg_restart_host = 0; 59 + dwc->otg_restart_host = false; 60 60 } 61 61 62 62 spin_unlock(&dwc->lock); ··· 82 82 83 83 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST && 84 84 !(reg & DWC3_OEVT_DEVICEMODE)) 85 - dwc->otg_restart_host = 1; 85 + dwc->otg_restart_host = true; 86 86 dwc3_writel(dwc->regs, DWC3_OEVT, reg); 87 87 ret = IRQ_WAKE_THREAD; 88 88 } ··· 653 653 break; 654 654 } 655 655 656 - if (!dwc->edev) 656 + if (dwc->otg_irq) 657 657 free_irq(dwc->otg_irq, dwc); 658 658 }
+40 -1
drivers/usb/dwc3/dwc3-keystone.c
··· 14 14 #include <linux/dma-mapping.h> 15 15 #include <linux/io.h> 16 16 #include <linux/of_platform.h> 17 + #include <linux/phy/phy.h> 17 18 #include <linux/pm_runtime.h> 18 19 19 20 /* USBSS register offsets */ ··· 35 34 struct dwc3_keystone { 36 35 struct device *dev; 37 36 void __iomem *usbss; 37 + struct phy *usb3_phy; 38 38 }; 39 39 40 40 static inline u32 kdwc3_readl(void __iomem *base, u32 offset) ··· 97 95 if (IS_ERR(kdwc->usbss)) 98 96 return PTR_ERR(kdwc->usbss); 99 97 100 - pm_runtime_enable(kdwc->dev); 98 + /* PSC dependency on AM65 needs SERDES0 to be powered before USB0 */ 99 + kdwc->usb3_phy = devm_phy_optional_get(dev, "usb3-phy"); 100 + if (IS_ERR(kdwc->usb3_phy)) { 101 + error = PTR_ERR(kdwc->usb3_phy); 102 + if (error != -EPROBE_DEFER) 103 + dev_err(dev, "couldn't get usb3 phy: %d\n", error); 101 104 105 + return error; 106 + } 107 + 108 + phy_pm_runtime_get_sync(kdwc->usb3_phy); 109 + 110 + error = phy_reset(kdwc->usb3_phy); 111 + if (error < 0) { 112 + dev_err(dev, "usb3 phy reset failed: %d\n", error); 113 + return error; 114 + } 115 + 116 + error = phy_init(kdwc->usb3_phy); 117 + if (error < 0) { 118 + dev_err(dev, "usb3 phy init failed: %d\n", error); 119 + return error; 120 + } 121 + 122 + error = phy_power_on(kdwc->usb3_phy); 123 + if (error < 0) { 124 + dev_err(dev, "usb3 phy power on failed: %d\n", error); 125 + phy_exit(kdwc->usb3_phy); 126 + return error; 127 + } 128 + 129 + pm_runtime_enable(kdwc->dev); 102 130 error = pm_runtime_get_sync(kdwc->dev); 103 131 if (error < 0) { 104 132 dev_err(kdwc->dev, "pm_runtime_get_sync failed, error %d\n", ··· 170 138 err_irq: 171 139 pm_runtime_put_sync(kdwc->dev); 172 140 pm_runtime_disable(kdwc->dev); 141 + phy_power_off(kdwc->usb3_phy); 142 + phy_exit(kdwc->usb3_phy); 143 + phy_pm_runtime_put_sync(kdwc->usb3_phy); 173 144 174 145 return error; 175 146 } ··· 197 162 device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core); 198 163 pm_runtime_put_sync(kdwc->dev); 199 164 pm_runtime_disable(kdwc->dev); 165 + 166 + phy_power_off(kdwc->usb3_phy); 167 + phy_exit(kdwc->usb3_phy); 168 + phy_pm_runtime_put_sync(kdwc->usb3_phy); 200 169 201 170 platform_set_drvdata(pdev, NULL); 202 171
+339 -83
drivers/usb/dwc3/dwc3-meson-g12a.c
··· 30 30 #include <linux/usb/role.h> 31 31 #include <linux/regulator/consumer.h> 32 32 33 - /* USB2 Ports Control Registers */ 33 + /* USB2 Ports Control Registers, offsets are per-port */ 34 34 35 35 #define U2P_REG_SIZE 0x20 36 36 ··· 50 50 51 51 /* USB Glue Control Registers */ 52 52 53 - #define USB_R0 0x80 53 + #define G12A_GLUE_OFFSET 0x80 54 + 55 + #define USB_R0 0x00 54 56 #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17) 55 57 #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18) 56 58 #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19) 57 59 #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29) 58 60 #define USB_R0_U2D_ACT BIT(31) 59 61 60 - #define USB_R1 0x84 62 + #define USB_R1 0x04 61 63 #define USB_R1_U3H_BIGENDIAN_GS BIT(0) 62 64 #define USB_R1_U3H_PME_ENABLE BIT(1) 63 65 #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(4, 2) ··· 71 69 #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19) 72 70 #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25) 73 71 74 - #define USB_R2 0x88 72 + #define USB_R2 0x08 75 73 #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20) 76 74 #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26) 77 75 78 - #define USB_R3 0x8c 76 + #define USB_R3 0x0c 79 77 #define USB_R3_P30_SSC_ENABLE BIT(0) 80 78 #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1) 81 79 #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4) 82 80 #define USB_R3_P30_REF_SSP_EN BIT(13) 83 81 84 - #define USB_R4 0x90 82 + #define USB_R4 0x10 85 83 #define USB_R4_P21_PORT_RESET_0 BIT(0) 86 84 #define USB_R4_P21_SLEEP_M0 BIT(1) 87 85 #define USB_R4_MEM_PD_MASK GENMASK(3, 2) 88 86 #define USB_R4_P21_ONLY BIT(4) 89 87 90 - #define USB_R5 0x94 88 + #define USB_R5 0x14 91 89 #define USB_R5_ID_DIG_SYNC BIT(0) 92 90 #define USB_R5_ID_DIG_REG BIT(1) 93 91 #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2) ··· 98 96 #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8) 99 97 #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16) 100 98 101 - enum { 102 - USB2_HOST_PHY = 0, 103 - USB2_OTG_PHY, 104 - USB3_HOST_PHY, 105 - PHY_COUNT, 106 - }; 99 + #define PHY_COUNT 3 100 + #define USB2_OTG_PHY 1 107 101 108 - static const char *phy_names[PHY_COUNT] = { 109 - "usb2-phy0", "usb2-phy1", "usb3-phy0", 102 + static struct clk_bulk_data meson_gxl_clocks[] = { 103 + { .id = "usb_ctrl" }, 104 + { .id = "ddr" }, 110 105 }; 111 106 112 107 static struct clk_bulk_data meson_g12a_clocks[] = { ··· 116 117 { .id = "xtal_usb_ctrl" }, 117 118 }; 118 119 120 + static const char *meson_gxm_phy_names[] = { 121 + "usb2-phy0", "usb2-phy1", "usb2-phy2", 122 + }; 123 + 124 + static const char *meson_g12a_phy_names[] = { 125 + "usb2-phy0", "usb2-phy1", "usb3-phy0", 126 + }; 127 + 128 + /* 129 + * Amlogic A1 has a single physical PHY, in slot 1, but still has the 130 + * two U2 PHY controls register blocks like G12A. 131 + * Handling the first PHY on slot 1 would need a large amount of code 132 + * changes, and the current management is generic enough to handle it 133 + * correctly when only the "usb2-phy1" phy is specified on-par with the 134 + * DT bindings. 135 + */ 136 + static const char *meson_a1_phy_names[] = { 137 + "usb2-phy0", "usb2-phy1" 138 + }; 139 + 140 + struct dwc3_meson_g12a; 141 + 119 142 struct dwc3_meson_g12a_drvdata { 120 143 bool otg_switch_supported; 144 + bool otg_phy_host_port_disable; 121 145 struct clk_bulk_data *clks; 122 146 int num_clks; 147 + const char **phy_names; 148 + int num_phys; 149 + int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base); 150 + int (*usb2_init_phy)(struct dwc3_meson_g12a *priv, int i, 151 + enum phy_mode mode); 152 + int (*set_phy_mode)(struct dwc3_meson_g12a *priv, int i, 153 + enum phy_mode mode); 154 + int (*usb_init)(struct dwc3_meson_g12a *priv); 155 + int (*usb_post_init)(struct dwc3_meson_g12a *priv); 156 + }; 157 + 158 + static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv, 159 + void __iomem *base); 160 + static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv, 161 + void __iomem *base); 162 + 163 + static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i, 164 + enum phy_mode mode); 165 + static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i, 166 + enum phy_mode mode); 167 + 168 + static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv, 169 + int i, enum phy_mode mode); 170 + static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv, 171 + int i, enum phy_mode mode); 172 + 173 + static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv); 174 + static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv); 175 + 176 + static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv); 177 + 178 + /* 179 + * For GXL and GXM SoCs: 180 + * USB Phy muxing between the DWC2 Device controller and the DWC3 Host 181 + * controller is buggy when switching from Device to Host when USB port 182 + * is unpopulated, it causes the DWC3 to hard crash. 183 + * When populated (including OTG switching with ID pin), the switch works 184 + * like a charm like on the G12A platforms. 185 + * In order to still switch from Host to Device on an USB Type-A port, 186 + * an U2_PORT_DISABLE bit has been added to disconnect the DWC3 Host 187 + * controller from the port, but when used the DWC3 controller must be 188 + * reset to recover usage of the port. 189 + */ 190 + 191 + static struct dwc3_meson_g12a_drvdata gxl_drvdata = { 192 + .otg_switch_supported = true, 193 + .otg_phy_host_port_disable = true, 194 + .clks = meson_gxl_clocks, 195 + .num_clks = ARRAY_SIZE(meson_g12a_clocks), 196 + .phy_names = meson_a1_phy_names, 197 + .num_phys = ARRAY_SIZE(meson_a1_phy_names), 198 + .setup_regmaps = dwc3_meson_gxl_setup_regmaps, 199 + .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy, 200 + .set_phy_mode = dwc3_meson_gxl_set_phy_mode, 201 + .usb_init = dwc3_meson_gxl_usb_init, 202 + .usb_post_init = dwc3_meson_gxl_usb_post_init, 203 + }; 204 + 205 + static struct dwc3_meson_g12a_drvdata gxm_drvdata = { 206 + .otg_switch_supported = true, 207 + .otg_phy_host_port_disable = true, 208 + .clks = meson_gxl_clocks, 209 + .num_clks = ARRAY_SIZE(meson_g12a_clocks), 210 + .phy_names = meson_gxm_phy_names, 211 + .num_phys = ARRAY_SIZE(meson_gxm_phy_names), 212 + .setup_regmaps = dwc3_meson_gxl_setup_regmaps, 213 + .usb2_init_phy = dwc3_meson_gxl_usb2_init_phy, 214 + .set_phy_mode = dwc3_meson_gxl_set_phy_mode, 215 + .usb_init = dwc3_meson_gxl_usb_init, 216 + .usb_post_init = dwc3_meson_gxl_usb_post_init, 123 217 }; 124 218 125 219 static struct dwc3_meson_g12a_drvdata g12a_drvdata = { 126 220 .otg_switch_supported = true, 127 221 .clks = meson_g12a_clocks, 128 222 .num_clks = ARRAY_SIZE(meson_g12a_clocks), 223 + .phy_names = meson_g12a_phy_names, 224 + .num_phys = ARRAY_SIZE(meson_g12a_phy_names), 225 + .setup_regmaps = dwc3_meson_g12a_setup_regmaps, 226 + .usb2_init_phy = dwc3_meson_g12a_usb2_init_phy, 227 + .set_phy_mode = dwc3_meson_g12a_set_phy_mode, 228 + .usb_init = dwc3_meson_g12a_usb_init, 129 229 }; 130 230 131 231 static struct dwc3_meson_g12a_drvdata a1_drvdata = { 132 232 .otg_switch_supported = false, 133 233 .clks = meson_a1_clocks, 134 234 .num_clks = ARRAY_SIZE(meson_a1_clocks), 235 + .phy_names = meson_a1_phy_names, 236 + .num_phys = ARRAY_SIZE(meson_a1_phy_names), 237 + .setup_regmaps = dwc3_meson_g12a_setup_regmaps, 238 + .usb2_init_phy = dwc3_meson_g12a_usb2_init_phy, 239 + .set_phy_mode = dwc3_meson_g12a_set_phy_mode, 240 + .usb_init = dwc3_meson_g12a_usb_init, 135 241 }; 136 242 137 243 struct dwc3_meson_g12a { 138 244 struct device *dev; 139 - struct regmap *regmap; 245 + struct regmap *u2p_regmap[PHY_COUNT]; 246 + struct regmap *usb_glue_regmap; 140 247 struct reset_control *reset; 141 248 struct phy *phys[PHY_COUNT]; 142 249 enum usb_dr_mode otg_mode; ··· 255 150 const struct dwc3_meson_g12a_drvdata *drvdata; 256 151 }; 257 152 258 - static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv, 259 - int i, enum phy_mode mode) 153 + static int dwc3_meson_gxl_set_phy_mode(struct dwc3_meson_g12a *priv, 154 + int i, enum phy_mode mode) 155 + { 156 + return phy_set_mode(priv->phys[i], mode); 157 + } 158 + 159 + static int dwc3_meson_gxl_usb2_init_phy(struct dwc3_meson_g12a *priv, int i, 160 + enum phy_mode mode) 161 + { 162 + /* On GXL PHY must be started in device mode for DWC2 init */ 163 + return priv->drvdata->set_phy_mode(priv, i, 164 + (i == USB2_OTG_PHY) ? PHY_MODE_USB_DEVICE 165 + : PHY_MODE_USB_HOST); 166 + } 167 + 168 + static int dwc3_meson_g12a_set_phy_mode(struct dwc3_meson_g12a *priv, 169 + int i, enum phy_mode mode) 260 170 { 261 171 if (mode == PHY_MODE_USB_HOST) 262 - regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i), 172 + regmap_update_bits(priv->u2p_regmap[i], U2P_R0, 263 173 U2P_R0_HOST_DEVICE, 264 174 U2P_R0_HOST_DEVICE); 265 175 else 266 - regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i), 176 + regmap_update_bits(priv->u2p_regmap[i], U2P_R0, 267 177 U2P_R0_HOST_DEVICE, 0); 178 + 179 + return 0; 268 180 } 269 181 270 - static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv) 182 + static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i, 183 + enum phy_mode mode) 271 184 { 272 - int i; 185 + int ret; 273 186 274 - if (priv->otg_mode == USB_DR_MODE_PERIPHERAL) 275 - priv->otg_phy_mode = PHY_MODE_USB_DEVICE; 276 - else 277 - priv->otg_phy_mode = PHY_MODE_USB_HOST; 187 + regmap_update_bits(priv->u2p_regmap[i], U2P_R0, 188 + U2P_R0_POWER_ON_RESET, 189 + U2P_R0_POWER_ON_RESET); 278 190 279 - for (i = 0 ; i < USB3_HOST_PHY ; ++i) { 191 + if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) { 192 + regmap_update_bits(priv->u2p_regmap[i], U2P_R0, 193 + U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS, 194 + U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS); 195 + 196 + ret = priv->drvdata->set_phy_mode(priv, i, mode); 197 + } else 198 + ret = priv->drvdata->set_phy_mode(priv, i, 199 + PHY_MODE_USB_HOST); 200 + 201 + if (ret) 202 + return ret; 203 + 204 + regmap_update_bits(priv->u2p_regmap[i], U2P_R0, 205 + U2P_R0_POWER_ON_RESET, 0); 206 + 207 + return 0; 208 + } 209 + 210 + static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv, 211 + enum phy_mode mode) 212 + { 213 + int i, ret; 214 + 215 + for (i = 0; i < priv->drvdata->num_phys; ++i) { 280 216 if (!priv->phys[i]) 281 217 continue; 282 218 283 - regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i), 284 - U2P_R0_POWER_ON_RESET, 285 - U2P_R0_POWER_ON_RESET); 219 + if (!strstr(priv->drvdata->phy_names[i], "usb2")) 220 + continue; 286 221 287 - if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) { 288 - regmap_update_bits(priv->regmap, 289 - U2P_R0 + (U2P_REG_SIZE * i), 290 - U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS, 291 - U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS); 292 - 293 - dwc3_meson_g12a_usb2_set_mode(priv, i, 294 - priv->otg_phy_mode); 295 - } else 296 - dwc3_meson_g12a_usb2_set_mode(priv, i, 297 - PHY_MODE_USB_HOST); 298 - 299 - regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i), 300 - U2P_R0_POWER_ON_RESET, 0); 222 + ret = priv->drvdata->usb2_init_phy(priv, i, mode); 223 + if (ret) 224 + return ret; 301 225 } 302 226 303 227 return 0; ··· 334 200 335 201 static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv) 336 202 { 337 - regmap_update_bits(priv->regmap, USB_R3, 203 + regmap_update_bits(priv->usb_glue_regmap, USB_R3, 338 204 USB_R3_P30_SSC_RANGE_MASK | 339 205 USB_R3_P30_REF_SSP_EN, 340 206 USB_R3_P30_SSC_ENABLE | ··· 342 208 USB_R3_P30_REF_SSP_EN); 343 209 udelay(2); 344 210 345 - regmap_update_bits(priv->regmap, USB_R2, 211 + regmap_update_bits(priv->usb_glue_regmap, USB_R2, 346 212 USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 347 213 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15)); 348 214 349 - regmap_update_bits(priv->regmap, USB_R2, 215 + regmap_update_bits(priv->usb_glue_regmap, USB_R2, 350 216 USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 351 217 FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20)); 352 218 353 219 udelay(2); 354 220 355 - regmap_update_bits(priv->regmap, USB_R1, 221 + regmap_update_bits(priv->usb_glue_regmap, USB_R1, 356 222 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT, 357 223 USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT); 358 224 359 - regmap_update_bits(priv->regmap, USB_R1, 225 + regmap_update_bits(priv->usb_glue_regmap, USB_R1, 360 226 USB_R1_P30_PCS_TX_SWING_FULL_MASK, 361 227 FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127)); 362 228 } 363 229 364 - static void dwc3_meson_g12a_usb_otg_apply_mode(struct dwc3_meson_g12a *priv) 230 + static void dwc3_meson_g12a_usb_otg_apply_mode(struct dwc3_meson_g12a *priv, 231 + enum phy_mode mode) 365 232 { 366 - if (priv->otg_phy_mode == PHY_MODE_USB_DEVICE) { 367 - regmap_update_bits(priv->regmap, USB_R0, 233 + if (mode == PHY_MODE_USB_DEVICE) { 234 + if (priv->otg_mode != USB_DR_MODE_OTG && 235 + priv->drvdata->otg_phy_host_port_disable) 236 + /* Isolate the OTG PHY port from the Host Controller */ 237 + regmap_update_bits(priv->usb_glue_regmap, USB_R1, 238 + USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK, 239 + FIELD_PREP(USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK, 240 + BIT(USB2_OTG_PHY))); 241 + 242 + regmap_update_bits(priv->usb_glue_regmap, USB_R0, 368 243 USB_R0_U2D_ACT, USB_R0_U2D_ACT); 369 - regmap_update_bits(priv->regmap, USB_R0, 244 + regmap_update_bits(priv->usb_glue_regmap, USB_R0, 370 245 USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0); 371 - regmap_update_bits(priv->regmap, USB_R4, 246 + regmap_update_bits(priv->usb_glue_regmap, USB_R4, 372 247 USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0); 373 248 } else { 374 - regmap_update_bits(priv->regmap, USB_R0, 249 + if (priv->otg_mode != USB_DR_MODE_OTG && 250 + priv->drvdata->otg_phy_host_port_disable) { 251 + regmap_update_bits(priv->usb_glue_regmap, USB_R1, 252 + USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK, 0); 253 + msleep(500); 254 + } 255 + regmap_update_bits(priv->usb_glue_regmap, USB_R0, 375 256 USB_R0_U2D_ACT, 0); 376 - regmap_update_bits(priv->regmap, USB_R4, 257 + regmap_update_bits(priv->usb_glue_regmap, USB_R4, 377 258 USB_R4_P21_SLEEP_M0, 0); 378 259 } 379 260 } 380 261 381 - static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv) 262 + static int dwc3_meson_g12a_usb_init_glue(struct dwc3_meson_g12a *priv, 263 + enum phy_mode mode) 382 264 { 383 265 int ret; 384 266 385 - ret = dwc3_meson_g12a_usb2_init(priv); 267 + ret = dwc3_meson_g12a_usb2_init(priv, mode); 386 268 if (ret) 387 269 return ret; 388 270 389 - regmap_update_bits(priv->regmap, USB_R1, 271 + regmap_update_bits(priv->usb_glue_regmap, USB_R1, 390 272 USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 391 273 FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20)); 392 274 393 - regmap_update_bits(priv->regmap, USB_R5, 275 + regmap_update_bits(priv->usb_glue_regmap, USB_R5, 394 276 USB_R5_ID_DIG_EN_0, 395 277 USB_R5_ID_DIG_EN_0); 396 - regmap_update_bits(priv->regmap, USB_R5, 278 + regmap_update_bits(priv->usb_glue_regmap, USB_R5, 397 279 USB_R5_ID_DIG_EN_1, 398 280 USB_R5_ID_DIG_EN_1); 399 - regmap_update_bits(priv->regmap, USB_R5, 281 + regmap_update_bits(priv->usb_glue_regmap, USB_R5, 400 282 USB_R5_ID_DIG_TH_MASK, 401 283 FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff)); 402 284 ··· 420 270 if (priv->usb3_ports) 421 271 dwc3_meson_g12a_usb3_init(priv); 422 272 423 - dwc3_meson_g12a_usb_otg_apply_mode(priv); 273 + dwc3_meson_g12a_usb_otg_apply_mode(priv, mode); 424 274 425 275 return 0; 426 276 } 427 277 428 - static const struct regmap_config phy_meson_g12a_usb3_regmap_conf = { 278 + static const struct regmap_config phy_meson_g12a_usb_glue_regmap_conf = { 279 + .name = "usb-glue", 429 280 .reg_bits = 8, 430 281 .val_bits = 32, 431 282 .reg_stride = 4, ··· 435 284 436 285 static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv) 437 286 { 287 + const char *phy_name; 438 288 int i; 439 289 440 - for (i = 0 ; i < PHY_COUNT ; ++i) { 441 - priv->phys[i] = devm_phy_optional_get(priv->dev, phy_names[i]); 290 + for (i = 0 ; i < priv->drvdata->num_phys ; ++i) { 291 + phy_name = priv->drvdata->phy_names[i]; 292 + priv->phys[i] = devm_phy_optional_get(priv->dev, phy_name); 442 293 if (!priv->phys[i]) 443 294 continue; 444 295 445 296 if (IS_ERR(priv->phys[i])) 446 297 return PTR_ERR(priv->phys[i]); 447 298 448 - if (i == USB3_HOST_PHY) 299 + if (strstr(phy_name, "usb3")) 449 300 priv->usb3_ports++; 450 301 else 451 302 priv->usb2_ports++; ··· 463 310 { 464 311 u32 reg; 465 312 466 - regmap_read(priv->regmap, USB_R5, &reg); 313 + regmap_read(priv->usb_glue_regmap, USB_R5, &reg); 467 314 468 315 if (reg & (USB_R5_ID_DIG_SYNC | USB_R5_ID_DIG_REG)) 469 316 return PHY_MODE_USB_DEVICE; ··· 495 342 496 343 priv->otg_phy_mode = mode; 497 344 498 - dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode); 345 + ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, mode); 346 + if (ret) 347 + return ret; 499 348 500 - dwc3_meson_g12a_usb_otg_apply_mode(priv); 349 + dwc3_meson_g12a_usb_otg_apply_mode(priv, mode); 501 350 502 351 return 0; 503 352 } ··· 518 363 519 364 if (mode == priv->otg_phy_mode) 520 365 return 0; 366 + 367 + if (priv->drvdata->otg_phy_host_port_disable) 368 + dev_warn_once(priv->dev, "Manual OTG switch is broken on this "\ 369 + "SoC, when manual switching from "\ 370 + "Host to device, DWC3 controller "\ 371 + "will need to be resetted in order "\ 372 + "to recover usage of the Host port"); 521 373 522 374 return dwc3_meson_g12a_otg_mode_set(priv, mode); 523 375 } ··· 548 386 dev_warn(priv->dev, "Failed to switch OTG mode\n"); 549 387 } 550 388 551 - regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_IRQ, 0); 389 + regmap_update_bits(priv->usb_glue_regmap, USB_R5, 390 + USB_R5_ID_DIG_IRQ, 0); 552 391 553 392 return IRQ_HANDLED; 554 393 } ··· 584 421 585 422 if (priv->otg_mode == USB_DR_MODE_OTG) { 586 423 /* Ack irq before registering */ 587 - regmap_update_bits(priv->regmap, USB_R5, 424 + regmap_update_bits(priv->usb_glue_regmap, USB_R5, 588 425 USB_R5_ID_DIG_IRQ, 0); 589 426 590 427 irq = platform_get_irq(pdev, 0); ··· 620 457 return 0; 621 458 } 622 459 460 + static int dwc3_meson_gxl_setup_regmaps(struct dwc3_meson_g12a *priv, 461 + void __iomem *base) 462 + { 463 + /* GXL controls the PHY mode in the PHY registers unlike G12A */ 464 + priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, base, 465 + &phy_meson_g12a_usb_glue_regmap_conf); 466 + if (IS_ERR(priv->usb_glue_regmap)) 467 + return PTR_ERR(priv->usb_glue_regmap); 468 + 469 + return 0; 470 + } 471 + 472 + static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv, 473 + void __iomem *base) 474 + { 475 + int i; 476 + 477 + priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev, 478 + base + G12A_GLUE_OFFSET, 479 + &phy_meson_g12a_usb_glue_regmap_conf); 480 + if (IS_ERR(priv->usb_glue_regmap)) 481 + return PTR_ERR(priv->usb_glue_regmap); 482 + 483 + /* Create a regmap for each USB2 PHY control register set */ 484 + for (i = 0; i < priv->usb2_ports; i++) { 485 + struct regmap_config u2p_regmap_config = { 486 + .reg_bits = 8, 487 + .val_bits = 32, 488 + .reg_stride = 4, 489 + .max_register = U2P_R1, 490 + }; 491 + 492 + u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL, 493 + "u2p-%d", i); 494 + if (!u2p_regmap_config.name) 495 + return -ENOMEM; 496 + 497 + priv->u2p_regmap[i] = devm_regmap_init_mmio(priv->dev, 498 + base + (i * U2P_REG_SIZE), 499 + &u2p_regmap_config); 500 + if (IS_ERR(priv->u2p_regmap[i])) 501 + return PTR_ERR(priv->u2p_regmap[i]); 502 + } 503 + 504 + return 0; 505 + } 506 + 507 + static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv) 508 + { 509 + return dwc3_meson_g12a_usb_init_glue(priv, priv->otg_phy_mode); 510 + } 511 + 512 + static int dwc3_meson_gxl_usb_init(struct dwc3_meson_g12a *priv) 513 + { 514 + return dwc3_meson_g12a_usb_init_glue(priv, PHY_MODE_USB_DEVICE); 515 + } 516 + 517 + static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv) 518 + { 519 + int ret; 520 + 521 + ret = priv->drvdata->set_phy_mode(priv, USB2_OTG_PHY, 522 + priv->otg_phy_mode); 523 + if (ret) 524 + return ret; 525 + 526 + dwc3_meson_g12a_usb_otg_apply_mode(priv, priv->otg_phy_mode); 527 + 528 + return 0; 529 + } 530 + 623 531 static int dwc3_meson_g12a_probe(struct platform_device *pdev) 624 532 { 625 533 struct dwc3_meson_g12a *priv; ··· 707 473 if (IS_ERR(base)) 708 474 return PTR_ERR(base); 709 475 710 - priv->regmap = devm_regmap_init_mmio(dev, base, 711 - &phy_meson_g12a_usb3_regmap_conf); 712 - if (IS_ERR(priv->regmap)) 713 - return PTR_ERR(priv->regmap); 476 + priv->drvdata = of_device_get_match_data(&pdev->dev); 477 + priv->dev = dev; 714 478 715 479 priv->vbus = devm_regulator_get_optional(dev, "vbus"); 716 480 if (IS_ERR(priv->vbus)) { ··· 716 484 return PTR_ERR(priv->vbus); 717 485 priv->vbus = NULL; 718 486 } 719 - 720 - priv->drvdata = of_device_get_match_data(&pdev->dev); 721 487 722 488 ret = devm_clk_bulk_get(dev, 723 489 priv->drvdata->num_clks, ··· 729 499 return ret; 730 500 731 501 platform_set_drvdata(pdev, priv); 732 - priv->dev = dev; 733 502 734 - priv->reset = devm_reset_control_get(dev, NULL); 503 + priv->reset = devm_reset_control_get_shared(dev, NULL); 735 504 if (IS_ERR(priv->reset)) { 736 505 ret = PTR_ERR(priv->reset); 737 506 dev_err(dev, "failed to get device reset, err=%d\n", ret); 738 - return ret; 507 + goto err_disable_clks; 739 508 } 740 509 741 510 ret = reset_control_reset(priv->reset); ··· 745 516 if (ret) 746 517 goto err_disable_clks; 747 518 519 + ret = priv->drvdata->setup_regmaps(priv, base); 520 + if (ret) 521 + return ret; 522 + 748 523 if (priv->vbus) { 749 524 ret = regulator_enable(priv->vbus); 750 525 if (ret) ··· 758 525 /* Get dr_mode */ 759 526 priv->otg_mode = usb_get_dr_mode(dev); 760 527 761 - dwc3_meson_g12a_usb_init(priv); 528 + if (priv->otg_mode == USB_DR_MODE_PERIPHERAL) 529 + priv->otg_phy_mode = PHY_MODE_USB_DEVICE; 530 + else 531 + priv->otg_phy_mode = PHY_MODE_USB_HOST; 532 + 533 + ret = priv->drvdata->usb_init(priv); 534 + if (ret) 535 + goto err_disable_clks; 762 536 763 537 /* Init PHYs */ 764 538 for (i = 0 ; i < PHY_COUNT ; ++i) { ··· 779 539 ret = phy_power_on(priv->phys[i]); 780 540 if (ret) 781 541 goto err_phys_exit; 542 + } 543 + 544 + if (priv->drvdata->usb_post_init) { 545 + ret = priv->drvdata->usb_post_init(priv); 546 + if (ret) 547 + goto err_phys_power; 782 548 } 783 549 784 550 ret = of_platform_populate(np, NULL, NULL, dev); ··· 888 642 889 643 reset_control_deassert(priv->reset); 890 644 891 - dwc3_meson_g12a_usb_init(priv); 645 + ret = priv->drvdata->usb_init(priv); 646 + if (ret) 647 + return ret; 892 648 893 649 /* Init PHYs */ 894 650 for (i = 0 ; i < PHY_COUNT ; ++i) { ··· 922 674 }; 923 675 924 676 static const struct of_device_id dwc3_meson_g12a_match[] = { 677 + { 678 + .compatible = "amlogic,meson-gxl-usb-ctrl", 679 + .data = &gxl_drvdata, 680 + }, 681 + { 682 + .compatible = "amlogic,meson-gxm-usb-ctrl", 683 + .data = &gxm_drvdata, 684 + }, 925 685 { 926 686 .compatible = "amlogic,meson-g12a-usb-ctrl", 927 687 .data = &g12a_drvdata,
+6 -24
drivers/usb/dwc3/dwc3-of-simple.c
··· 27 27 struct clk_bulk_data *clks; 28 28 int num_clocks; 29 29 struct reset_control *resets; 30 - bool pulse_resets; 31 30 bool need_reset; 32 31 }; 33 32 ··· 37 38 struct device_node *np = dev->of_node; 38 39 39 40 int ret; 40 - bool shared_resets = false; 41 41 42 42 simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL); 43 43 if (!simple) ··· 52 54 if (of_device_is_compatible(np, "rockchip,rk3399-dwc3")) 53 55 simple->need_reset = true; 54 56 55 - if (of_device_is_compatible(np, "amlogic,meson-axg-dwc3") || 56 - of_device_is_compatible(np, "amlogic,meson-gxl-dwc3")) { 57 - shared_resets = true; 58 - simple->pulse_resets = true; 59 - } 60 - 61 - simple->resets = of_reset_control_array_get(np, shared_resets, true, 57 + simple->resets = of_reset_control_array_get(np, false, true, 62 58 true); 63 59 if (IS_ERR(simple->resets)) { 64 60 ret = PTR_ERR(simple->resets); ··· 60 68 return ret; 61 69 } 62 70 63 - if (simple->pulse_resets) { 64 - ret = reset_control_reset(simple->resets); 65 - if (ret) 66 - goto err_resetc_put; 67 - } else { 68 - ret = reset_control_deassert(simple->resets); 69 - if (ret) 70 - goto err_resetc_put; 71 - } 71 + ret = reset_control_deassert(simple->resets); 72 + if (ret) 73 + goto err_resetc_put; 72 74 73 75 ret = clk_bulk_get_all(simple->dev, &simple->clks); 74 76 if (ret < 0) ··· 88 102 clk_bulk_put_all(simple->num_clocks, simple->clks); 89 103 90 104 err_resetc_assert: 91 - if (!simple->pulse_resets) 92 - reset_control_assert(simple->resets); 105 + reset_control_assert(simple->resets); 93 106 94 107 err_resetc_put: 95 108 reset_control_put(simple->resets); ··· 103 118 clk_bulk_put_all(simple->num_clocks, simple->clks); 104 119 simple->num_clocks = 0; 105 120 106 - if (!simple->pulse_resets) 107 - reset_control_assert(simple->resets); 121 + reset_control_assert(simple->resets); 108 122 109 123 reset_control_put(simple->resets); 110 124 ··· 175 191 { .compatible = "xlnx,zynqmp-dwc3" }, 176 192 { .compatible = "cavium,octeon-7130-usb-uctl" }, 177 193 { .compatible = "sprd,sc9860-dwc3" }, 178 - { .compatible = "amlogic,meson-axg-dwc3" }, 179 - { .compatible = "amlogic,meson-gxl-dwc3" }, 180 194 { .compatible = "allwinner,sun50i-h6-dwc3" }, 181 195 { /* Sentinel */ } 182 196 };
+364 -109
drivers/usb/dwc3/gadget.c
··· 95 95 * Wait until device controller is ready. Only applies to 1.94a and 96 96 * later RTL. 97 97 */ 98 - if (dwc->revision >= DWC3_REVISION_194A) { 98 + if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) { 99 99 while (--retries) { 100 100 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 101 101 if (reg & DWC3_DSTS_DCNRD) ··· 122 122 * The following code is racy when called from dwc3_gadget_wakeup, 123 123 * and is not needed, at least on newer versions 124 124 */ 125 - if (dwc->revision >= DWC3_REVISION_194A) 125 + if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) 126 126 return 0; 127 127 128 128 /* wait for a change in DSTS */ ··· 273 273 { 274 274 const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; 275 275 struct dwc3 *dwc = dep->dwc; 276 - u32 timeout = 1000; 276 + u32 timeout = 5000; 277 277 u32 saved_config = 0; 278 278 u32 reg; 279 279 ··· 356 356 ret = 0; 357 357 break; 358 358 case DEPEVT_TRANSFER_NO_RESOURCE: 359 + dev_WARN(dwc->dev, "No resource for %s\n", 360 + dep->name); 359 361 ret = -EINVAL; 360 362 break; 361 363 case DEPEVT_TRANSFER_BUS_EXPIRY: ··· 389 387 390 388 trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status); 391 389 392 - if (ret == 0 && DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { 393 - dep->flags |= DWC3_EP_TRANSFER_STARTED; 394 - dwc3_gadget_ep_get_transfer_index(dep); 390 + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { 391 + if (ret == 0) 392 + dep->flags |= DWC3_EP_TRANSFER_STARTED; 393 + 394 + if (ret != -ETIMEDOUT) 395 + dwc3_gadget_ep_get_transfer_index(dep); 395 396 } 396 397 397 398 if (saved_config) { ··· 420 415 * IN transfers due to a mishandled error condition. Synopsys 421 416 * STAR 9000614252. 422 417 */ 423 - if (dep->direction && (dwc->revision >= DWC3_REVISION_260A) && 418 + if (dep->direction && 419 + !DWC3_VER_IS_PRIOR(DWC3, 260A) && 424 420 (dwc->gadget.speed >= USB_SPEED_SUPER)) 425 421 cmd |= DWC3_DEPCMD_CLEARPENDIN; 426 422 ··· 579 573 580 574 if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) { 581 575 params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE 576 + | DWC3_DEPCFG_XFER_COMPLETE_EN 582 577 | DWC3_DEPCFG_STREAM_EVENT_EN; 583 578 dep->stream_capable = true; 584 579 } ··· 609 602 610 603 return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, &params); 611 604 } 605 + 606 + static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, 607 + bool interrupt); 612 608 613 609 /** 614 610 * __dwc3_gadget_ep_enable - initializes a hw endpoint ··· 673 663 * Issue StartTransfer here with no-op TRB so we can always rely on No 674 664 * Response Update Transfer command. 675 665 */ 676 - if ((usb_endpoint_xfer_bulk(desc) && !dep->stream_capable) || 666 + if (usb_endpoint_xfer_bulk(desc) || 677 667 usb_endpoint_xfer_int(desc)) { 678 668 struct dwc3_gadget_ep_cmd_params params; 679 669 struct dwc3_trb *trb; ··· 692 682 ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params); 693 683 if (ret < 0) 694 684 return ret; 685 + 686 + if (dep->stream_capable) { 687 + /* 688 + * For streams, at start, there maybe a race where the 689 + * host primes the endpoint before the function driver 690 + * queues a request to initiate a stream. In that case, 691 + * the controller will not see the prime to generate the 692 + * ERDY and start stream. To workaround this, issue a 693 + * no-op TRB as normal, but end it immediately. As a 694 + * result, when the function driver queues the request, 695 + * the next START_TRANSFER command will cause the 696 + * controller to generate an ERDY to initiate the 697 + * stream. 698 + */ 699 + dwc3_stop_active_transfer(dep, true, true); 700 + 701 + /* 702 + * All stream eps will reinitiate stream on NoStream 703 + * rejection until we can determine that the host can 704 + * prime after the first transfer. 705 + */ 706 + dep->flags |= DWC3_EP_FORCE_RESTART_STREAM; 707 + } 695 708 } 696 709 697 710 out: ··· 723 690 return 0; 724 691 } 725 692 726 - static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, 727 - bool interrupt); 728 693 static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) 729 694 { 730 695 struct dwc3_request *req; ··· 943 912 944 913 static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, 945 914 dma_addr_t dma, unsigned length, unsigned chain, unsigned node, 946 - unsigned stream_id, unsigned short_not_ok, unsigned no_interrupt) 915 + unsigned stream_id, unsigned short_not_ok, 916 + unsigned no_interrupt, unsigned is_last) 947 917 { 948 918 struct dwc3 *dwc = dep->dwc; 949 919 struct usb_gadget *gadget = &dwc->gadget; ··· 1037 1005 1038 1006 if (chain) 1039 1007 trb->ctrl |= DWC3_TRB_CTRL_CHN; 1008 + else if (dep->stream_capable && is_last) 1009 + trb->ctrl |= DWC3_TRB_CTRL_LST; 1040 1010 1041 1011 if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) 1042 1012 trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id); ··· 1066 1032 unsigned stream_id = req->request.stream_id; 1067 1033 unsigned short_not_ok = req->request.short_not_ok; 1068 1034 unsigned no_interrupt = req->request.no_interrupt; 1035 + unsigned is_last = req->request.is_last; 1069 1036 1070 1037 if (req->request.num_sgs > 0) { 1071 1038 length = sg_dma_len(req->start_sg); ··· 1087 1052 req->num_trbs++; 1088 1053 1089 1054 __dwc3_prepare_one_trb(dep, trb, dma, length, chain, node, 1090 - stream_id, short_not_ok, no_interrupt); 1055 + stream_id, short_not_ok, no_interrupt, is_last); 1091 1056 } 1092 1057 1093 1058 static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, ··· 1132 1097 maxp - rem, false, 1, 1133 1098 req->request.stream_id, 1134 1099 req->request.short_not_ok, 1135 - req->request.no_interrupt); 1100 + req->request.no_interrupt, 1101 + req->request.is_last); 1136 1102 } else { 1137 1103 dwc3_prepare_one_trb(dep, req, chain, i); 1138 1104 } ··· 1177 1141 __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem, 1178 1142 false, 1, req->request.stream_id, 1179 1143 req->request.short_not_ok, 1180 - req->request.no_interrupt); 1144 + req->request.no_interrupt, 1145 + req->request.is_last); 1181 1146 } else if (req->request.zero && req->request.length && 1182 1147 (IS_ALIGNED(req->request.length, maxp))) { 1183 1148 struct dwc3 *dwc = dep->dwc; ··· 1195 1158 __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, 1196 1159 false, 1, req->request.stream_id, 1197 1160 req->request.short_not_ok, 1198 - req->request.no_interrupt); 1161 + req->request.no_interrupt, 1162 + req->request.is_last); 1199 1163 } else { 1200 1164 dwc3_prepare_one_trb(dep, req, false, 0); 1201 1165 } ··· 1232 1194 1233 1195 if (!dwc3_calc_trbs_left(dep)) 1234 1196 return; 1197 + 1198 + /* 1199 + * Don't prepare beyond a transfer. In DWC_usb32, its transfer 1200 + * burst capability may try to read and use TRBs beyond the 1201 + * active transfer instead of stopping. 1202 + */ 1203 + if (dep->stream_capable && req->request.is_last) 1204 + return; 1235 1205 } 1236 1206 1237 1207 list_for_each_entry_safe(req, n, &dep->pending_list, list) { ··· 1263 1217 1264 1218 if (!dwc3_calc_trbs_left(dep)) 1265 1219 return; 1220 + 1221 + /* 1222 + * Don't prepare beyond a transfer. In DWC_usb32, its transfer 1223 + * burst capability may try to read and use TRBs beyond the 1224 + * active transfer instead of stopping. 1225 + */ 1226 + if (dep->stream_capable && req->request.is_last) 1227 + return; 1266 1228 } 1267 1229 } 1230 + 1231 + static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); 1268 1232 1269 1233 static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) 1270 1234 { ··· 1315 1259 1316 1260 ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params); 1317 1261 if (ret < 0) { 1318 - /* 1319 - * FIXME we need to iterate over the list of requests 1320 - * here and stop, unmap, free and del each of the linked 1321 - * requests instead of what we do now. 1322 - */ 1323 - if (req->trb) 1324 - memset(req->trb, 0, sizeof(struct dwc3_trb)); 1325 - dwc3_gadget_del_and_unmap_request(dep, req, ret); 1262 + struct dwc3_request *tmp; 1263 + 1264 + if (ret == -EAGAIN) 1265 + return ret; 1266 + 1267 + dwc3_stop_active_transfer(dep, true, true); 1268 + 1269 + list_for_each_entry_safe(req, tmp, &dep->started_list, list) 1270 + dwc3_gadget_move_cancelled_request(req); 1271 + 1272 + /* If ep isn't started, then there's no end transfer pending */ 1273 + if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) 1274 + dwc3_gadget_ep_cleanup_cancelled_requests(dep); 1275 + 1326 1276 return ret; 1327 1277 } 1278 + 1279 + if (dep->stream_capable && req->request.is_last) 1280 + dep->flags |= DWC3_EP_WAIT_TRANSFER_COMPLETE; 1328 1281 1329 1282 return 0; 1330 1283 } ··· 1467 1402 int ret; 1468 1403 int i; 1469 1404 1470 - if (list_empty(&dep->pending_list)) { 1405 + if (list_empty(&dep->pending_list) && 1406 + list_empty(&dep->started_list)) { 1471 1407 dep->flags |= DWC3_EP_PENDING_REQUEST; 1472 1408 return -EAGAIN; 1473 1409 } 1474 1410 1475 - if (!dwc->dis_start_transfer_quirk && dwc3_is_usb31(dwc) && 1476 - (dwc->revision <= DWC3_USB31_REVISION_160A || 1477 - (dwc->revision == DWC3_USB31_REVISION_170A && 1478 - dwc->version_type >= DWC31_VERSIONTYPE_EA01 && 1479 - dwc->version_type <= DWC31_VERSIONTYPE_EA06))) { 1480 - 1411 + if (!dwc->dis_start_transfer_quirk && 1412 + (DWC3_VER_IS_PRIOR(DWC31, 170A) || 1413 + DWC3_VER_TYPE_IS_WITHIN(DWC31, 170A, EA01, EA06))) { 1481 1414 if (dwc->gadget.speed <= USB_SPEED_HIGH && dep->direction) 1482 1415 return dwc3_gadget_start_isoc_quirk(dep); 1483 1416 } ··· 1486 1423 ret = __dwc3_gadget_kick_transfer(dep); 1487 1424 if (ret != -EAGAIN) 1488 1425 break; 1426 + } 1427 + 1428 + /* 1429 + * After a number of unsuccessful start attempts due to bus-expiry 1430 + * status, issue END_TRANSFER command and retry on the next XferNotReady 1431 + * event. 1432 + */ 1433 + if (ret == -EAGAIN) { 1434 + struct dwc3_gadget_ep_cmd_params params; 1435 + u32 cmd; 1436 + 1437 + cmd = DWC3_DEPCMD_ENDTRANSFER | 1438 + DWC3_DEPCMD_CMDIOC | 1439 + DWC3_DEPCMD_PARAM(dep->resource_index); 1440 + 1441 + dep->resource_index = 0; 1442 + memset(&params, 0, sizeof(params)); 1443 + 1444 + ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params); 1445 + if (!ret) 1446 + dep->flags |= DWC3_EP_END_TRANSFER_PENDING; 1489 1447 } 1490 1448 1491 1449 return ret; ··· 1540 1456 1541 1457 list_add_tail(&req->list, &dep->pending_list); 1542 1458 req->status = DWC3_REQUEST_STATUS_QUEUED; 1459 + 1460 + if (dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE) 1461 + return 0; 1543 1462 1544 1463 /* Start the transfer only after the END_TRANSFER is completed */ 1545 1464 if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) { ··· 1595 1508 { 1596 1509 int i; 1597 1510 1511 + /* If req->trb is not set, then the request has not started */ 1512 + if (!req->trb) 1513 + return; 1514 + 1598 1515 /* 1599 1516 * If request was already started, this means we had to 1600 1517 * stop the transfer. With that we also need to ignore ··· 1647 1556 1648 1557 spin_lock_irqsave(&dwc->lock, flags); 1649 1558 1650 - list_for_each_entry(r, &dep->pending_list, list) { 1559 + list_for_each_entry(r, &dep->cancelled_list, list) { 1651 1560 if (r == req) 1652 - break; 1561 + goto out; 1653 1562 } 1654 1563 1655 - if (r != req) { 1656 - list_for_each_entry(r, &dep->started_list, list) { 1657 - if (r == req) 1658 - break; 1659 - } 1564 + list_for_each_entry(r, &dep->pending_list, list) { 1660 1565 if (r == req) { 1566 + dwc3_gadget_giveback(dep, req, -ECONNRESET); 1567 + goto out; 1568 + } 1569 + } 1570 + 1571 + list_for_each_entry(r, &dep->started_list, list) { 1572 + if (r == req) { 1573 + struct dwc3_request *t; 1574 + 1661 1575 /* wait until it is processed */ 1662 1576 dwc3_stop_active_transfer(dep, true, true); 1663 1577 1664 - if (!r->trb) 1665 - goto out0; 1578 + /* 1579 + * Remove any started request if the transfer is 1580 + * cancelled. 1581 + */ 1582 + list_for_each_entry_safe(r, t, &dep->started_list, list) 1583 + dwc3_gadget_move_cancelled_request(r); 1666 1584 1667 - dwc3_gadget_move_cancelled_request(req); 1668 - if (dep->flags & DWC3_EP_TRANSFER_STARTED) 1669 - goto out0; 1670 - else 1671 - goto out1; 1585 + goto out; 1672 1586 } 1673 - dev_err(dwc->dev, "request %pK was not queued to %s\n", 1674 - request, ep->name); 1675 - ret = -EINVAL; 1676 - goto out0; 1677 1587 } 1678 1588 1679 - out1: 1680 - dwc3_gadget_giveback(dep, req, -ECONNRESET); 1681 - 1682 - out0: 1589 + dev_err(dwc->dev, "request %pK was not queued to %s\n", 1590 + request, ep->name); 1591 + ret = -EINVAL; 1592 + out: 1683 1593 spin_unlock_irqrestore(&dwc->lock, flags); 1684 1594 1685 1595 return ret; ··· 1690 1598 { 1691 1599 struct dwc3_gadget_ep_cmd_params params; 1692 1600 struct dwc3 *dwc = dep->dwc; 1601 + struct dwc3_request *req; 1602 + struct dwc3_request *tmp; 1693 1603 int ret; 1694 1604 1695 1605 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { ··· 1728 1634 else 1729 1635 dep->flags |= DWC3_EP_STALL; 1730 1636 } else { 1637 + /* 1638 + * Don't issue CLEAR_STALL command to control endpoints. The 1639 + * controller automatically clears the STALL when it receives 1640 + * the SETUP token. 1641 + */ 1642 + if (dep->number <= 1) { 1643 + dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); 1644 + return 0; 1645 + } 1731 1646 1732 1647 ret = dwc3_send_clear_stall_ep_cmd(dep); 1733 - if (ret) 1648 + if (ret) { 1734 1649 dev_err(dwc->dev, "failed to clear STALL on %s\n", 1735 1650 dep->name); 1736 - else 1737 - dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); 1651 + return ret; 1652 + } 1653 + 1654 + dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); 1655 + 1656 + dwc3_stop_active_transfer(dep, true, true); 1657 + 1658 + list_for_each_entry_safe(req, tmp, &dep->started_list, list) 1659 + dwc3_gadget_move_cancelled_request(req); 1660 + 1661 + list_for_each_entry_safe(req, tmp, &dep->pending_list, list) 1662 + dwc3_gadget_move_cancelled_request(req); 1663 + 1664 + if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) { 1665 + dep->flags &= ~DWC3_EP_DELAY_START; 1666 + dwc3_gadget_ep_cleanup_cancelled_requests(dep); 1667 + } 1738 1668 } 1739 1669 1740 1670 return ret; ··· 1874 1756 } 1875 1757 1876 1758 /* Recent versions do this automatically */ 1877 - if (dwc->revision < DWC3_REVISION_194A) { 1759 + if (DWC3_VER_IS_PRIOR(DWC3, 194A)) { 1878 1760 /* write zeroes to Link Change Request */ 1879 1761 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 1880 1762 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; ··· 1936 1818 1937 1819 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 1938 1820 if (is_on) { 1939 - if (dwc->revision <= DWC3_REVISION_187A) { 1821 + if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) { 1940 1822 reg &= ~DWC3_DCTL_TRGTULST_MASK; 1941 1823 reg |= DWC3_DCTL_TRGTULST_RX_DET; 1942 1824 } 1943 1825 1944 - if (dwc->revision >= DWC3_REVISION_194A) 1826 + if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) 1945 1827 reg &= ~DWC3_DCTL_KEEP_CONNECT; 1946 1828 reg |= DWC3_DCTL_RUN_STOP; 1947 1829 ··· 2015 1897 DWC3_DEVTEN_USBRSTEN | 2016 1898 DWC3_DEVTEN_DISCONNEVTEN); 2017 1899 2018 - if (dwc->revision < DWC3_REVISION_250A) 1900 + if (DWC3_VER_IS_PRIOR(DWC3, 250A)) 2019 1901 reg |= DWC3_DEVTEN_ULSTCNGEN; 2020 1902 2021 1903 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); ··· 2060 1942 2061 1943 ram2_depth = DWC3_GHWPARAMS7_RAM2_DEPTH(dwc->hwparams.hwparams7); 2062 1944 mdwidth = DWC3_GHWPARAMS0_MDWIDTH(dwc->hwparams.hwparams0); 1945 + if (DWC3_IP_IS(DWC32)) 1946 + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 2063 1947 2064 1948 nump = ((ram2_depth * mdwidth / 8) - 24 - 16) / 1024; 2065 1949 nump = min_t(u32, nump, 16); ··· 2098 1978 * bursts of data without going through any sort of endpoint throttling. 2099 1979 */ 2100 1980 reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); 2101 - if (dwc3_is_usb31(dwc)) 2102 - reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL; 2103 - else 1981 + if (DWC3_IP_IS(DWC3)) 2104 1982 reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL; 1983 + else 1984 + reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL; 2105 1985 2106 1986 dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); 2107 1987 ··· 2274 2154 * STAR#9000525659: Clock Domain Crossing on DCTL in 2275 2155 * USB 2.0 Mode 2276 2156 */ 2277 - if (dwc->revision < DWC3_REVISION_220A && 2157 + if (DWC3_VER_IS_PRIOR(DWC3, 220A) && 2278 2158 !dwc->dis_metastability_quirk) { 2279 2159 reg |= DWC3_DCFG_SUPERSPEED; 2280 2160 } else { ··· 2292 2172 reg |= DWC3_DCFG_SUPERSPEED; 2293 2173 break; 2294 2174 case USB_SPEED_SUPER_PLUS: 2295 - if (dwc3_is_usb31(dwc)) 2296 - reg |= DWC3_DCFG_SUPERSPEED_PLUS; 2297 - else 2175 + if (DWC3_IP_IS(DWC3)) 2298 2176 reg |= DWC3_DCFG_SUPERSPEED; 2177 + else 2178 + reg |= DWC3_DCFG_SUPERSPEED_PLUS; 2299 2179 break; 2300 2180 default: 2301 2181 dev_err(dwc->dev, "invalid speed (%d)\n", speed); 2302 2182 2303 - if (dwc->revision & DWC3_REVISION_IS_DWC31) 2304 - reg |= DWC3_DCFG_SUPERSPEED_PLUS; 2305 - else 2183 + if (DWC3_IP_IS(DWC3)) 2306 2184 reg |= DWC3_DCFG_SUPERSPEED; 2185 + else 2186 + reg |= DWC3_DCFG_SUPERSPEED_PLUS; 2307 2187 } 2308 2188 } 2309 2189 dwc3_writel(dwc->regs, DWC3_DCFG, reg); ··· 2346 2226 int size; 2347 2227 2348 2228 mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 2229 + if (DWC3_IP_IS(DWC32)) 2230 + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 2231 + 2349 2232 /* MDWIDTH is represented in bits, we need it in bytes */ 2350 2233 mdwidth /= 8; 2351 2234 2352 2235 size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1)); 2353 - if (dwc3_is_usb31(dwc)) 2354 - size = DWC31_GTXFIFOSIZ_TXFDEP(size); 2355 - else 2236 + if (DWC3_IP_IS(DWC3)) 2356 2237 size = DWC3_GTXFIFOSIZ_TXFDEP(size); 2238 + else 2239 + size = DWC31_GTXFIFOSIZ_TXFDEP(size); 2357 2240 2358 2241 /* FIFO Depth is in MDWDITH bytes. Multiply */ 2359 2242 size *= mdwidth; ··· 2393 2270 int size; 2394 2271 2395 2272 mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); 2273 + if (DWC3_IP_IS(DWC32)) 2274 + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); 2396 2275 2397 2276 /* MDWIDTH is represented in bits, convert to bytes */ 2398 2277 mdwidth /= 8; 2399 2278 2400 2279 /* All OUT endpoints share a single RxFIFO space */ 2401 2280 size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0)); 2402 - if (dwc3_is_usb31(dwc)) 2403 - size = DWC31_GRXFIFOSIZ_RXFDEP(size); 2404 - else 2281 + if (DWC3_IP_IS(DWC3)) 2405 2282 size = DWC3_GRXFIFOSIZ_RXFDEP(size); 2283 + else 2284 + size = DWC31_GRXFIFOSIZ_RXFDEP(size); 2406 2285 2407 2286 /* FIFO depth is in MDWDITH bytes */ 2408 2287 size *= mdwidth; ··· 2656 2531 2657 2532 req->request.actual = req->request.length - req->remaining; 2658 2533 2659 - if (!dwc3_gadget_ep_request_completed(req)) { 2660 - __dwc3_gadget_kick_transfer(dep); 2534 + if (!dwc3_gadget_ep_request_completed(req)) 2661 2535 goto out; 2662 - } 2663 2536 2664 2537 dwc3_gadget_giveback(dep, req, status); 2665 2538 ··· 2681 2558 } 2682 2559 } 2683 2560 2561 + static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep) 2562 + { 2563 + struct dwc3_request *req; 2564 + 2565 + if (!list_empty(&dep->pending_list)) 2566 + return true; 2567 + 2568 + /* 2569 + * We only need to check the first entry of the started list. We can 2570 + * assume the completed requests are removed from the started list. 2571 + */ 2572 + req = next_request(&dep->started_list); 2573 + if (!req) 2574 + return false; 2575 + 2576 + return !dwc3_gadget_ep_request_completed(req); 2577 + } 2578 + 2684 2579 static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, 2685 2580 const struct dwc3_event_depevt *event) 2686 2581 { 2687 2582 dep->frame_number = event->parameters; 2688 2583 } 2689 2584 2690 - static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, 2691 - const struct dwc3_event_depevt *event) 2585 + static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, 2586 + const struct dwc3_event_depevt *event, int status) 2692 2587 { 2693 2588 struct dwc3 *dwc = dep->dwc; 2694 - unsigned status = 0; 2695 - bool stop = false; 2696 - 2697 - dwc3_gadget_endpoint_frame_from_event(dep, event); 2698 - 2699 - if (event->status & DEPEVT_STATUS_BUSERR) 2700 - status = -ECONNRESET; 2701 - 2702 - if (event->status & DEPEVT_STATUS_MISSED_ISOC) { 2703 - status = -EXDEV; 2704 - 2705 - if (list_empty(&dep->started_list)) 2706 - stop = true; 2707 - } 2589 + bool no_started_trb = true; 2708 2590 2709 2591 dwc3_gadget_ep_cleanup_completed_requests(dep, event, status); 2710 2592 2711 - if (stop) 2712 - dwc3_stop_active_transfer(dep, true, true); 2593 + if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) 2594 + goto out; 2713 2595 2596 + if (status == -EXDEV && list_empty(&dep->started_list)) 2597 + dwc3_stop_active_transfer(dep, true, true); 2598 + else if (dwc3_gadget_ep_should_continue(dep)) 2599 + if (__dwc3_gadget_kick_transfer(dep) == 0) 2600 + no_started_trb = false; 2601 + 2602 + out: 2714 2603 /* 2715 2604 * WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround. 2716 2605 * See dwc3_gadget_linksts_change_interrupt() for 1st half. 2717 2606 */ 2718 - if (dwc->revision < DWC3_REVISION_183A) { 2607 + if (DWC3_VER_IS_PRIOR(DWC3, 183A)) { 2719 2608 u32 reg; 2720 2609 int i; 2721 2610 ··· 2738 2603 continue; 2739 2604 2740 2605 if (!list_empty(&dep->started_list)) 2741 - return; 2606 + return no_started_trb; 2742 2607 } 2743 2608 2744 2609 reg = dwc3_readl(dwc->regs, DWC3_DCTL); ··· 2747 2612 2748 2613 dwc->u1u2 = 0; 2749 2614 } 2615 + 2616 + return no_started_trb; 2617 + } 2618 + 2619 + static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, 2620 + const struct dwc3_event_depevt *event) 2621 + { 2622 + int status = 0; 2623 + 2624 + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) 2625 + dwc3_gadget_endpoint_frame_from_event(dep, event); 2626 + 2627 + if (event->status & DEPEVT_STATUS_BUSERR) 2628 + status = -ECONNRESET; 2629 + 2630 + if (event->status & DEPEVT_STATUS_MISSED_ISOC) 2631 + status = -EXDEV; 2632 + 2633 + dwc3_gadget_endpoint_trbs_complete(dep, event, status); 2634 + } 2635 + 2636 + static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep, 2637 + const struct dwc3_event_depevt *event) 2638 + { 2639 + int status = 0; 2640 + 2641 + dep->flags &= ~DWC3_EP_TRANSFER_STARTED; 2642 + 2643 + if (event->status & DEPEVT_STATUS_BUSERR) 2644 + status = -ECONNRESET; 2645 + 2646 + if (dwc3_gadget_endpoint_trbs_complete(dep, event, status)) 2647 + dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; 2750 2648 } 2751 2649 2752 2650 static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, 2753 2651 const struct dwc3_event_depevt *event) 2754 2652 { 2755 2653 dwc3_gadget_endpoint_frame_from_event(dep, event); 2654 + 2655 + /* 2656 + * The XferNotReady event is generated only once before the endpoint 2657 + * starts. It will be generated again when END_TRANSFER command is 2658 + * issued. For some controller versions, the XferNotReady event may be 2659 + * generated while the END_TRANSFER command is still in process. Ignore 2660 + * it and wait for the next XferNotReady event after the command is 2661 + * completed. 2662 + */ 2663 + if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) 2664 + return; 2665 + 2756 2666 (void) __dwc3_gadget_start_isoc(dep); 2667 + } 2668 + 2669 + static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep, 2670 + const struct dwc3_event_depevt *event) 2671 + { 2672 + struct dwc3 *dwc = dep->dwc; 2673 + 2674 + if (event->status == DEPEVT_STREAMEVT_FOUND) { 2675 + dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED; 2676 + goto out; 2677 + } 2678 + 2679 + /* Note: NoStream rejection event param value is 0 and not 0xFFFF */ 2680 + switch (event->parameters) { 2681 + case DEPEVT_STREAM_PRIME: 2682 + /* 2683 + * If the host can properly transition the endpoint state from 2684 + * idle to prime after a NoStream rejection, there's no need to 2685 + * force restarting the endpoint to reinitiate the stream. To 2686 + * simplify the check, assume the host follows the USB spec if 2687 + * it primed the endpoint more than once. 2688 + */ 2689 + if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM) { 2690 + if (dep->flags & DWC3_EP_FIRST_STREAM_PRIMED) 2691 + dep->flags &= ~DWC3_EP_FORCE_RESTART_STREAM; 2692 + else 2693 + dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED; 2694 + } 2695 + 2696 + break; 2697 + case DEPEVT_STREAM_NOSTREAM: 2698 + if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) || 2699 + !(dep->flags & DWC3_EP_FORCE_RESTART_STREAM) || 2700 + !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)) 2701 + break; 2702 + 2703 + /* 2704 + * If the host rejects a stream due to no active stream, by the 2705 + * USB and xHCI spec, the endpoint will be put back to idle 2706 + * state. When the host is ready (buffer added/updated), it will 2707 + * prime the endpoint to inform the usb device controller. This 2708 + * triggers the device controller to issue ERDY to restart the 2709 + * stream. However, some hosts don't follow this and keep the 2710 + * endpoint in the idle state. No prime will come despite host 2711 + * streams are updated, and the device controller will not be 2712 + * triggered to generate ERDY to move the next stream data. To 2713 + * workaround this and maintain compatibility with various 2714 + * hosts, force to reinitate the stream until the host is ready 2715 + * instead of waiting for the host to prime the endpoint. 2716 + */ 2717 + if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) { 2718 + unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME; 2719 + 2720 + dwc3_send_gadget_generic_command(dwc, cmd, dep->number); 2721 + } else { 2722 + dep->flags |= DWC3_EP_DELAY_START; 2723 + dwc3_stop_active_transfer(dep, true, true); 2724 + return; 2725 + } 2726 + break; 2727 + } 2728 + 2729 + out: 2730 + dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM; 2757 2731 } 2758 2732 2759 2733 static void dwc3_endpoint_interrupt(struct dwc3 *dwc, ··· 2909 2665 dep->flags &= ~DWC3_EP_DELAY_START; 2910 2666 } 2911 2667 break; 2912 - case DWC3_DEPEVT_STREAMEVT: 2913 2668 case DWC3_DEPEVT_XFERCOMPLETE: 2669 + dwc3_gadget_endpoint_transfer_complete(dep, event); 2670 + break; 2671 + case DWC3_DEPEVT_STREAMEVT: 2672 + dwc3_gadget_endpoint_stream_event(dep, event); 2673 + break; 2914 2674 case DWC3_DEPEVT_RXTXFIFOEVT: 2915 2675 break; 2916 2676 } ··· 3006 2758 WARN_ON_ONCE(ret); 3007 2759 dep->resource_index = 0; 3008 2760 2761 + /* 2762 + * The END_TRANSFER command will cause the controller to generate a 2763 + * NoStream Event, and it's not due to the host DP NoStream rejection. 2764 + * Ignore the next NoStream event. 2765 + */ 2766 + if (dep->stream_capable) 2767 + dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM; 2768 + 3009 2769 if (!interrupt) 3010 2770 dep->flags &= ~DWC3_EP_TRANSFER_STARTED; 3011 2771 else ··· 3094 2838 * STAR#9000466709: RTL: Device : Disconnect event not 3095 2839 * generated if setup packet pending in FIFO 3096 2840 */ 3097 - if (dwc->revision < DWC3_REVISION_188A) { 2841 + if (DWC3_VER_IS_PRIOR(DWC3, 188A)) { 3098 2842 if (dwc->setup_packet_pending) 3099 2843 dwc3_gadget_disconnect_interrupt(dwc); 3100 2844 } ··· 3153 2897 * STAR#9000483510: RTL: SS : USB3 reset event may 3154 2898 * not be generated always when the link enters poll 3155 2899 */ 3156 - if (dwc->revision < DWC3_REVISION_190A) 2900 + if (DWC3_VER_IS_PRIOR(DWC3, 190A)) 3157 2901 dwc3_gadget_reset_interrupt(dwc); 3158 2902 3159 2903 dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); ··· 3181 2925 3182 2926 /* Enable USB2 LPM Capability */ 3183 2927 3184 - if ((dwc->revision > DWC3_REVISION_194A) && 2928 + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) && 3185 2929 (speed != DWC3_DSTS_SUPERSPEED) && 3186 2930 (speed != DWC3_DSTS_SUPERSPEED_PLUS)) { 3187 2931 reg = dwc3_readl(dwc->regs, DWC3_DCFG); ··· 3200 2944 * BESL value in the LPM token is less than or equal to LPM 3201 2945 * NYET threshold. 3202 2946 */ 3203 - WARN_ONCE(dwc->revision < DWC3_REVISION_240A 3204 - && dwc->has_lpm_erratum, 2947 + WARN_ONCE(DWC3_VER_IS_PRIOR(DWC3, 240A) && dwc->has_lpm_erratum, 3205 2948 "LPM Erratum not available on dwc3 revisions < 2.40a\n"); 3206 2949 3207 - if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A) 2950 + if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A)) 3208 2951 reg |= DWC3_DCTL_NYET_THRES(dwc->lpm_nyet_threshold); 3209 2952 3210 2953 dwc3_gadget_dctl_write_safe(dwc, reg); ··· 3274 3019 * operational mode 3275 3020 */ 3276 3021 pwropt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); 3277 - if ((dwc->revision < DWC3_REVISION_250A) && 3022 + if (DWC3_VER_IS_PRIOR(DWC3, 250A) && 3278 3023 (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { 3279 3024 if ((dwc->link_state == DWC3_LINK_STATE_U3) && 3280 3025 (next == DWC3_LINK_STATE_RESUME)) { ··· 3300 3045 * STAR#9000446952: RTL: Device SS : if U1/U2 ->U0 takes >128us 3301 3046 * core send LGO_Ux entering U0 3302 3047 */ 3303 - if (dwc->revision < DWC3_REVISION_183A) { 3048 + if (DWC3_VER_IS_PRIOR(DWC3, 183A)) { 3304 3049 if (next == DWC3_LINK_STATE_U0) { 3305 3050 u32 u1u2; 3306 3051 u32 reg; ··· 3411 3156 break; 3412 3157 case DWC3_DEVICE_EVENT_EOPF: 3413 3158 /* It changed to be suspend event for version 2.30a and above */ 3414 - if (dwc->revision >= DWC3_REVISION_230A) { 3159 + if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) { 3415 3160 /* 3416 3161 * Ignore suspend event until the gadget enters into 3417 3162 * USB_STATE_CONFIGURED state. ··· 3656 3401 * is less than super speed because we don't have means, yet, to tell 3657 3402 * composite.c that we are USB 2.0 + LPM ECN. 3658 3403 */ 3659 - if (dwc->revision < DWC3_REVISION_220A && 3404 + if (DWC3_VER_IS_PRIOR(DWC3, 220A) && 3660 3405 !dwc->dis_metastability_quirk) 3661 3406 dev_info(dwc->dev, "changing max_speed on rev %08x\n", 3662 3407 dwc->revision);
+1 -1
drivers/usb/dwc3/gadget.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * gadget.h - DesignWare USB3 DRD Gadget Header 4 4 *
+1 -1
drivers/usb/dwc3/host.c
··· 104 104 * 105 105 * This following flag tells XHCI to do just that. 106 106 */ 107 - if (dwc->revision <= DWC3_REVISION_300A) 107 + if (DWC3_VER_IS_WITHIN(DWC3, ANY, 300A)) 108 108 props[prop_idx++] = PROPERTY_ENTRY_BOOL("quirk-broken-port-ped"); 109 109 110 110 if (prop_idx) {
+1 -1
drivers/usb/dwc3/io.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /** 3 3 * io.h - DesignWare USB3 DRD IO Header 4 4 *
+1 -1
drivers/usb/dwc3/trace.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /** 3 3 * trace.h - DesignWare USB3 DRD Controller Trace Support 4 4 *
-1
drivers/usb/early/xhci-dbc.c
··· 18 18 #include <asm/fixmap.h> 19 19 #include <linux/bcd.h> 20 20 #include <linux/export.h> 21 - #include <linux/version.h> 22 21 #include <linux/module.h> 23 22 #include <linux/delay.h> 24 23 #include <linux/kthread.h>
+1 -1
drivers/usb/early/xhci-dbc.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * xhci-dbc.h - xHCI debug capability early driver 4 4 *
+61 -17
drivers/usb/gadget/composite.c
··· 96 96 } 97 97 98 98 /** 99 - * next_ep_desc() - advance to the next EP descriptor 99 + * next_desc() - advance to the next desc_type descriptor 100 100 * @t: currect pointer within descriptor array 101 + * @desc_type: descriptor type 101 102 * 102 - * Return: next EP descriptor or NULL 103 + * Return: next desc_type descriptor or NULL 103 104 * 104 - * Iterate over @t until either EP descriptor found or 105 + * Iterate over @t until either desc_type descriptor found or 105 106 * NULL (that indicates end of list) encountered 106 107 */ 107 108 static struct usb_descriptor_header** 108 - next_ep_desc(struct usb_descriptor_header **t) 109 + next_desc(struct usb_descriptor_header **t, u8 desc_type) 109 110 { 110 111 for (; *t; t++) { 111 - if ((*t)->bDescriptorType == USB_DT_ENDPOINT) 112 + if ((*t)->bDescriptorType == desc_type) 112 113 return t; 113 114 } 114 115 return NULL; 115 116 } 116 117 117 118 /* 118 - * for_each_ep_desc()- iterate over endpoint descriptors in the 119 - * descriptors list 120 - * @start: pointer within descriptor array. 121 - * @ep_desc: endpoint descriptor to use as the loop cursor 119 + * for_each_desc() - iterate over desc_type descriptors in the 120 + * descriptors list 121 + * @start: pointer within descriptor array. 122 + * @iter_desc: desc_type descriptor to use as the loop cursor 123 + * @desc_type: wanted descriptr type 122 124 */ 123 - #define for_each_ep_desc(start, ep_desc) \ 124 - for (ep_desc = next_ep_desc(start); \ 125 - ep_desc; ep_desc = next_ep_desc(ep_desc+1)) 125 + #define for_each_desc(start, iter_desc, desc_type) \ 126 + for (iter_desc = next_desc(start, desc_type); \ 127 + iter_desc; iter_desc = next_desc(iter_desc + 1, desc_type)) 126 128 127 129 /** 128 - * config_ep_by_speed() - configures the given endpoint 130 + * config_ep_by_speed_and_alt() - configures the given endpoint 129 131 * according to gadget speed. 130 132 * @g: pointer to the gadget 131 133 * @f: usb function 132 134 * @_ep: the endpoint to configure 135 + * @alt: alternate setting number 133 136 * 134 137 * Return: error code, 0 on success 135 138 * ··· 145 142 * Note: the supplied function should hold all the descriptors 146 143 * for supported speeds 147 144 */ 148 - int config_ep_by_speed(struct usb_gadget *g, 149 - struct usb_function *f, 150 - struct usb_ep *_ep) 145 + int config_ep_by_speed_and_alt(struct usb_gadget *g, 146 + struct usb_function *f, 147 + struct usb_ep *_ep, 148 + u8 alt) 151 149 { 152 150 struct usb_endpoint_descriptor *chosen_desc = NULL; 151 + struct usb_interface_descriptor *int_desc = NULL; 153 152 struct usb_descriptor_header **speed_desc = NULL; 154 153 155 154 struct usb_ss_ep_comp_descriptor *comp_desc = NULL; ··· 187 182 default: 188 183 speed_desc = f->fs_descriptors; 189 184 } 185 + 186 + /* find correct alternate setting descriptor */ 187 + for_each_desc(speed_desc, d_spd, USB_DT_INTERFACE) { 188 + int_desc = (struct usb_interface_descriptor *)*d_spd; 189 + 190 + if (int_desc->bAlternateSetting == alt) { 191 + speed_desc = d_spd; 192 + goto intf_found; 193 + } 194 + } 195 + return -EIO; 196 + 197 + intf_found: 190 198 /* find descriptors */ 191 - for_each_ep_desc(speed_desc, d_spd) { 199 + for_each_desc(speed_desc, d_spd, USB_DT_ENDPOINT) { 192 200 chosen_desc = (struct usb_endpoint_descriptor *)*d_spd; 193 201 if (chosen_desc->bEndpointAddress == _ep->address) 194 202 goto ep_found; ··· 254 236 } 255 237 } 256 238 return 0; 239 + } 240 + EXPORT_SYMBOL_GPL(config_ep_by_speed_and_alt); 241 + 242 + /** 243 + * config_ep_by_speed() - configures the given endpoint 244 + * according to gadget speed. 245 + * @g: pointer to the gadget 246 + * @f: usb function 247 + * @_ep: the endpoint to configure 248 + * 249 + * Return: error code, 0 on success 250 + * 251 + * This function chooses the right descriptors for a given 252 + * endpoint according to gadget speed and saves it in the 253 + * endpoint desc field. If the endpoint already has a descriptor 254 + * assigned to it - overwrites it with currently corresponding 255 + * descriptor. The endpoint maxpacket field is updated according 256 + * to the chosen descriptor. 257 + * Note: the supplied function should hold all the descriptors 258 + * for supported speeds 259 + */ 260 + int config_ep_by_speed(struct usb_gadget *g, 261 + struct usb_function *f, 262 + struct usb_ep *_ep) 263 + { 264 + return config_ep_by_speed_and_alt(g, f, _ep, 0); 257 265 } 258 266 EXPORT_SYMBOL_GPL(config_ep_by_speed); 259 267
+1 -13
drivers/usb/gadget/configfs.c
··· 13 13 int check_user_usb_string(const char *name, 14 14 struct usb_gadget_strings *stringtab_dev) 15 15 { 16 - unsigned primary_lang; 17 - unsigned sub_lang; 18 16 u16 num; 19 17 int ret; 20 18 ··· 20 22 if (ret) 21 23 return ret; 22 24 23 - primary_lang = num & 0x3ff; 24 - sub_lang = num >> 10; 25 - 26 - /* simple sanity check for valid langid */ 27 - switch (primary_lang) { 28 - case 0: 29 - case 0x62 ... 0xfe: 30 - case 0x100 ... 0x3ff: 31 - return -EINVAL; 32 - } 33 - if (!sub_lang) 25 + if (!usb_validate_langid(num)) 34 26 return -EINVAL; 35 27 36 28 stringtab_dev->language = num;
+16
drivers/usb/gadget/function/f_acm.c
··· 723 723 kfree(acm); 724 724 } 725 725 726 + static void acm_resume(struct usb_function *f) 727 + { 728 + struct f_acm *acm = func_to_acm(f); 729 + 730 + gserial_resume(&acm->port); 731 + } 732 + 733 + static void acm_suspend(struct usb_function *f) 734 + { 735 + struct f_acm *acm = func_to_acm(f); 736 + 737 + gserial_suspend(&acm->port); 738 + } 739 + 726 740 static struct usb_function *acm_alloc_func(struct usb_function_instance *fi) 727 741 { 728 742 struct f_serial_opts *opts; ··· 764 750 acm->port_num = opts->port_num; 765 751 acm->port.func.unbind = acm_unbind; 766 752 acm->port.func.free_func = acm_free_func; 753 + acm->port.func.resume = acm_resume; 754 + acm->port.func.suspend = acm_suspend; 767 755 768 756 return &acm->port.func; 769 757 }
-2
drivers/usb/gadget/function/f_eem.c
··· 291 291 goto fail; 292 292 eem->port.out_ep = ep; 293 293 294 - status = -ENOMEM; 295 - 296 294 /* support all relevant hardware speeds... we expect that when 297 295 * hardware is dual speed, all bulk-capable endpoints work at 298 296 * both speeds
+1 -1
drivers/usb/gadget/function/f_fs.c
··· 2508 2508 os_descs_count = get_unaligned_le32(data); 2509 2509 data += 4; 2510 2510 len -= 4; 2511 - }; 2511 + } 2512 2512 2513 2513 /* Read descriptors */ 2514 2514 raw_descs = data;
+16
drivers/usb/gadget/function/f_serial.c
··· 348 348 usb_free_all_descriptors(f); 349 349 } 350 350 351 + static void gser_resume(struct usb_function *f) 352 + { 353 + struct f_gser *gser = func_to_gser(f); 354 + 355 + gserial_resume(&gser->port); 356 + } 357 + 358 + static void gser_suspend(struct usb_function *f) 359 + { 360 + struct f_gser *gser = func_to_gser(f); 361 + 362 + gserial_suspend(&gser->port); 363 + } 364 + 351 365 static struct usb_function *gser_alloc(struct usb_function_instance *fi) 352 366 { 353 367 struct f_gser *gser; ··· 383 369 gser->port.func.set_alt = gser_set_alt; 384 370 gser->port.func.disable = gser_disable; 385 371 gser->port.func.free_func = gser_free; 372 + gser->port.func.resume = gser_resume; 373 + gser->port.func.suspend = gser_suspend; 386 374 387 375 return &gser->port.func; 388 376 }
+3
drivers/usb/gadget/function/f_tcm.c
··· 531 531 stream->req_in->sg = se_cmd->t_data_sg; 532 532 } 533 533 534 + stream->req_in->is_last = 1; 534 535 stream->req_in->complete = uasp_status_data_cmpl; 535 536 stream->req_in->length = se_cmd->data_length; 536 537 stream->req_in->context = cmd; ··· 555 554 */ 556 555 iu->len = cpu_to_be16(se_cmd->scsi_sense_length); 557 556 iu->status = se_cmd->scsi_status; 557 + stream->req_status->is_last = 1; 558 558 stream->req_status->context = cmd; 559 559 stream->req_status->length = se_cmd->scsi_sense_length + 16; 560 560 stream->req_status->buf = iu; ··· 993 991 req->sg = se_cmd->t_data_sg; 994 992 } 995 993 994 + req->is_last = 1; 996 995 req->complete = usbg_data_write_cmpl; 997 996 req->length = se_cmd->data_length; 998 997 req->context = cmd;
+1 -1
drivers/usb/gadget/function/f_uvc.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * f_uvc.h -- USB Video Class Gadget driver 4 4 *
+1 -1
drivers/usb/gadget/function/rndis.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * RNDIS Definitions for Remote NDIS 4 4 *
+1 -1
drivers/usb/gadget/function/u_audio.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * u_audio.h -- interface to USB gadget "ALSA sound card" utilities 4 4 *
+1 -1
drivers/usb/gadget/function/u_ecm.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_ecm.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_eem.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_eem.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_ether.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * u_ether.h -- interface to USB gadget "ethernet link" utilities 4 4 *
+1 -1
drivers/usb/gadget/function/u_ether_configfs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_ether_configfs.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_fs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_fs.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_gether.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_gether.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_hid.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_hid.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_midi.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_midi.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_ncm.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_ncm.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_phonet.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * u_phonet.h - interface to Phonet 4 4 *
+1 -1
drivers/usb/gadget/function/u_printer.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_printer.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_rndis.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_rndis.h 4 4 *
+47 -6
drivers/usb/gadget/function/u_serial.c
··· 120 120 wait_queue_head_t drain_wait; /* wait while writes drain */ 121 121 bool write_busy; 122 122 wait_queue_head_t close_wait; 123 + bool suspended; /* port suspended */ 124 + bool start_delayed; /* delay start when suspended */ 123 125 124 126 /* REVISIT this state ... */ 125 127 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ ··· 632 630 633 631 /* if connected, start the I/O stream */ 634 632 if (port->port_usb) { 635 - struct gserial *gser = port->port_usb; 633 + /* if port is suspended, wait resume to start I/0 stream */ 634 + if (!port->suspended) { 635 + struct gserial *gser = port->port_usb; 636 636 637 - pr_debug("gs_open: start ttyGS%d\n", port->port_num); 638 - gs_start_io(port); 637 + pr_debug("gs_open: start ttyGS%d\n", port->port_num); 638 + gs_start_io(port); 639 639 640 - if (gser->connect) 641 - gser->connect(gser); 640 + if (gser->connect) 641 + gser->connect(gser); 642 + } else { 643 + pr_debug("delay start of ttyGS%d\n", port->port_num); 644 + port->start_delayed = true; 645 + } 642 646 } 643 647 644 648 pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file); ··· 688 680 pr_debug("gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file); 689 681 690 682 gser = port->port_usb; 691 - if (gser && gser->disconnect) 683 + if (gser && !port->suspended && gser->disconnect) 692 684 gser->disconnect(gser); 693 685 694 686 /* wait for circular write buffer to drain, disconnect, or at ··· 716 708 else 717 709 kfifo_reset(&port->port_write_buf); 718 710 711 + port->start_delayed = false; 719 712 port->port.count = 0; 720 713 port->port.tty = NULL; 721 714 ··· 1411 1402 spin_unlock_irqrestore(&port->port_lock, flags); 1412 1403 } 1413 1404 EXPORT_SYMBOL_GPL(gserial_disconnect); 1405 + 1406 + void gserial_suspend(struct gserial *gser) 1407 + { 1408 + struct gs_port *port = gser->ioport; 1409 + unsigned long flags; 1410 + 1411 + spin_lock_irqsave(&port->port_lock, flags); 1412 + port->suspended = true; 1413 + spin_unlock_irqrestore(&port->port_lock, flags); 1414 + } 1415 + EXPORT_SYMBOL_GPL(gserial_suspend); 1416 + 1417 + void gserial_resume(struct gserial *gser) 1418 + { 1419 + struct gs_port *port = gser->ioport; 1420 + unsigned long flags; 1421 + 1422 + spin_lock_irqsave(&port->port_lock, flags); 1423 + port->suspended = false; 1424 + if (!port->start_delayed) { 1425 + spin_unlock_irqrestore(&port->port_lock, flags); 1426 + return; 1427 + } 1428 + 1429 + pr_debug("delayed start ttyGS%d\n", port->port_num); 1430 + gs_start_io(port); 1431 + if (gser->connect) 1432 + gser->connect(gser); 1433 + port->start_delayed = false; 1434 + spin_unlock_irqrestore(&port->port_lock, flags); 1435 + } 1436 + EXPORT_SYMBOL_GPL(gserial_resume); 1414 1437 1415 1438 static int userial_init(void) 1416 1439 {
+3 -1
drivers/usb/gadget/function/u_serial.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * u_serial.h - interface to USB gadget "serial port"/TTY utilities 4 4 * ··· 68 68 /* connect/disconnect is handled by individual functions */ 69 69 int gserial_connect(struct gserial *, u8 port_num); 70 70 void gserial_disconnect(struct gserial *); 71 + void gserial_suspend(struct gserial *p); 72 + void gserial_resume(struct gserial *p); 71 73 72 74 /* functions are bound to configurations by a config or gadget driver */ 73 75 int gser_bind_config(struct usb_configuration *c, u8 port_num);
+1 -1
drivers/usb/gadget/function/u_tcm.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_tcm.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_uac1.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_uac1.h - Utility definitions for UAC1 function 4 4 *
+1 -1
drivers/usb/gadget/function/u_uac1_legacy.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities 4 4 *
+1 -1
drivers/usb/gadget/function/u_uac2.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_uac2.h 4 4 *
+1 -1
drivers/usb/gadget/function/u_uvc.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * u_uvc.h 4 4 *
+3 -1
drivers/usb/gadget/function/uvc.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * uvc_gadget.h -- USB Video Class Gadget driver 4 4 * ··· 76 76 struct uvc_video { 77 77 struct uvc_device *uvc; 78 78 struct usb_ep *ep; 79 + 80 + struct work_struct pump; 79 81 80 82 /* Frame parameters */ 81 83 u8 bpp;
+1 -1
drivers/usb/gadget/function/uvc_configfs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * uvc_configfs.h 4 4 *
+3 -1
drivers/usb/gadget/function/uvc_v4l2.c
··· 169 169 if (ret < 0) 170 170 return ret; 171 171 172 - return uvcg_video_pump(video); 172 + schedule_work(&video->pump); 173 + 174 + return ret; 173 175 } 174 176 175 177 static int
+1 -1
drivers/usb/gadget/function/uvc_v4l2.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * uvc_v4l2.h -- USB Video Class Gadget driver 4 4 *
+14 -62
drivers/usb/gadget/function/uvc_video.c
··· 142 142 return ret; 143 143 } 144 144 145 - /* 146 - * I somehow feel that synchronisation won't be easy to achieve here. We have 147 - * three events that control USB requests submission: 148 - * 149 - * - USB request completion: the completion handler will resubmit the request 150 - * if a video buffer is available. 151 - * 152 - * - USB interface setting selection: in response to a SET_INTERFACE request, 153 - * the handler will start streaming if a video buffer is available and if 154 - * video is not currently streaming. 155 - * 156 - * - V4L2 buffer queueing: the driver will start streaming if video is not 157 - * currently streaming. 158 - * 159 - * Race conditions between those 3 events might lead to deadlocks or other 160 - * nasty side effects. 161 - * 162 - * The "video currently streaming" condition can't be detected by the irqqueue 163 - * being empty, as a request can still be in flight. A separate "queue paused" 164 - * flag is thus needed. 165 - * 166 - * The paused flag will be set when we try to retrieve the irqqueue head if the 167 - * queue is empty, and cleared when we queue a buffer. 168 - * 169 - * The USB request completion handler will get the buffer at the irqqueue head 170 - * under protection of the queue spinlock. If the queue is empty, the streaming 171 - * paused flag will be set. Right after releasing the spinlock a userspace 172 - * application can queue a buffer. The flag will then cleared, and the ioctl 173 - * handler will restart the video stream. 174 - */ 175 145 static void 176 146 uvc_video_complete(struct usb_ep *ep, struct usb_request *req) 177 147 { 178 148 struct uvc_video *video = req->context; 179 149 struct uvc_video_queue *queue = &video->queue; 180 - struct uvc_buffer *buf; 181 150 unsigned long flags; 182 - int ret; 183 151 184 152 switch (req->status) { 185 153 case 0: ··· 156 188 case -ESHUTDOWN: /* disconnect from host. */ 157 189 uvcg_dbg(&video->uvc->func, "VS request cancelled.\n"); 158 190 uvcg_queue_cancel(queue, 1); 159 - goto requeue; 191 + break; 160 192 161 193 default: 162 194 uvcg_info(&video->uvc->func, 163 195 "VS request completed with status %d.\n", 164 196 req->status); 165 197 uvcg_queue_cancel(queue, 0); 166 - goto requeue; 167 198 } 168 199 169 - spin_lock_irqsave(&video->queue.irqlock, flags); 170 - buf = uvcg_queue_head(&video->queue); 171 - if (buf == NULL) { 172 - spin_unlock_irqrestore(&video->queue.irqlock, flags); 173 - goto requeue; 174 - } 175 - 176 - video->encode(req, video, buf); 177 - 178 - ret = uvcg_video_ep_queue(video, req); 179 - spin_unlock_irqrestore(&video->queue.irqlock, flags); 180 - 181 - if (ret < 0) { 182 - uvcg_queue_cancel(queue, 0); 183 - goto requeue; 184 - } 185 - 186 - return; 187 - 188 - requeue: 189 200 spin_lock_irqsave(&video->req_lock, flags); 190 201 list_add_tail(&req->list, &video->req_free); 191 202 spin_unlock_irqrestore(&video->req_lock, flags); 203 + 204 + schedule_work(&video->pump); 192 205 } 193 206 194 207 static int ··· 243 294 * This function fills the available USB requests (listed in req_free) with 244 295 * video data from the queued buffers. 245 296 */ 246 - int uvcg_video_pump(struct uvc_video *video) 297 + static void uvcg_video_pump(struct work_struct *work) 247 298 { 299 + struct uvc_video *video = container_of(work, struct uvc_video, pump); 248 300 struct uvc_video_queue *queue = &video->queue; 249 301 struct usb_request *req; 250 302 struct uvc_buffer *buf; 251 303 unsigned long flags; 252 304 int ret; 253 - 254 - /* FIXME TODO Race between uvcg_video_pump and requests completion 255 - * handler ??? 256 - */ 257 305 258 306 while (1) { 259 307 /* Retrieve the first available USB request, protected by the ··· 259 313 spin_lock_irqsave(&video->req_lock, flags); 260 314 if (list_empty(&video->req_free)) { 261 315 spin_unlock_irqrestore(&video->req_lock, flags); 262 - return 0; 316 + return; 263 317 } 264 318 req = list_first_entry(&video->req_free, struct usb_request, 265 319 list); ··· 291 345 spin_lock_irqsave(&video->req_lock, flags); 292 346 list_add_tail(&req->list, &video->req_free); 293 347 spin_unlock_irqrestore(&video->req_lock, flags); 294 - return 0; 348 + return; 295 349 } 296 350 297 351 /* ··· 309 363 } 310 364 311 365 if (!enable) { 366 + cancel_work_sync(&video->pump); 367 + uvcg_queue_cancel(&video->queue, 0); 368 + 312 369 for (i = 0; i < UVC_NUM_REQUESTS; ++i) 313 370 if (video->req[i]) 314 371 usb_ep_dequeue(video->ep, video->req[i]); ··· 333 384 } else 334 385 video->encode = uvc_video_encode_isoc; 335 386 336 - return uvcg_video_pump(video); 387 + schedule_work(&video->pump); 388 + 389 + return ret; 337 390 } 338 391 339 392 /* ··· 345 394 { 346 395 INIT_LIST_HEAD(&video->req_free); 347 396 spin_lock_init(&video->req_lock); 397 + INIT_WORK(&video->pump, uvcg_video_pump); 348 398 349 399 video->uvc = uvc; 350 400 video->fcc = V4L2_PIX_FMT_YUYV;
+1 -3
drivers/usb/gadget/function/uvc_video.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * uvc_video.h -- USB Video Class Gadget driver 4 4 * ··· 13 13 #define __UVC_VIDEO_H__ 14 14 15 15 struct uvc_video; 16 - 17 - int uvcg_video_pump(struct uvc_video *video); 18 16 19 17 int uvcg_video_enable(struct uvc_video *video, int enable); 20 18
+2 -12
drivers/usb/gadget/legacy/mass_storage.c
··· 229 229 .unbind = msg_unbind, 230 230 }; 231 231 232 + module_usb_composite_driver(msg_driver); 233 + 232 234 MODULE_DESCRIPTION(DRIVER_DESC); 233 235 MODULE_AUTHOR("Michal Nazarewicz"); 234 236 MODULE_LICENSE("GPL"); 235 - 236 - static int __init msg_init(void) 237 - { 238 - return usb_composite_probe(&msg_driver); 239 - } 240 - module_init(msg_init); 241 - 242 - static void __exit msg_cleanup(void) 243 - { 244 - usb_composite_unregister(&msg_driver); 245 - } 246 - module_exit(msg_cleanup);
+12 -4
drivers/usb/gadget/udc/aspeed-vhub/core.c
··· 134 134 } 135 135 136 136 /* Handle device interrupts */ 137 - for (i = 0; i < vhub->max_ports; i++) { 138 - u32 dev_mask = VHUB_IRQ_DEVICE1 << i; 137 + if (istat & vhub->port_irq_mask) { 138 + unsigned long bitmap = istat; 139 + int offset = VHUB_IRQ_DEV1_BIT; 140 + int size = VHUB_IRQ_DEV1_BIT + vhub->max_ports; 139 141 140 - if (istat & dev_mask) 142 + for_each_set_bit_from(offset, &bitmap, size) { 143 + i = offset - VHUB_IRQ_DEV1_BIT; 141 144 ast_vhub_dev_irq(&vhub->ports[i].dev); 145 + } 142 146 } 143 147 144 148 /* Handle top-level vHub EP0 interrupts */ ··· 336 332 337 333 spin_lock_init(&vhub->lock); 338 334 vhub->pdev = pdev; 335 + vhub->port_irq_mask = GENMASK(VHUB_IRQ_DEV1_BIT + vhub->max_ports - 1, 336 + VHUB_IRQ_DEV1_BIT); 339 337 340 338 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 341 339 vhub->regs = devm_ioremap_resource(&pdev->dev, res); ··· 408 402 goto err; 409 403 410 404 /* Init hub emulation */ 411 - ast_vhub_init_hub(vhub); 405 + rc = ast_vhub_init_hub(vhub); 406 + if (rc) 407 + goto err; 412 408 413 409 /* Initialize HW */ 414 410 ast_vhub_init_hw(vhub);
+211 -25
drivers/usb/gadget/udc/aspeed-vhub/hub.c
··· 50 50 #define KERNEL_VER bin2bcd(((LINUX_VERSION_CODE >> 8) & 0x0ff)) 51 51 52 52 enum { 53 + AST_VHUB_STR_INDEX_MAX = 4, 53 54 AST_VHUB_STR_MANUF = 3, 54 55 AST_VHUB_STR_PRODUCT = 2, 55 56 AST_VHUB_STR_SERIAL = 1, ··· 72 71 .iSerialNumber = AST_VHUB_STR_SERIAL, 73 72 .bNumConfigurations = 1, 74 73 }; 75 - 76 - /* Patches to the above when forcing USB1 mode */ 77 - static void ast_vhub_patch_dev_desc_usb1(struct usb_device_descriptor *desc) 78 - { 79 - desc->bcdUSB = cpu_to_le16(0x0100); 80 - desc->bDeviceProtocol = 0; 81 - } 82 74 83 75 /* 84 76 * Configuration descriptor: same comments as above ··· 296 302 if (len > dsize) 297 303 len = dsize; 298 304 299 - /* Patch it if forcing USB1 */ 300 - if (desc_type == USB_DT_DEVICE && ep->vhub->force_usb1) 301 - ast_vhub_patch_dev_desc_usb1(ep->buf); 302 - 303 305 /* Shoot it from the EP buffer */ 304 306 return ast_vhub_reply(ep, NULL, len); 307 + } 308 + 309 + static struct usb_gadget_strings* 310 + ast_vhub_str_of_container(struct usb_gadget_string_container *container) 311 + { 312 + return (struct usb_gadget_strings *)container->stash; 313 + } 314 + 315 + static int ast_vhub_collect_languages(struct ast_vhub *vhub, void *buf, 316 + size_t size) 317 + { 318 + int rc, hdr_len, nlangs, max_langs; 319 + struct usb_gadget_strings *lang_str; 320 + struct usb_gadget_string_container *container; 321 + struct usb_string_descriptor *sdesc = buf; 322 + 323 + nlangs = 0; 324 + hdr_len = sizeof(struct usb_descriptor_header); 325 + max_langs = (size - hdr_len) / sizeof(sdesc->wData[0]); 326 + list_for_each_entry(container, &vhub->vhub_str_desc, list) { 327 + if (nlangs >= max_langs) 328 + break; 329 + 330 + lang_str = ast_vhub_str_of_container(container); 331 + sdesc->wData[nlangs++] = cpu_to_le16(lang_str->language); 332 + } 333 + 334 + rc = hdr_len + nlangs * sizeof(sdesc->wData[0]); 335 + sdesc->bLength = rc; 336 + sdesc->bDescriptorType = USB_DT_STRING; 337 + 338 + return rc; 339 + } 340 + 341 + static struct usb_gadget_strings *ast_vhub_lookup_string(struct ast_vhub *vhub, 342 + u16 lang_id) 343 + { 344 + struct usb_gadget_strings *lang_str; 345 + struct usb_gadget_string_container *container; 346 + 347 + list_for_each_entry(container, &vhub->vhub_str_desc, list) { 348 + lang_str = ast_vhub_str_of_container(container); 349 + if (lang_str->language == lang_id) 350 + return lang_str; 351 + } 352 + 353 + return NULL; 305 354 } 306 355 307 356 static int ast_vhub_rep_string(struct ast_vhub_ep *ep, 308 357 u8 string_id, u16 lang_id, 309 358 u16 len) 310 359 { 311 - int rc = usb_gadget_get_string(&ep->vhub->vhub_str_desc, 312 - string_id, ep->buf); 360 + int rc; 361 + u8 buf[256]; 362 + struct ast_vhub *vhub = ep->vhub; 363 + struct usb_gadget_strings *lang_str; 313 364 314 - /* 315 - * This should never happen unless we put too big strings in 316 - * the array above 317 - */ 318 - BUG_ON(rc >= AST_VHUB_EP0_MAX_PACKET); 365 + if (string_id == 0) { 366 + rc = ast_vhub_collect_languages(vhub, buf, sizeof(buf)); 367 + } else { 368 + lang_str = ast_vhub_lookup_string(vhub, lang_id); 369 + if (!lang_str) 370 + return std_req_stall; 319 371 320 - if (rc < 0) 372 + rc = usb_gadget_get_string(lang_str, string_id, buf); 373 + } 374 + 375 + if (rc < 0 || rc >= AST_VHUB_EP0_MAX_PACKET) 321 376 return std_req_stall; 322 377 323 378 /* Shoot it from the EP buffer */ 379 + memcpy(ep->buf, buf, rc); 324 380 return ast_vhub_reply(ep, NULL, min_t(u16, rc, len)); 325 381 } 326 382 ··· 876 832 writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG); 877 833 } 878 834 879 - static void ast_vhub_init_desc(struct ast_vhub *vhub) 835 + static void ast_vhub_of_parse_dev_desc(struct ast_vhub *vhub, 836 + const struct device_node *vhub_np) 880 837 { 838 + u16 id; 839 + u32 data; 840 + 841 + if (!of_property_read_u32(vhub_np, "vhub-vendor-id", &data)) { 842 + id = (u16)data; 843 + vhub->vhub_dev_desc.idVendor = cpu_to_le16(id); 844 + } 845 + if (!of_property_read_u32(vhub_np, "vhub-product-id", &data)) { 846 + id = (u16)data; 847 + vhub->vhub_dev_desc.idProduct = cpu_to_le16(id); 848 + } 849 + if (!of_property_read_u32(vhub_np, "vhub-device-revision", &data)) { 850 + id = (u16)data; 851 + vhub->vhub_dev_desc.bcdDevice = cpu_to_le16(id); 852 + } 853 + } 854 + 855 + static void ast_vhub_fixup_usb1_dev_desc(struct ast_vhub *vhub) 856 + { 857 + vhub->vhub_dev_desc.bcdUSB = cpu_to_le16(0x0100); 858 + vhub->vhub_dev_desc.bDeviceProtocol = 0; 859 + } 860 + 861 + static struct usb_gadget_string_container* 862 + ast_vhub_str_container_alloc(struct ast_vhub *vhub) 863 + { 864 + unsigned int size; 865 + struct usb_string *str_array; 866 + struct usb_gadget_strings *lang_str; 867 + struct usb_gadget_string_container *container; 868 + 869 + size = sizeof(*container); 870 + size += sizeof(struct usb_gadget_strings); 871 + size += sizeof(struct usb_string) * AST_VHUB_STR_INDEX_MAX; 872 + container = devm_kzalloc(&vhub->pdev->dev, size, GFP_KERNEL); 873 + if (!container) 874 + return ERR_PTR(-ENOMEM); 875 + 876 + lang_str = ast_vhub_str_of_container(container); 877 + str_array = (struct usb_string *)(lang_str + 1); 878 + lang_str->strings = str_array; 879 + return container; 880 + } 881 + 882 + static void ast_vhub_str_deep_copy(struct usb_gadget_strings *dest, 883 + const struct usb_gadget_strings *src) 884 + { 885 + struct usb_string *src_array = src->strings; 886 + struct usb_string *dest_array = dest->strings; 887 + 888 + dest->language = src->language; 889 + if (src_array && dest_array) { 890 + do { 891 + *dest_array = *src_array; 892 + dest_array++; 893 + src_array++; 894 + } while (src_array->s); 895 + } 896 + } 897 + 898 + static int ast_vhub_str_alloc_add(struct ast_vhub *vhub, 899 + const struct usb_gadget_strings *src_str) 900 + { 901 + struct usb_gadget_strings *dest_str; 902 + struct usb_gadget_string_container *container; 903 + 904 + container = ast_vhub_str_container_alloc(vhub); 905 + if (IS_ERR(container)) 906 + return PTR_ERR(container); 907 + 908 + dest_str = ast_vhub_str_of_container(container); 909 + ast_vhub_str_deep_copy(dest_str, src_str); 910 + list_add_tail(&container->list, &vhub->vhub_str_desc); 911 + 912 + return 0; 913 + } 914 + 915 + static const struct { 916 + const char *name; 917 + u8 id; 918 + } str_id_map[] = { 919 + {"manufacturer", AST_VHUB_STR_MANUF}, 920 + {"product", AST_VHUB_STR_PRODUCT}, 921 + {"serial-number", AST_VHUB_STR_SERIAL}, 922 + {}, 923 + }; 924 + 925 + static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub, 926 + const struct device_node *desc_np) 927 + { 928 + u32 langid; 929 + int ret = 0; 930 + int i, offset; 931 + const char *str; 932 + struct device_node *child; 933 + struct usb_string str_array[AST_VHUB_STR_INDEX_MAX]; 934 + struct usb_gadget_strings lang_str = { 935 + .strings = (struct usb_string *)str_array, 936 + }; 937 + 938 + for_each_child_of_node(desc_np, child) { 939 + if (of_property_read_u32(child, "reg", &langid)) 940 + continue; /* no language identifier specified */ 941 + 942 + if (!usb_validate_langid(langid)) 943 + continue; /* invalid language identifier */ 944 + 945 + lang_str.language = langid; 946 + for (i = offset = 0; str_id_map[i].name; i++) { 947 + str = of_get_property(child, str_id_map[i].name, NULL); 948 + if (str) { 949 + str_array[offset].s = str; 950 + str_array[offset].id = str_id_map[i].id; 951 + offset++; 952 + } 953 + } 954 + str_array[offset].id = 0; 955 + str_array[offset].s = NULL; 956 + 957 + ret = ast_vhub_str_alloc_add(vhub, &lang_str); 958 + if (ret) 959 + break; 960 + } 961 + 962 + return ret; 963 + } 964 + 965 + static int ast_vhub_init_desc(struct ast_vhub *vhub) 966 + { 967 + int ret; 968 + struct device_node *desc_np; 969 + const struct device_node *vhub_np = vhub->pdev->dev.of_node; 970 + 881 971 /* Initialize vhub Device Descriptor. */ 882 972 memcpy(&vhub->vhub_dev_desc, &ast_vhub_dev_desc, 883 973 sizeof(vhub->vhub_dev_desc)); 974 + ast_vhub_of_parse_dev_desc(vhub, vhub_np); 975 + if (vhub->force_usb1) 976 + ast_vhub_fixup_usb1_dev_desc(vhub); 884 977 885 978 /* Initialize vhub Configuration Descriptor. */ 886 979 memcpy(&vhub->vhub_conf_desc, &ast_vhub_conf_desc, ··· 1029 848 vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports; 1030 849 1031 850 /* Initialize vhub String Descriptors. */ 1032 - memcpy(&vhub->vhub_str_desc, &ast_vhub_strings, 1033 - sizeof(vhub->vhub_str_desc)); 851 + INIT_LIST_HEAD(&vhub->vhub_str_desc); 852 + desc_np = of_get_child_by_name(vhub_np, "vhub-strings"); 853 + if (desc_np) 854 + ret = ast_vhub_of_parse_str_desc(vhub, desc_np); 855 + else 856 + ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings); 857 + 858 + return ret; 1034 859 } 1035 860 1036 - void ast_vhub_init_hub(struct ast_vhub *vhub) 861 + int ast_vhub_init_hub(struct ast_vhub *vhub) 1037 862 { 1038 863 vhub->speed = USB_SPEED_UNKNOWN; 1039 864 INIT_WORK(&vhub->wake_work, ast_vhub_wake_work); 1040 865 1041 - ast_vhub_init_desc(vhub); 866 + return ast_vhub_init_desc(vhub); 1042 867 } 1043 -
+5 -7
drivers/usb/gadget/udc/aspeed-vhub/vhub.h
··· 51 51 #define VHUB_CTRL_UPSTREAM_CONNECT (1 << 0) 52 52 53 53 /* IER & ISR */ 54 + #define VHUB_IRQ_DEV1_BIT 9 54 55 #define VHUB_IRQ_USB_CMD_DEADLOCK (1 << 18) 55 56 #define VHUB_IRQ_EP_POOL_NAK (1 << 17) 56 57 #define VHUB_IRQ_EP_POOL_ACK_STALL (1 << 16) 57 - #define VHUB_IRQ_DEVICE5 (1 << 13) 58 - #define VHUB_IRQ_DEVICE4 (1 << 12) 59 - #define VHUB_IRQ_DEVICE3 (1 << 11) 60 - #define VHUB_IRQ_DEVICE2 (1 << 10) 61 - #define VHUB_IRQ_DEVICE1 (1 << 9) 58 + #define VHUB_IRQ_DEVICE1 (1 << (VHUB_IRQ_DEV1_BIT)) 62 59 #define VHUB_IRQ_BUS_RESUME (1 << 8) 63 60 #define VHUB_IRQ_BUS_SUSPEND (1 << 7) 64 61 #define VHUB_IRQ_BUS_RESET (1 << 6) ··· 399 402 /* Per-port info */ 400 403 struct ast_vhub_port *ports; 401 404 u32 max_ports; 405 + u32 port_irq_mask; 402 406 403 407 /* Generic EP data structures */ 404 408 struct ast_vhub_ep *epns; ··· 421 423 struct usb_device_descriptor vhub_dev_desc; 422 424 struct ast_vhub_full_cdesc vhub_conf_desc; 423 425 struct usb_hub_descriptor vhub_hub_desc; 424 - struct usb_gadget_strings vhub_str_desc; 426 + struct list_head vhub_str_desc; 425 427 }; 426 428 427 429 /* Standard request handlers result codes */ ··· 531 533 __VA_ARGS__) 532 534 533 535 /* hub.c */ 534 - void ast_vhub_init_hub(struct ast_vhub *vhub); 536 + int ast_vhub_init_hub(struct ast_vhub *vhub); 535 537 enum std_req_rc ast_vhub_std_hub_request(struct ast_vhub_ep *ep, 536 538 struct usb_ctrlrequest *crq); 537 539 enum std_req_rc ast_vhub_class_hub_request(struct ast_vhub_ep *ep,
+72 -40
drivers/usb/gadget/udc/atmel_usba_udc.c
··· 2043 2043 .pulse_bias = at91sam9g45_pulse_bias, 2044 2044 }; 2045 2045 2046 + static const struct usba_ep_config ep_config_sam9[] __initconst = { 2047 + { .nr_banks = 1 }, /* ep 0 */ 2048 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 1 */ 2049 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 2 */ 2050 + { .nr_banks = 3, .can_dma = 1 }, /* ep 3 */ 2051 + { .nr_banks = 3, .can_dma = 1 }, /* ep 4 */ 2052 + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 5 */ 2053 + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 6 */ 2054 + }; 2055 + 2056 + static const struct usba_ep_config ep_config_sama5[] __initconst = { 2057 + { .nr_banks = 1 }, /* ep 0 */ 2058 + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 1 */ 2059 + { .nr_banks = 3, .can_dma = 1, .can_isoc = 1 }, /* ep 2 */ 2060 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 3 */ 2061 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 4 */ 2062 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 5 */ 2063 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 6 */ 2064 + { .nr_banks = 2, .can_dma = 1, .can_isoc = 1 }, /* ep 7 */ 2065 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 8 */ 2066 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 9 */ 2067 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 10 */ 2068 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 11 */ 2069 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 12 */ 2070 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 13 */ 2071 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 14 */ 2072 + { .nr_banks = 2, .can_isoc = 1 }, /* ep 15 */ 2073 + }; 2074 + 2075 + static const struct usba_udc_config udc_at91sam9rl_cfg = { 2076 + .errata = &at91sam9rl_errata, 2077 + .config = ep_config_sam9, 2078 + .num_ep = ARRAY_SIZE(ep_config_sam9), 2079 + }; 2080 + 2081 + static const struct usba_udc_config udc_at91sam9g45_cfg = { 2082 + .errata = &at91sam9g45_errata, 2083 + .config = ep_config_sam9, 2084 + .num_ep = ARRAY_SIZE(ep_config_sam9), 2085 + }; 2086 + 2087 + static const struct usba_udc_config udc_sama5d3_cfg = { 2088 + .config = ep_config_sama5, 2089 + .num_ep = ARRAY_SIZE(ep_config_sama5), 2090 + }; 2091 + 2046 2092 static const struct of_device_id atmel_udc_dt_ids[] = { 2047 - { .compatible = "atmel,at91sam9rl-udc", .data = &at91sam9rl_errata }, 2048 - { .compatible = "atmel,at91sam9g45-udc", .data = &at91sam9g45_errata }, 2049 - { .compatible = "atmel,sama5d3-udc" }, 2093 + { .compatible = "atmel,at91sam9rl-udc", .data = &udc_at91sam9rl_cfg }, 2094 + { .compatible = "atmel,at91sam9g45-udc", .data = &udc_at91sam9g45_cfg }, 2095 + { .compatible = "atmel,sama5d3-udc", .data = &udc_sama5d3_cfg }, 2050 2096 { /* sentinel */ } 2051 2097 }; 2052 2098 ··· 2101 2055 static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, 2102 2056 struct usba_udc *udc) 2103 2057 { 2104 - u32 val; 2105 2058 struct device_node *np = pdev->dev.of_node; 2106 2059 const struct of_device_id *match; 2107 2060 struct device_node *pp; 2108 2061 int i, ret; 2109 2062 struct usba_ep *eps, *ep; 2063 + const struct usba_udc_config *udc_config; 2110 2064 2111 2065 match = of_match_node(atmel_udc_dt_ids, np); 2112 2066 if (!match) 2113 2067 return ERR_PTR(-EINVAL); 2114 2068 2115 - udc->errata = match->data; 2069 + udc_config = match->data; 2070 + udc->errata = udc_config->errata; 2116 2071 udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc"); 2117 2072 if (IS_ERR(udc->pmc)) 2118 2073 udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9rl-pmc"); ··· 2129 2082 2130 2083 if (fifo_mode == 0) { 2131 2084 pp = NULL; 2132 - while ((pp = of_get_next_child(np, pp))) 2133 - udc->num_ep++; 2085 + udc->num_ep = udc_config->num_ep; 2134 2086 udc->configured_ep = 1; 2135 2087 } else { 2136 2088 udc->num_ep = usba_config_fifo_table(udc); ··· 2146 2100 2147 2101 pp = NULL; 2148 2102 i = 0; 2149 - while ((pp = of_get_next_child(np, pp)) && i < udc->num_ep) { 2103 + while (i < udc->num_ep) { 2104 + const struct usba_ep_config *ep_cfg = &udc_config->config[i]; 2105 + 2150 2106 ep = &eps[i]; 2151 2107 2152 - ret = of_property_read_u32(pp, "reg", &val); 2153 - if (ret) { 2154 - dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret); 2155 - goto err; 2156 - } 2157 - ep->index = fifo_mode ? udc->fifo_cfg[i].hw_ep_num : val; 2108 + ep->index = fifo_mode ? udc->fifo_cfg[i].hw_ep_num : i; 2158 2109 2159 - ret = of_property_read_u32(pp, "atmel,fifo-size", &val); 2160 - if (ret) { 2161 - dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret); 2162 - goto err; 2163 - } 2110 + /* Only the first EP is 64 bytes */ 2111 + if (ep->index == 0) 2112 + ep->fifo_size = 64; 2113 + else 2114 + ep->fifo_size = 1024; 2115 + 2164 2116 if (fifo_mode) { 2165 - if (val < udc->fifo_cfg[i].fifo_size) { 2117 + if (ep->fifo_size < udc->fifo_cfg[i].fifo_size) 2166 2118 dev_warn(&pdev->dev, 2167 - "Using max fifo-size value from DT\n"); 2168 - ep->fifo_size = val; 2169 - } else { 2119 + "Using default max fifo-size value\n"); 2120 + else 2170 2121 ep->fifo_size = udc->fifo_cfg[i].fifo_size; 2171 - } 2172 - } else { 2173 - ep->fifo_size = val; 2174 2122 } 2175 2123 2176 - ret = of_property_read_u32(pp, "atmel,nb-banks", &val); 2177 - if (ret) { 2178 - dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret); 2179 - goto err; 2180 - } 2124 + ep->nr_banks = ep_cfg->nr_banks; 2181 2125 if (fifo_mode) { 2182 - if (val < udc->fifo_cfg[i].nr_banks) { 2126 + if (ep->nr_banks < udc->fifo_cfg[i].nr_banks) 2183 2127 dev_warn(&pdev->dev, 2184 - "Using max nb-banks value from DT\n"); 2185 - ep->nr_banks = val; 2186 - } else { 2128 + "Using default max nb-banks value\n"); 2129 + else 2187 2130 ep->nr_banks = udc->fifo_cfg[i].nr_banks; 2188 - } 2189 - } else { 2190 - ep->nr_banks = val; 2191 2131 } 2192 2132 2193 - ep->can_dma = of_property_read_bool(pp, "atmel,can-dma"); 2194 - ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc"); 2133 + ep->can_dma = ep_cfg->can_dma; 2134 + ep->can_isoc = ep_cfg->can_isoc; 2195 2135 2196 2136 sprintf(ep->name, "ep%d", ep->index); 2197 2137 ep->ep.name = ep->name;
+12
drivers/usb/gadget/udc/atmel_usba_udc.h
··· 290 290 #endif 291 291 }; 292 292 293 + struct usba_ep_config { 294 + u8 nr_banks; 295 + unsigned int can_dma:1; 296 + unsigned int can_isoc:1; 297 + }; 298 + 293 299 struct usba_request { 294 300 struct usb_request req; 295 301 struct list_head queue; ··· 311 305 struct usba_udc_errata { 312 306 void (*toggle_bias)(struct usba_udc *udc, int is_on); 313 307 void (*pulse_bias)(struct usba_udc *udc); 308 + }; 309 + 310 + struct usba_udc_config { 311 + const struct usba_udc_errata *errata; 312 + const struct usba_ep_config *config; 313 + const int num_ep; 314 314 }; 315 315 316 316 struct usba_udc {
+2
drivers/usb/gadget/udc/core.c
··· 1297 1297 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); 1298 1298 1299 1299 usb_gadget_disconnect(udc->gadget); 1300 + if (udc->gadget->irq) 1301 + synchronize_irq(udc->gadget->irq); 1300 1302 udc->driver->unbind(udc->gadget); 1301 1303 usb_gadget_udc_stop(udc); 1302 1304
+14 -13
drivers/usb/gadget/udc/dummy_hcd.c
··· 187 187 USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), 188 188 189 189 /* and now some generic EPs so we have enough in multi config */ 190 - EP_INFO("ep3out", 190 + EP_INFO("ep-aout", 191 191 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 192 - EP_INFO("ep4in", 192 + EP_INFO("ep-bin", 193 193 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), 194 - EP_INFO("ep5out", 194 + EP_INFO("ep-cout", 195 195 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 196 - EP_INFO("ep6out", 196 + EP_INFO("ep-dout", 197 197 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 198 - EP_INFO("ep7in", 198 + EP_INFO("ep-ein", 199 199 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), 200 - EP_INFO("ep8out", 200 + EP_INFO("ep-fout", 201 201 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 202 - EP_INFO("ep9in", 202 + EP_INFO("ep-gin", 203 203 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), 204 - EP_INFO("ep10out", 204 + EP_INFO("ep-hout", 205 205 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 206 - EP_INFO("ep11out", 206 + EP_INFO("ep-iout", 207 207 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 208 - EP_INFO("ep12in", 208 + EP_INFO("ep-jin", 209 209 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), 210 - EP_INFO("ep13out", 210 + EP_INFO("ep-kout", 211 211 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 212 - EP_INFO("ep14in", 212 + EP_INFO("ep-lin", 213 213 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), 214 - EP_INFO("ep15out", 214 + EP_INFO("ep-mout", 215 215 USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), 216 216 217 217 #undef EP_INFO ··· 427 427 428 428 /* caller must hold lock */ 429 429 static void set_link_state(struct dummy_hcd *dum_hcd) 430 + __must_hold(&dum->lock) 430 431 { 431 432 struct dummy *dum = dum_hcd->dum; 432 433 unsigned int power_bit;
+2 -2
drivers/usb/gadget/udc/fsl_udc_core.c
··· 2440 2440 udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; 2441 2441 2442 2442 udc_controller->irq = platform_get_irq(pdev, 0); 2443 - if (!udc_controller->irq) { 2444 - ret = -ENODEV; 2443 + if (udc_controller->irq <= 0) { 2444 + ret = udc_controller->irq ? : -ENODEV; 2445 2445 goto err_iounmap; 2446 2446 } 2447 2447
-1
drivers/usb/gadget/udc/gr_udc.c
··· 48 48 #define DRIVER_DESC "Aeroflex Gaisler GRUSBDC USB Peripheral Controller" 49 49 50 50 static const char driver_name[] = DRIVER_NAME; 51 - static const char driver_desc[] = DRIVER_DESC; 52 51 53 52 #define gr_read32(x) (ioread32be((x))) 54 53 #define gr_write32(x, v) (iowrite32be((v), (x)))
+6 -5
drivers/usb/gadget/udc/lpc32xx_udc.c
··· 1614 1614 const struct usb_endpoint_descriptor *desc) 1615 1615 { 1616 1616 struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep); 1617 - struct lpc32xx_udc *udc = ep->udc; 1617 + struct lpc32xx_udc *udc; 1618 1618 u16 maxpacket; 1619 1619 u32 tmp; 1620 1620 unsigned long flags; 1621 1621 1622 1622 /* Verify EP data */ 1623 1623 if ((!_ep) || (!ep) || (!desc) || 1624 - (desc->bDescriptorType != USB_DT_ENDPOINT)) { 1625 - dev_dbg(udc->dev, "bad ep or descriptor\n"); 1624 + (desc->bDescriptorType != USB_DT_ENDPOINT)) 1626 1625 return -EINVAL; 1627 - } 1626 + 1627 + udc = ep->udc; 1628 1628 maxpacket = usb_endpoint_maxp(desc); 1629 1629 if ((maxpacket == 0) || (maxpacket > ep->maxpacket)) { 1630 1630 dev_dbg(udc->dev, "bad ep descriptor's packet size\n"); ··· 1872 1872 static int lpc32xx_ep_set_halt(struct usb_ep *_ep, int value) 1873 1873 { 1874 1874 struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep); 1875 - struct lpc32xx_udc *udc = ep->udc; 1875 + struct lpc32xx_udc *udc; 1876 1876 unsigned long flags; 1877 1877 1878 1878 if ((!ep) || (ep->hwep_num <= 1)) ··· 1882 1882 if (ep->is_in) 1883 1883 return -EAGAIN; 1884 1884 1885 + udc = ep->udc; 1885 1886 spin_lock_irqsave(&udc->lock, flags); 1886 1887 1887 1888 if (value == 1) {
+1 -1
drivers/usb/gadget/udc/m66592-udc.c
··· 1667 1667 1668 1668 err_add_udc: 1669 1669 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 1670 - 1670 + m66592->ep0_req = NULL; 1671 1671 clean_up3: 1672 1672 if (m66592->pdata->on_chip) { 1673 1673 clk_disable(m66592->clk);
+1 -1
drivers/usb/gadget/udc/max3420_udc.c
··· 901 901 } 902 902 903 903 set_current_state(TASK_RUNNING); 904 - dev_info(udc->dev, "SPI thread exiting"); 904 + dev_info(udc->dev, "SPI thread exiting\n"); 905 905 return 0; 906 906 } 907 907
+1 -1
drivers/usb/gadget/udc/mv_u3d_core.c
··· 1548 1548 delegate = true; 1549 1549 1550 1550 /* delegate USB standard requests to the gadget driver */ 1551 - if (delegate == true) { 1551 + if (delegate) { 1552 1552 /* USB requests handled by gadget */ 1553 1553 if (setup->wLength) { 1554 1554 /* DATA phase from gadget, STATUS phase from u3d */
+1 -1
drivers/usb/gadget/udc/net2272.c
··· 54 54 * 55 55 * If use_dma is disabled, pio will be used instead. 56 56 */ 57 - static bool use_dma = 0; 57 + static bool use_dma = false; 58 58 module_param(use_dma, bool, 0644); 59 59 60 60 /*
+1 -1
drivers/usb/gadget/udc/omap_udc.c
··· 2576 2576 case USB_ENDPOINT_XFER_INT: 2577 2577 ep->ep.caps.type_int = true; 2578 2578 break; 2579 - }; 2579 + } 2580 2580 2581 2581 if (addr & USB_DIR_IN) 2582 2582 ep->ep.caps.dir_in = true;
-4
drivers/usb/gadget/udc/s3c2410_udc.c
··· 251 251 static void s3c2410_udc_nuke(struct s3c2410_udc *udc, 252 252 struct s3c2410_ep *ep, int status) 253 253 { 254 - /* Sanity check */ 255 - if (&ep->queue == NULL) 256 - return; 257 - 258 254 while (!list_empty(&ep->queue)) { 259 255 struct s3c2410_request *req; 260 256 req = list_entry(ep->queue.next, struct s3c2410_request,
+140
drivers/usb/gadget/udc/tegra-xudc.c
··· 158 158 #define SSPX_CORE_CNT32_POLL_TBURST_MAX_MASK GENMASK(7, 0) 159 159 #define SSPX_CORE_CNT32_POLL_TBURST_MAX(x) ((x) & \ 160 160 SSPX_CORE_CNT32_POLL_TBURST_MAX_MASK) 161 + #define SSPX_CORE_CNT56 0x6fc 162 + #define SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX_MASK GENMASK(19, 0) 163 + #define SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX(x) ((x) & \ 164 + SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX_MASK) 165 + #define SSPX_CORE_CNT57 0x700 166 + #define SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX_MASK GENMASK(19, 0) 167 + #define SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX(x) ((x) & \ 168 + SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX_MASK) 169 + #define SSPX_CORE_CNT65 0x720 170 + #define SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID_MASK GENMASK(19, 0) 171 + #define SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID(x) ((x) & \ 172 + SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID_MASK) 173 + #define SSPX_CORE_CNT66 0x724 174 + #define SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID_MASK GENMASK(19, 0) 175 + #define SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID(x) ((x) & \ 176 + SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID_MASK) 177 + #define SSPX_CORE_CNT67 0x728 178 + #define SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID_MASK GENMASK(19, 0) 179 + #define SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID(x) ((x) & \ 180 + SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID_MASK) 181 + #define SSPX_CORE_CNT72 0x73c 182 + #define SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT_MASK GENMASK(19, 0) 183 + #define SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT(x) ((x) & \ 184 + SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT_MASK) 161 185 #define SSPX_CORE_PADCTL4 0x750 162 186 #define SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3_MASK GENMASK(19, 0) 163 187 #define SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3(x) ((x) & \ ··· 516 492 bool powergated; 517 493 518 494 struct usb_phy **usbphy; 495 + struct usb_phy *curr_usbphy; 519 496 struct notifier_block vbus_nb; 520 497 521 498 struct completion disconnect_complete; ··· 555 530 bool invalid_seq_num; 556 531 bool pls_quirk; 557 532 bool port_reset_quirk; 533 + bool port_speed_quirk; 558 534 bool has_ipfs; 559 535 }; 560 536 ··· 625 599 trb->control); 626 600 } 627 601 602 + static void tegra_xudc_limit_port_speed(struct tegra_xudc *xudc) 603 + { 604 + u32 val; 605 + 606 + /* limit port speed to gen 1 */ 607 + val = xudc_readl(xudc, SSPX_CORE_CNT56); 608 + val &= ~(SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX_MASK); 609 + val |= SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX(0x260); 610 + xudc_writel(xudc, val, SSPX_CORE_CNT56); 611 + 612 + val = xudc_readl(xudc, SSPX_CORE_CNT57); 613 + val &= ~(SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX_MASK); 614 + val |= SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX(0x6D6); 615 + xudc_writel(xudc, val, SSPX_CORE_CNT57); 616 + 617 + val = xudc_readl(xudc, SSPX_CORE_CNT65); 618 + val &= ~(SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID_MASK); 619 + val |= SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID(0x4B0); 620 + xudc_writel(xudc, val, SSPX_CORE_CNT66); 621 + 622 + val = xudc_readl(xudc, SSPX_CORE_CNT66); 623 + val &= ~(SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID_MASK); 624 + val |= SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID(0x4B0); 625 + xudc_writel(xudc, val, SSPX_CORE_CNT66); 626 + 627 + val = xudc_readl(xudc, SSPX_CORE_CNT67); 628 + val &= ~(SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID_MASK); 629 + val |= SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID(0x4B0); 630 + xudc_writel(xudc, val, SSPX_CORE_CNT67); 631 + 632 + val = xudc_readl(xudc, SSPX_CORE_CNT72); 633 + val &= ~(SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT_MASK); 634 + val |= SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT(0x10); 635 + xudc_writel(xudc, val, SSPX_CORE_CNT72); 636 + } 637 + 638 + static void tegra_xudc_restore_port_speed(struct tegra_xudc *xudc) 639 + { 640 + u32 val; 641 + 642 + /* restore port speed to gen2 */ 643 + val = xudc_readl(xudc, SSPX_CORE_CNT56); 644 + val &= ~(SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX_MASK); 645 + val |= SSPX_CORE_CNT56_SCD_BIT0_TRPT_MAX(0x438); 646 + xudc_writel(xudc, val, SSPX_CORE_CNT56); 647 + 648 + val = xudc_readl(xudc, SSPX_CORE_CNT57); 649 + val &= ~(SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX_MASK); 650 + val |= SSPX_CORE_CNT57_SCD_BIT1_TRPT_MAX(0x528); 651 + xudc_writel(xudc, val, SSPX_CORE_CNT57); 652 + 653 + val = xudc_readl(xudc, SSPX_CORE_CNT65); 654 + val &= ~(SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID_MASK); 655 + val |= SSPX_CORE_CNT65_TX_SCD_END_TRPT_MID(0xE10); 656 + xudc_writel(xudc, val, SSPX_CORE_CNT66); 657 + 658 + val = xudc_readl(xudc, SSPX_CORE_CNT66); 659 + val &= ~(SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID_MASK); 660 + val |= SSPX_CORE_CNT66_TX_SCD_BIT0_TRPT_MID(0x348); 661 + xudc_writel(xudc, val, SSPX_CORE_CNT66); 662 + 663 + val = xudc_readl(xudc, SSPX_CORE_CNT67); 664 + val &= ~(SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID_MASK); 665 + val |= SSPX_CORE_CNT67_TX_SCD_BIT1_TRPT_MID(0x5a0); 666 + xudc_writel(xudc, val, SSPX_CORE_CNT67); 667 + 668 + val = xudc_readl(xudc, SSPX_CORE_CNT72); 669 + val &= ~(SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT_MASK); 670 + val |= SSPX_CORE_CNT72_SCD_LFPS_TIMEOUT(0x1c21); 671 + xudc_writel(xudc, val, SSPX_CORE_CNT72); 672 + } 673 + 628 674 static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc) 629 675 { 630 676 int err; ··· 728 630 connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS); 729 631 730 632 reinit_completion(&xudc->disconnect_complete); 633 + 634 + if (xudc->soc->port_speed_quirk) 635 + tegra_xudc_restore_port_speed(xudc); 731 636 732 637 phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG, USB_ROLE_NONE); 733 638 ··· 820 719 if (!xudc->suspended && phy_index != -1) { 821 720 xudc->curr_utmi_phy = xudc->utmi_phy[phy_index]; 822 721 xudc->curr_usb3_phy = xudc->usb3_phy[phy_index]; 722 + xudc->curr_usbphy = usbphy; 823 723 schedule_work(&xudc->usb_role_sw_work); 824 724 } 825 725 ··· 2144 2042 return 0; 2145 2043 } 2146 2044 2045 + static int tegra_xudc_gadget_vbus_draw(struct usb_gadget *gadget, 2046 + unsigned int m_a) 2047 + { 2048 + int ret = 0; 2049 + struct tegra_xudc *xudc = to_xudc(gadget); 2050 + 2051 + dev_dbg(xudc->dev, "%s: %u mA\n", __func__, m_a); 2052 + 2053 + if (xudc->curr_usbphy->chg_type == SDP_TYPE) 2054 + ret = usb_phy_set_power(xudc->curr_usbphy, m_a); 2055 + 2056 + return ret; 2057 + } 2058 + 2147 2059 static int tegra_xudc_set_selfpowered(struct usb_gadget *gadget, int is_on) 2148 2060 { 2149 2061 struct tegra_xudc *xudc = to_xudc(gadget); ··· 2174 2058 .pullup = tegra_xudc_gadget_pullup, 2175 2059 .udc_start = tegra_xudc_gadget_start, 2176 2060 .udc_stop = tegra_xudc_gadget_stop, 2061 + .vbus_draw = tegra_xudc_gadget_vbus_draw, 2177 2062 .set_selfpowered = tegra_xudc_set_selfpowered, 2178 2063 }; 2179 2064 ··· 3391 3274 xudc_writel(xudc, val, BLCG); 3392 3275 } 3393 3276 3277 + if (xudc->soc->port_speed_quirk) 3278 + tegra_xudc_limit_port_speed(xudc); 3279 + 3394 3280 /* Set a reasonable U3 exit timer value. */ 3395 3281 val = xudc_readl(xudc, SSPX_CORE_PADCTL4); 3396 3282 val &= ~(SSPX_CORE_PADCTL4_RXDAT_VLD_TIMEOUT_U3_MASK); ··· 3626 3506 .invalid_seq_num = true, 3627 3507 .pls_quirk = true, 3628 3508 .port_reset_quirk = true, 3509 + .port_speed_quirk = false, 3629 3510 .has_ipfs = true, 3630 3511 }; 3631 3512 ··· 3640 3519 .invalid_seq_num = false, 3641 3520 .pls_quirk = false, 3642 3521 .port_reset_quirk = false, 3522 + .port_speed_quirk = false, 3523 + .has_ipfs = false, 3524 + }; 3525 + 3526 + static struct tegra_xudc_soc tegra194_xudc_soc_data = { 3527 + .clock_names = tegra186_xudc_clock_names, 3528 + .num_clks = ARRAY_SIZE(tegra186_xudc_clock_names), 3529 + .num_phys = 4, 3530 + .u1_enable = true, 3531 + .u2_enable = true, 3532 + .lpm_enable = true, 3533 + .invalid_seq_num = false, 3534 + .pls_quirk = false, 3535 + .port_reset_quirk = false, 3536 + .port_speed_quirk = true, 3643 3537 .has_ipfs = false, 3644 3538 }; 3645 3539 ··· 3666 3530 { 3667 3531 .compatible = "nvidia,tegra186-xudc", 3668 3532 .data = &tegra186_xudc_soc_data 3533 + }, 3534 + { 3535 + .compatible = "nvidia,tegra194-xudc", 3536 + .data = &tegra194_xudc_soc_data 3669 3537 }, 3670 3538 { } 3671 3539 };
+1
drivers/usb/gadget/udc/udc-xilinx.c
··· 1732 1732 * Process setup packet and delegate to gadget layer. 1733 1733 */ 1734 1734 static void xudc_handle_setup(struct xusb_udc *udc) 1735 + __must_hold(&udc->lock) 1735 1736 { 1736 1737 struct xusb_ep *ep0 = &udc->ep[0]; 1737 1738 struct usb_ctrlrequest setup;
+24
drivers/usb/gadget/usbstring.c
··· 65 65 return buf [0]; 66 66 } 67 67 EXPORT_SYMBOL_GPL(usb_gadget_get_string); 68 + 69 + /** 70 + * usb_validate_langid - validate usb language identifiers 71 + * @lang: usb language identifier 72 + * 73 + * Returns true for valid language identifier, otherwise false. 74 + */ 75 + bool usb_validate_langid(u16 langid) 76 + { 77 + u16 primary_lang = langid & 0x3ff; /* bit [9:0] */ 78 + u16 sub_lang = langid >> 10; /* bit [15:10] */ 79 + 80 + switch (primary_lang) { 81 + case 0: 82 + case 0x62 ... 0xfe: 83 + case 0x100 ... 0x3ff: 84 + return false; 85 + } 86 + if (!sub_lang) 87 + return false; 88 + 89 + return true; 90 + } 91 + EXPORT_SYMBOL_GPL(usb_validate_langid);
+29
drivers/usb/host/Kconfig
··· 40 40 config USB_XHCI_PCI 41 41 tristate 42 42 depends on USB_PCI 43 + depends on USB_XHCI_PCI_RENESAS || !USB_XHCI_PCI_RENESAS 43 44 default y 45 + 46 + config USB_XHCI_PCI_RENESAS 47 + tristate "Support for additional Renesas xHCI controller with firwmare" 48 + ---help--- 49 + Say 'Y' to enable the support for the Renesas xHCI controller with 50 + firwmare. Make sure you have the firwmare for the device and 51 + installed on your system for this device to work. 52 + If unsure, say 'N'. 44 53 45 54 config USB_XHCI_PLATFORM 46 55 tristate "Generic xHCI driver for a platform device" ··· 105 96 found in NVIDIA Tegra124 and later SoCs. 106 97 107 98 endif # USB_XHCI_HCD 99 + 100 + config USB_EHCI_BRCMSTB 101 + tristate 102 + 103 + config USB_BRCMSTB 104 + tristate "Broadcom STB USB support" 105 + depends on (ARCH_BRCMSTB && PHY_BRCM_USB) || COMPILE_TEST 106 + select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD 107 + select USB_EHCI_BRCMSTB if USB_EHCI_HCD 108 + select USB_XHCI_PLATFORM if USB_XHCI_HCD 109 + help 110 + Enables support for XHCI, EHCI and OHCI host controllers 111 + found in Broadcom STB SoC's. 112 + 113 + To compile these drivers as modules, choose M here: the 114 + modules will be called ohci-platform.ko, ehci-brcm.ko and 115 + xhci-plat-hcd.ko 116 + 117 + Disabling this will keep the controllers and corresponding 118 + PHYs powered down. 108 119 109 120 config USB_EHCI_HCD 110 121 tristate "EHCI HCD (USB 2.0) support"
+2
drivers/usb/host/Makefile
··· 49 49 obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o 50 50 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o 51 51 obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o 52 + obj-$(CONFIG_USB_EHCI_BRCMSTB) += ehci-brcm.o 52 53 53 54 obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o 54 55 obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o ··· 72 71 obj-$(CONFIG_USB_FHCI_HCD) += fhci.o 73 72 obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o 74 73 obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o 74 + obj-$(CONFIG_USB_XHCI_PCI_RENESAS) += xhci-pci-renesas.o 75 75 obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o 76 76 obj-$(CONFIG_USB_XHCI_HISTB) += xhci-histb.o 77 77 obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
+280
drivers/usb/host/ehci-brcm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2020, Broadcom */ 3 + 4 + #include <linux/clk.h> 5 + #include <linux/dma-mapping.h> 6 + #include <linux/err.h> 7 + #include <linux/kernel.h> 8 + #include <linux/io.h> 9 + #include <linux/module.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/usb.h> 12 + #include <linux/usb/hcd.h> 13 + #include <linux/iopoll.h> 14 + 15 + #include "ehci.h" 16 + 17 + #define hcd_to_ehci_priv(h) ((struct brcm_priv *)hcd_to_ehci(h)->priv) 18 + 19 + struct brcm_priv { 20 + struct clk *clk; 21 + }; 22 + 23 + /* 24 + * ehci_brcm_wait_for_sof 25 + * Wait for start of next microframe, then wait extra delay microseconds 26 + */ 27 + static inline void ehci_brcm_wait_for_sof(struct ehci_hcd *ehci, u32 delay) 28 + { 29 + u32 frame_idx = ehci_readl(ehci, &ehci->regs->frame_index); 30 + u32 val; 31 + int res; 32 + 33 + /* Wait for next microframe (every 125 usecs) */ 34 + res = readl_relaxed_poll_timeout(&ehci->regs->frame_index, val, 35 + val != frame_idx, 1, 130); 36 + if (res) 37 + ehci_err(ehci, "Error waiting for SOF\n"); 38 + udelay(delay); 39 + } 40 + 41 + /* 42 + * ehci_brcm_hub_control 43 + * The EHCI controller has a bug where it can violate the SOF 44 + * interval between the first two SOF's transmitted after resume 45 + * if the resume occurs near the end of the microframe. This causees 46 + * the controller to detect babble on the suspended port and 47 + * will eventually cause the controller to reset the port. 48 + * The fix is to Intercept the echi-hcd request to complete RESUME and 49 + * align it to the start of the next microframe. 50 + * See SWLINUX-1909 for more details 51 + */ 52 + static int ehci_brcm_hub_control( 53 + struct usb_hcd *hcd, 54 + u16 typeReq, 55 + u16 wValue, 56 + u16 wIndex, 57 + char *buf, 58 + u16 wLength) 59 + { 60 + struct ehci_hcd *ehci = hcd_to_ehci(hcd); 61 + int ports = HCS_N_PORTS(ehci->hcs_params); 62 + u32 __iomem *status_reg; 63 + unsigned long flags; 64 + int retval, irq_disabled = 0; 65 + 66 + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; 67 + 68 + /* 69 + * RESUME is cleared when GetPortStatus() is called 20ms after start 70 + * of RESUME 71 + */ 72 + if ((typeReq == GetPortStatus) && 73 + (wIndex && wIndex <= ports) && 74 + ehci->reset_done[wIndex-1] && 75 + time_after_eq(jiffies, ehci->reset_done[wIndex-1]) && 76 + (ehci_readl(ehci, status_reg) & PORT_RESUME)) { 77 + 78 + /* 79 + * to make sure we are not interrupted until RESUME bit 80 + * is cleared, disable interrupts on current CPU 81 + */ 82 + ehci_dbg(ehci, "SOF alignment workaround\n"); 83 + irq_disabled = 1; 84 + local_irq_save(flags); 85 + ehci_brcm_wait_for_sof(ehci, 5); 86 + } 87 + retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); 88 + if (irq_disabled) 89 + local_irq_restore(flags); 90 + return retval; 91 + } 92 + 93 + static int ehci_brcm_reset(struct usb_hcd *hcd) 94 + { 95 + struct ehci_hcd *ehci = hcd_to_ehci(hcd); 96 + int len; 97 + 98 + ehci->big_endian_mmio = 1; 99 + 100 + ehci->caps = (void __iomem *)hcd->regs; 101 + len = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); 102 + ehci->regs = (void __iomem *)(hcd->regs + len); 103 + 104 + /* This fixes the lockup during reboot due to prior interrupts */ 105 + ehci_writel(ehci, CMD_RESET, &ehci->regs->command); 106 + mdelay(10); 107 + 108 + /* 109 + * SWLINUX-1705: Avoid OUT packet underflows during high memory 110 + * bus usage 111 + * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 @ 0x90 112 + */ 113 + ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]); 114 + ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]); 115 + 116 + return ehci_setup(hcd); 117 + } 118 + 119 + static struct hc_driver __read_mostly ehci_brcm_hc_driver; 120 + 121 + static const struct ehci_driver_overrides brcm_overrides __initconst = { 122 + .reset = ehci_brcm_reset, 123 + .extra_priv_size = sizeof(struct brcm_priv), 124 + }; 125 + 126 + static int ehci_brcm_probe(struct platform_device *pdev) 127 + { 128 + struct device *dev = &pdev->dev; 129 + struct resource *res_mem; 130 + struct brcm_priv *priv; 131 + struct usb_hcd *hcd; 132 + int irq; 133 + int err; 134 + 135 + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 136 + if (err) 137 + return err; 138 + 139 + irq = platform_get_irq(pdev, 0); 140 + if (irq <= 0) 141 + return irq ? irq : -EINVAL; 142 + 143 + /* Hook the hub control routine to work around a bug */ 144 + ehci_brcm_hc_driver.hub_control = ehci_brcm_hub_control; 145 + 146 + /* initialize hcd */ 147 + hcd = usb_create_hcd(&ehci_brcm_hc_driver, dev, dev_name(dev)); 148 + if (!hcd) 149 + return -ENOMEM; 150 + 151 + platform_set_drvdata(pdev, hcd); 152 + priv = hcd_to_ehci_priv(hcd); 153 + 154 + priv->clk = devm_clk_get_optional(dev, NULL); 155 + if (IS_ERR(priv->clk)) { 156 + err = PTR_ERR(priv->clk); 157 + goto err_hcd; 158 + } 159 + 160 + err = clk_prepare_enable(priv->clk); 161 + if (err) 162 + goto err_hcd; 163 + 164 + hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mem); 165 + if (IS_ERR(hcd->regs)) { 166 + err = PTR_ERR(hcd->regs); 167 + goto err_clk; 168 + } 169 + hcd->rsrc_start = res_mem->start; 170 + hcd->rsrc_len = resource_size(res_mem); 171 + err = usb_add_hcd(hcd, irq, IRQF_SHARED); 172 + if (err) 173 + goto err_clk; 174 + 175 + device_wakeup_enable(hcd->self.controller); 176 + device_enable_async_suspend(hcd->self.controller); 177 + 178 + return 0; 179 + 180 + err_clk: 181 + clk_disable_unprepare(priv->clk); 182 + err_hcd: 183 + usb_put_hcd(hcd); 184 + 185 + return err; 186 + } 187 + 188 + static int ehci_brcm_remove(struct platform_device *dev) 189 + { 190 + struct usb_hcd *hcd = platform_get_drvdata(dev); 191 + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); 192 + 193 + usb_remove_hcd(hcd); 194 + clk_disable_unprepare(priv->clk); 195 + usb_put_hcd(hcd); 196 + return 0; 197 + } 198 + 199 + static int __maybe_unused ehci_brcm_suspend(struct device *dev) 200 + { 201 + int ret; 202 + struct usb_hcd *hcd = dev_get_drvdata(dev); 203 + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); 204 + bool do_wakeup = device_may_wakeup(dev); 205 + 206 + ret = ehci_suspend(hcd, do_wakeup); 207 + if (ret) 208 + return ret; 209 + clk_disable_unprepare(priv->clk); 210 + return 0; 211 + } 212 + 213 + static int __maybe_unused ehci_brcm_resume(struct device *dev) 214 + { 215 + struct usb_hcd *hcd = dev_get_drvdata(dev); 216 + struct ehci_hcd *ehci = hcd_to_ehci(hcd); 217 + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); 218 + int err; 219 + 220 + err = clk_prepare_enable(priv->clk); 221 + if (err) 222 + return err; 223 + /* 224 + * SWLINUX-1705: Avoid OUT packet underflows during high memory 225 + * bus usage 226 + * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 227 + * @ 0x90 228 + */ 229 + ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]); 230 + ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]); 231 + 232 + ehci_resume(hcd, false); 233 + 234 + pm_runtime_disable(dev); 235 + pm_runtime_set_active(dev); 236 + pm_runtime_enable(dev); 237 + 238 + return 0; 239 + } 240 + 241 + static SIMPLE_DEV_PM_OPS(ehci_brcm_pm_ops, ehci_brcm_suspend, 242 + ehci_brcm_resume); 243 + 244 + static const struct of_device_id brcm_ehci_of_match[] = { 245 + { .compatible = "brcm,ehci-brcm-v2", }, 246 + { .compatible = "brcm,bcm7445-ehci", }, 247 + {} 248 + }; 249 + 250 + static struct platform_driver ehci_brcm_driver = { 251 + .probe = ehci_brcm_probe, 252 + .remove = ehci_brcm_remove, 253 + .shutdown = usb_hcd_platform_shutdown, 254 + .driver = { 255 + .name = "ehci-brcm", 256 + .pm = &ehci_brcm_pm_ops, 257 + .of_match_table = brcm_ehci_of_match, 258 + } 259 + }; 260 + 261 + static int __init ehci_brcm_init(void) 262 + { 263 + if (usb_disabled()) 264 + return -ENODEV; 265 + 266 + ehci_init_driver(&ehci_brcm_hc_driver, &brcm_overrides); 267 + return platform_driver_register(&ehci_brcm_driver); 268 + } 269 + module_init(ehci_brcm_init); 270 + 271 + static void __exit ehci_brcm_exit(void) 272 + { 273 + platform_driver_unregister(&ehci_brcm_driver); 274 + } 275 + module_exit(ehci_brcm_exit); 276 + 277 + MODULE_ALIAS("platform:ehci-brcm"); 278 + MODULE_DESCRIPTION("EHCI Broadcom STB driver"); 279 + MODULE_AUTHOR("Al Cooper"); 280 + MODULE_LICENSE("GPL");
+1 -1
drivers/usb/host/ehci-fsl.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc. 3 3 * Copyright (c) 2005 MontaVista Software 4 4 */
+4 -8
drivers/usb/host/ehci-mv.c
··· 108 108 struct ehci_hcd *ehci; 109 109 struct ehci_hcd_mv *ehci_mv; 110 110 struct resource *r; 111 - int retval = -ENODEV; 111 + int retval; 112 112 u32 offset; 113 113 u32 status; 114 114 ··· 143 143 goto err_put_hcd; 144 144 } 145 145 146 - 147 - 148 146 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 149 147 ehci_mv->base = devm_ioremap_resource(&pdev->dev, r); 150 148 if (IS_ERR(ehci_mv->base)) { ··· 166 168 hcd->rsrc_len = resource_size(r); 167 169 hcd->regs = ehci_mv->op_regs; 168 170 169 - hcd->irq = platform_get_irq(pdev, 0); 170 - if (!hcd->irq) { 171 - dev_err(&pdev->dev, "Cannot get irq."); 172 - retval = -ENODEV; 171 + retval = platform_get_irq(pdev, 0); 172 + if (retval < 0) 173 173 goto err_disable_clk; 174 - } 174 + hcd->irq = retval; 175 175 176 176 ehci = hcd_to_ehci(hcd); 177 177 ehci->caps = (struct ehci_caps __iomem *) ehci_mv->cap_regs;
+8 -7
drivers/usb/host/ehci-mxc.c
··· 36 36 37 37 static int ehci_mxc_drv_probe(struct platform_device *pdev) 38 38 { 39 - struct mxc_usbh_platform_data *pdata = dev_get_platdata(&pdev->dev); 39 + struct device *dev = &pdev->dev; 40 + struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev); 40 41 struct usb_hcd *hcd; 41 42 struct resource *res; 42 43 int irq, ret; 43 44 struct ehci_mxc_priv *priv; 44 - struct device *dev = &pdev->dev; 45 45 struct ehci_hcd *ehci; 46 46 47 47 if (!pdata) { ··· 50 50 } 51 51 52 52 irq = platform_get_irq(pdev, 0); 53 + if (irq < 0) 54 + return irq; 53 55 54 56 hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); 55 57 if (!hcd) 56 58 return -ENOMEM; 57 59 58 60 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 59 - hcd->regs = devm_ioremap_resource(&pdev->dev, res); 61 + hcd->regs = devm_ioremap_resource(dev, res); 60 62 if (IS_ERR(hcd->regs)) { 61 63 ret = PTR_ERR(hcd->regs); 62 64 goto err_alloc; ··· 71 69 priv = (struct ehci_mxc_priv *) ehci->priv; 72 70 73 71 /* enable clocks */ 74 - priv->usbclk = devm_clk_get(&pdev->dev, "ipg"); 72 + priv->usbclk = devm_clk_get(dev, "ipg"); 75 73 if (IS_ERR(priv->usbclk)) { 76 74 ret = PTR_ERR(priv->usbclk); 77 75 goto err_alloc; 78 76 } 79 77 clk_prepare_enable(priv->usbclk); 80 78 81 - priv->ahbclk = devm_clk_get(&pdev->dev, "ahb"); 79 + priv->ahbclk = devm_clk_get(dev, "ahb"); 82 80 if (IS_ERR(priv->ahbclk)) { 83 81 ret = PTR_ERR(priv->ahbclk); 84 82 goto err_clk_ahb; ··· 86 84 clk_prepare_enable(priv->ahbclk); 87 85 88 86 /* "dr" device has its own clock on i.MX51 */ 89 - priv->phyclk = devm_clk_get(&pdev->dev, "phy"); 87 + priv->phyclk = devm_clk_get(dev, "phy"); 90 88 if (IS_ERR(priv->phyclk)) 91 89 priv->phyclk = NULL; 92 90 if (priv->phyclk) 93 91 clk_prepare_enable(priv->phyclk); 94 - 95 92 96 93 /* call platform specific init function */ 97 94 if (pdata->init) {
+2 -4
drivers/usb/host/ehci-pci.c
··· 360 360 { 361 361 if (is_bypassed_id(pdev)) 362 362 return -ENODEV; 363 - return usb_hcd_pci_probe(pdev, id); 363 + return usb_hcd_pci_probe(pdev, id, &ehci_pci_hc_driver); 364 364 } 365 365 366 366 static void ehci_pci_remove(struct pci_dev *pdev) 367 367 { 368 368 pci_clear_mwi(pdev); 369 - usb_hcd_pci_remove(pdev); 369 + usb_hcd_pci_remove(pdev); 370 370 } 371 371 372 372 /* PCI driver selection metadata; PCI hotplugging uses this */ 373 373 static const struct pci_device_id pci_ids [] = { { 374 374 /* handle any USB 2.0 EHCI controller */ 375 375 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), 376 - .driver_data = (unsigned long) &ehci_pci_hc_driver, 377 376 }, { 378 377 PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST), 379 - .driver_data = (unsigned long) &ehci_pci_hc_driver, 380 378 }, 381 379 { /* end: all zeroes */ } 382 380 };
+4
drivers/usb/host/ehci-platform.c
··· 455 455 456 456 ehci_resume(hcd, priv->reset_on_resume); 457 457 458 + pm_runtime_disable(dev); 459 + pm_runtime_set_active(dev); 460 + pm_runtime_enable(dev); 461 + 458 462 if (priv->quirk_poll) 459 463 quirk_poll_init(priv); 460 464
-1
drivers/usb/host/ehci-tegra.c
··· 480 480 481 481 irq = platform_get_irq(pdev, 0); 482 482 if (!irq) { 483 - dev_err(&pdev->dev, "Failed to get IRQ\n"); 484 483 err = -ENODEV; 485 484 goto cleanup_phy; 486 485 }
+1 -1
drivers/usb/host/ehci.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Copyright (c) 2001-2002 by David Brownell 4 4 */
+1 -1
drivers/usb/host/fhci.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Freescale QUICC Engine USB Host Controller Driver 4 4 *
+1 -1
drivers/usb/host/imx21-hcd.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Macros and prototypes for i.MX21 4 4 *
+6 -3
drivers/usb/host/ohci-pci.c
··· 277 277 static const struct pci_device_id pci_ids[] = { { 278 278 /* handle any USB OHCI controller */ 279 279 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), 280 - .driver_data = (unsigned long) &ohci_pci_hc_driver, 281 280 }, { 282 281 /* The device in the ConneXT I/O hub has no class reg */ 283 282 PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI), 284 - .driver_data = (unsigned long) &ohci_pci_hc_driver, 285 283 }, { /* end: all zeroes */ } 286 284 }; 287 285 MODULE_DEVICE_TABLE (pci, pci_ids); 286 + 287 + static int ohci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 288 + { 289 + return usb_hcd_pci_probe(dev, id, &ohci_pci_hc_driver); 290 + } 288 291 289 292 /* pci driver glue; this is a "new style" PCI driver module */ 290 293 static struct pci_driver ohci_pci_driver = { 291 294 .name = hcd_name, 292 295 .id_table = pci_ids, 293 296 294 - .probe = usb_hcd_pci_probe, 297 + .probe = ohci_pci_probe, 295 298 .remove = usb_hcd_pci_remove, 296 299 .shutdown = usb_hcd_pci_shutdown, 297 300
+5
drivers/usb/host/ohci-platform.c
··· 299 299 } 300 300 301 301 ohci_resume(hcd, false); 302 + 303 + pm_runtime_disable(dev); 304 + pm_runtime_set_active(dev); 305 + pm_runtime_enable(dev); 306 + 302 307 return 0; 303 308 } 304 309 #endif /* CONFIG_PM_SLEEP */
+4 -3
drivers/usb/host/ohci-sm501.c
··· 157 157 * the call to usb_hcd_setup_local_mem() below does just that. 158 158 */ 159 159 160 - if (usb_hcd_setup_local_mem(hcd, mem->start, 161 - mem->start - mem->parent->start, 162 - resource_size(mem)) < 0) 160 + retval = usb_hcd_setup_local_mem(hcd, mem->start, 161 + mem->start - mem->parent->start, 162 + resource_size(mem)); 163 + if (retval < 0) 163 164 goto err5; 164 165 retval = usb_add_hcd(hcd, irq, IRQF_SHARED); 165 166 if (retval)
+1 -1
drivers/usb/host/ohci.h
··· 1 - // SPDX-License-Identifier: GPL-1.0+ 1 + /* SPDX-License-Identifier: GPL-1.0+ */ 2 2 /* 3 3 * OHCI HCD (Host Controller Driver) for USB. 4 4 *
+4 -4
drivers/usb/host/pci-quirks.c
··· 208 208 { 209 209 unsigned long flags; 210 210 struct amd_chipset_info info; 211 - info.need_pll_quirk = 0; 211 + info.need_pll_quirk = false; 212 212 213 213 spin_lock_irqsave(&amd_lock, flags); 214 214 ··· 232 232 case AMD_CHIPSET_SB800: 233 233 case AMD_CHIPSET_HUDSON2: 234 234 case AMD_CHIPSET_BOLTON: 235 - info.need_pll_quirk = 1; 235 + info.need_pll_quirk = true; 236 236 break; 237 237 default: 238 - info.need_pll_quirk = 0; 238 + info.need_pll_quirk = false; 239 239 break; 240 240 } 241 241 ··· 532 532 amd_chipset.nb_type = 0; 533 533 memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type)); 534 534 amd_chipset.isoc_reqs = 0; 535 - amd_chipset.need_pll_quirk = 0; 535 + amd_chipset.need_pll_quirk = false; 536 536 537 537 spin_unlock_irqrestore(&amd_lock, flags); 538 538
+1 -1
drivers/usb/host/r8a66597.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * R8A66597 HCD (Host Controller Driver) 4 4 *
-10
drivers/usb/host/u132-hcd.c
··· 81 81 static struct mutex u132_module_lock; 82 82 static int u132_exiting; 83 83 static int u132_instances; 84 - static struct list_head u132_static_list; 85 84 /* 86 85 * end of the global variables protected by u132_module_lock 87 86 */ ··· 176 177 }; 177 178 struct u132 { 178 179 struct kref kref; 179 - struct list_head u132_list; 180 180 struct mutex sw_lock; 181 181 struct mutex scheduler_lock; 182 182 struct u132_platform_data *board; ··· 252 254 struct usb_hcd *hcd = u132_to_hcd(u132); 253 255 u132->going += 1; 254 256 mutex_lock(&u132_module_lock); 255 - list_del_init(&u132->u132_list); 256 257 u132_instances -= 1; 257 258 mutex_unlock(&u132_module_lock); 258 259 dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" ··· 3086 3089 retval = 0; 3087 3090 hcd->rsrc_start = 0; 3088 3091 mutex_lock(&u132_module_lock); 3089 - list_add_tail(&u132->u132_list, &u132_static_list); 3090 3092 u132->sequence_num = ++u132_instances; 3091 3093 mutex_unlock(&u132_module_lock); 3092 3094 u132_u132_init_kref(u132); ··· 3188 3192 static int __init u132_hcd_init(void) 3189 3193 { 3190 3194 int retval; 3191 - INIT_LIST_HEAD(&u132_static_list); 3192 3195 u132_instances = 0; 3193 3196 u132_exiting = 0; 3194 3197 mutex_init(&u132_module_lock); ··· 3208 3213 module_init(u132_hcd_init); 3209 3214 static void __exit u132_hcd_exit(void) 3210 3215 { 3211 - struct u132 *u132; 3212 - struct u132 *temp; 3213 3216 mutex_lock(&u132_module_lock); 3214 3217 u132_exiting += 1; 3215 3218 mutex_unlock(&u132_module_lock); 3216 - list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { 3217 - platform_device_unregister(u132->platform_dev); 3218 - } 3219 3219 platform_driver_unregister(&u132_platform_driver); 3220 3220 printk(KERN_INFO "u132-hcd driver deregistered\n"); 3221 3221 wait_event(u132_hcd_wait, u132_instances == 0);
+6 -2
drivers/usb/host/uhci-pci.c
··· 287 287 static const struct pci_device_id uhci_pci_ids[] = { { 288 288 /* handle any USB UHCI controller */ 289 289 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), 290 - .driver_data = (unsigned long) &uhci_driver, 291 290 }, { /* end: all zeroes */ } 292 291 }; 293 292 294 293 MODULE_DEVICE_TABLE(pci, uhci_pci_ids); 295 294 295 + static int uhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 296 + { 297 + return usb_hcd_pci_probe(dev, id, &uhci_driver); 298 + } 299 + 296 300 static struct pci_driver uhci_pci_driver = { 297 301 .name = hcd_name, 298 302 .id_table = uhci_pci_ids, 299 303 300 - .probe = usb_hcd_pci_probe, 304 + .probe = uhci_pci_probe, 301 305 .remove = usb_hcd_pci_remove, 302 306 .shutdown = uhci_shutdown, 303 307
+1 -1
drivers/usb/host/xhci-debugfs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * xhci-debugfs.h - xHCI debugfs interface 4 4 *
+1 -1
drivers/usb/host/xhci-ext-caps.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * xHCI host controller driver 4 4 *
+1 -1
drivers/usb/host/xhci-mtk.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Copyright (c) 2015 MediaTek Inc. 4 4 * Author:
+1 -1
drivers/usb/host/xhci-mvebu.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Copyright (C) 2014 Marvell 4 4 *
+645
drivers/usb/host/xhci-pci-renesas.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2019-2020 Linaro Limited */ 3 + 4 + #include <linux/acpi.h> 5 + #include <linux/firmware.h> 6 + #include <linux/module.h> 7 + #include <linux/pci.h> 8 + #include <linux/slab.h> 9 + #include <asm/unaligned.h> 10 + 11 + #include "xhci.h" 12 + #include "xhci-trace.h" 13 + #include "xhci-pci.h" 14 + 15 + #define RENESAS_FW_VERSION 0x6C 16 + #define RENESAS_ROM_CONFIG 0xF0 17 + #define RENESAS_FW_STATUS 0xF4 18 + #define RENESAS_FW_STATUS_MSB 0xF5 19 + #define RENESAS_ROM_STATUS 0xF6 20 + #define RENESAS_ROM_STATUS_MSB 0xF7 21 + #define RENESAS_DATA0 0xF8 22 + #define RENESAS_DATA1 0xFC 23 + 24 + #define RENESAS_FW_VERSION_FIELD GENMASK(23, 7) 25 + #define RENESAS_FW_VERSION_OFFSET 8 26 + 27 + #define RENESAS_FW_STATUS_DOWNLOAD_ENABLE BIT(0) 28 + #define RENESAS_FW_STATUS_LOCK BIT(1) 29 + #define RENESAS_FW_STATUS_RESULT GENMASK(6, 4) 30 + #define RENESAS_FW_STATUS_INVALID 0 31 + #define RENESAS_FW_STATUS_SUCCESS BIT(4) 32 + #define RENESAS_FW_STATUS_ERROR BIT(5) 33 + #define RENESAS_FW_STATUS_SET_DATA0 BIT(8) 34 + #define RENESAS_FW_STATUS_SET_DATA1 BIT(9) 35 + 36 + #define RENESAS_ROM_STATUS_ACCESS BIT(0) 37 + #define RENESAS_ROM_STATUS_ERASE BIT(1) 38 + #define RENESAS_ROM_STATUS_RELOAD BIT(2) 39 + #define RENESAS_ROM_STATUS_RESULT GENMASK(6, 4) 40 + #define RENESAS_ROM_STATUS_NO_RESULT 0 41 + #define RENESAS_ROM_STATUS_SUCCESS BIT(4) 42 + #define RENESAS_ROM_STATUS_ERROR BIT(5) 43 + #define RENESAS_ROM_STATUS_SET_DATA0 BIT(8) 44 + #define RENESAS_ROM_STATUS_SET_DATA1 BIT(9) 45 + #define RENESAS_ROM_STATUS_ROM_EXISTS BIT(15) 46 + 47 + #define RENESAS_ROM_ERASE_MAGIC 0x5A65726F 48 + #define RENESAS_ROM_WRITE_MAGIC 0x53524F4D 49 + 50 + #define RENESAS_RETRY 10000 51 + #define RENESAS_DELAY 10 52 + 53 + #define ROM_VALID_01 0x2013 54 + #define ROM_VALID_02 0x2026 55 + 56 + static int renesas_verify_fw_version(struct pci_dev *pdev, u32 version) 57 + { 58 + switch (version) { 59 + case ROM_VALID_01: 60 + case ROM_VALID_02: 61 + return 0; 62 + } 63 + dev_err(&pdev->dev, "FW has invalid version :%d\n", version); 64 + return -EINVAL; 65 + } 66 + 67 + static int renesas_fw_download_image(struct pci_dev *dev, 68 + const u32 *fw, size_t step, bool rom) 69 + { 70 + size_t i; 71 + int err; 72 + u8 fw_status; 73 + bool data0_or_data1; 74 + u32 status_reg; 75 + 76 + if (rom) 77 + status_reg = RENESAS_ROM_STATUS_MSB; 78 + else 79 + status_reg = RENESAS_FW_STATUS_MSB; 80 + 81 + /* 82 + * The hardware does alternate between two 32-bit pages. 83 + * (This is because each row of the firmware is 8 bytes). 84 + * 85 + * for even steps we use DATA0, for odd steps DATA1. 86 + */ 87 + data0_or_data1 = (step & 1) == 1; 88 + 89 + /* step+1. Read "Set DATAX" and confirm it is cleared. */ 90 + for (i = 0; i < RENESAS_RETRY; i++) { 91 + err = pci_read_config_byte(dev, status_reg, &fw_status); 92 + if (err) { 93 + dev_err(&dev->dev, "Read Status failed: %d\n", 94 + pcibios_err_to_errno(err)); 95 + return pcibios_err_to_errno(err); 96 + } 97 + if (!(fw_status & BIT(data0_or_data1))) 98 + break; 99 + 100 + udelay(RENESAS_DELAY); 101 + } 102 + if (i == RENESAS_RETRY) { 103 + dev_err(&dev->dev, "Timeout for Set DATAX step: %zd\n", step); 104 + return -ETIMEDOUT; 105 + } 106 + 107 + /* 108 + * step+2. Write FW data to "DATAX". 109 + * "LSB is left" => force little endian 110 + */ 111 + err = pci_write_config_dword(dev, data0_or_data1 ? 112 + RENESAS_DATA1 : RENESAS_DATA0, 113 + (__force u32)cpu_to_le32(fw[step])); 114 + if (err) { 115 + dev_err(&dev->dev, "Write to DATAX failed: %d\n", 116 + pcibios_err_to_errno(err)); 117 + return pcibios_err_to_errno(err); 118 + } 119 + 120 + udelay(100); 121 + 122 + /* step+3. Set "Set DATAX". */ 123 + err = pci_write_config_byte(dev, status_reg, BIT(data0_or_data1)); 124 + if (err) { 125 + dev_err(&dev->dev, "Write config for DATAX failed: %d\n", 126 + pcibios_err_to_errno(err)); 127 + return pcibios_err_to_errno(err); 128 + } 129 + 130 + return 0; 131 + } 132 + 133 + static int renesas_fw_verify(const void *fw_data, 134 + size_t length) 135 + { 136 + u16 fw_version_pointer; 137 + u16 fw_version; 138 + 139 + /* 140 + * The Firmware's Data Format is describe in 141 + * "6.3 Data Format" R19UH0078EJ0500 Rev.5.00 page 124 142 + */ 143 + 144 + /* 145 + * The bootrom chips of the big brother have sizes up to 64k, let's 146 + * assume that's the biggest the firmware can get. 147 + */ 148 + if (length < 0x1000 || length >= 0x10000) { 149 + pr_err("firmware is size %zd is not (4k - 64k).", 150 + length); 151 + return -EINVAL; 152 + } 153 + 154 + /* The First 2 bytes are fixed value (55aa). "LSB on Left" */ 155 + if (get_unaligned_le16(fw_data) != 0x55aa) { 156 + pr_err("no valid firmware header found."); 157 + return -EINVAL; 158 + } 159 + 160 + /* verify the firmware version position and print it. */ 161 + fw_version_pointer = get_unaligned_le16(fw_data + 4); 162 + if (fw_version_pointer + 2 >= length) { 163 + pr_err("fw ver pointer is outside of the firmware image"); 164 + return -EINVAL; 165 + } 166 + 167 + fw_version = get_unaligned_le16(fw_data + fw_version_pointer); 168 + pr_err("got firmware version: %02x.", fw_version); 169 + 170 + return 0; 171 + } 172 + 173 + static bool renesas_check_rom(struct pci_dev *pdev) 174 + { 175 + u16 rom_status; 176 + int retval; 177 + 178 + /* Check if external ROM exists */ 179 + retval = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_status); 180 + if (retval) 181 + return false; 182 + 183 + rom_status &= RENESAS_ROM_STATUS_ROM_EXISTS; 184 + if (rom_status) { 185 + dev_dbg(&pdev->dev, "External ROM exists\n"); 186 + return true; /* External ROM exists */ 187 + } 188 + 189 + return false; 190 + } 191 + 192 + static int renesas_check_rom_state(struct pci_dev *pdev) 193 + { 194 + u16 rom_state; 195 + u32 version; 196 + int err; 197 + 198 + /* check FW version */ 199 + err = pci_read_config_dword(pdev, RENESAS_FW_VERSION, &version); 200 + if (err) 201 + return pcibios_err_to_errno(err); 202 + 203 + version &= RENESAS_FW_VERSION_FIELD; 204 + version = version >> RENESAS_FW_VERSION_OFFSET; 205 + 206 + err = renesas_verify_fw_version(pdev, version); 207 + if (err) 208 + return err; 209 + 210 + /* 211 + * Test if ROM is present and loaded, if so we can skip everything 212 + */ 213 + err = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_state); 214 + if (err) 215 + return pcibios_err_to_errno(err); 216 + 217 + if (rom_state & BIT(15)) { 218 + /* ROM exists */ 219 + dev_dbg(&pdev->dev, "ROM exists\n"); 220 + 221 + /* Check the "Result Code" Bits (6:4) and act accordingly */ 222 + switch (rom_state & RENESAS_ROM_STATUS_RESULT) { 223 + case RENESAS_ROM_STATUS_SUCCESS: 224 + return 0; 225 + 226 + case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ 227 + return 0; 228 + 229 + case RENESAS_ROM_STATUS_ERROR: /* Error State */ 230 + default: /* All other states are marked as "Reserved states" */ 231 + dev_err(&pdev->dev, "Invalid ROM.."); 232 + break; 233 + } 234 + } 235 + 236 + return -EIO; 237 + } 238 + 239 + static int renesas_fw_check_running(struct pci_dev *pdev) 240 + { 241 + u8 fw_state; 242 + int err; 243 + 244 + /* Check if device has ROM and loaded, if so skip everything */ 245 + err = renesas_check_rom(pdev); 246 + if (err) { /* we have rom */ 247 + err = renesas_check_rom_state(pdev); 248 + if (!err) 249 + return err; 250 + } 251 + 252 + /* 253 + * Test if the device is actually needing the firmware. As most 254 + * BIOSes will initialize the device for us. If the device is 255 + * initialized. 256 + */ 257 + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_state); 258 + if (err) 259 + return pcibios_err_to_errno(err); 260 + 261 + /* 262 + * Check if "FW Download Lock" is locked. If it is and the FW is 263 + * ready we can simply continue. If the FW is not ready, we have 264 + * to give up. 265 + */ 266 + if (fw_state & RENESAS_FW_STATUS_LOCK) { 267 + dev_dbg(&pdev->dev, "FW Download Lock is engaged."); 268 + 269 + if (fw_state & RENESAS_FW_STATUS_SUCCESS) 270 + return 0; 271 + 272 + dev_err(&pdev->dev, 273 + "FW Download Lock is set and FW is not ready. Giving Up."); 274 + return -EIO; 275 + } 276 + 277 + /* 278 + * Check if "FW Download Enable" is set. If someone (us?) tampered 279 + * with it and it can't be reset, we have to give up too... and 280 + * ask for a forgiveness and a reboot. 281 + */ 282 + if (fw_state & RENESAS_FW_STATUS_DOWNLOAD_ENABLE) { 283 + dev_err(&pdev->dev, 284 + "FW Download Enable is stale. Giving Up (poweroff/reboot needed)."); 285 + return -EIO; 286 + } 287 + 288 + /* Otherwise, Check the "Result Code" Bits (6:4) and act accordingly */ 289 + switch (fw_state & RENESAS_FW_STATUS_RESULT) { 290 + case 0: /* No result yet */ 291 + dev_dbg(&pdev->dev, "FW is not ready/loaded yet."); 292 + 293 + /* tell the caller, that this device needs the firmware. */ 294 + return 1; 295 + 296 + case RENESAS_FW_STATUS_SUCCESS: /* Success, device should be working. */ 297 + dev_dbg(&pdev->dev, "FW is ready."); 298 + return 0; 299 + 300 + case RENESAS_FW_STATUS_ERROR: /* Error State */ 301 + dev_err(&pdev->dev, 302 + "hardware is in an error state. Giving up (poweroff/reboot needed)."); 303 + return -ENODEV; 304 + 305 + default: /* All other states are marked as "Reserved states" */ 306 + dev_err(&pdev->dev, 307 + "hardware is in an invalid state %lx. Giving up (poweroff/reboot needed).", 308 + (fw_state & RENESAS_FW_STATUS_RESULT) >> 4); 309 + return -EINVAL; 310 + } 311 + } 312 + 313 + static int renesas_fw_download(struct pci_dev *pdev, 314 + const struct firmware *fw) 315 + { 316 + const u32 *fw_data = (const u32 *)fw->data; 317 + size_t i; 318 + int err; 319 + u8 fw_status; 320 + 321 + /* 322 + * For more information and the big picture: please look at the 323 + * "Firmware Download Sequence" in "7.1 FW Download Interface" 324 + * of R19UH0078EJ0500 Rev.5.00 page 131 325 + */ 326 + 327 + /* 328 + * 0. Set "FW Download Enable" bit in the 329 + * "FW Download Control & Status Register" at 0xF4 330 + */ 331 + err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 332 + RENESAS_FW_STATUS_DOWNLOAD_ENABLE); 333 + if (err) 334 + return pcibios_err_to_errno(err); 335 + 336 + /* 1 - 10 follow one step after the other. */ 337 + for (i = 0; i < fw->size / 4; i++) { 338 + err = renesas_fw_download_image(pdev, fw_data, i, false); 339 + if (err) { 340 + dev_err(&pdev->dev, 341 + "Firmware Download Step %zd failed at position %zd bytes with (%d).", 342 + i, i * 4, err); 343 + return err; 344 + } 345 + } 346 + 347 + /* 348 + * This sequence continues until the last data is written to 349 + * "DATA0" or "DATA1". Naturally, we wait until "SET DATA0/1" 350 + * is cleared by the hardware beforehand. 351 + */ 352 + for (i = 0; i < RENESAS_RETRY; i++) { 353 + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS_MSB, 354 + &fw_status); 355 + if (err) 356 + return pcibios_err_to_errno(err); 357 + if (!(fw_status & (BIT(0) | BIT(1)))) 358 + break; 359 + 360 + udelay(RENESAS_DELAY); 361 + } 362 + if (i == RENESAS_RETRY) 363 + dev_warn(&pdev->dev, "Final Firmware Download step timed out."); 364 + 365 + /* 366 + * 11. After finishing writing the last data of FW, the 367 + * System Software must clear "FW Download Enable" 368 + */ 369 + err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 0); 370 + if (err) 371 + return pcibios_err_to_errno(err); 372 + 373 + /* 12. Read "Result Code" and confirm it is good. */ 374 + for (i = 0; i < RENESAS_RETRY; i++) { 375 + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_status); 376 + if (err) 377 + return pcibios_err_to_errno(err); 378 + if (fw_status & RENESAS_FW_STATUS_SUCCESS) 379 + break; 380 + 381 + udelay(RENESAS_DELAY); 382 + } 383 + if (i == RENESAS_RETRY) { 384 + /* Timed out / Error - let's see if we can fix this */ 385 + err = renesas_fw_check_running(pdev); 386 + switch (err) { 387 + case 0: /* 388 + * we shouldn't end up here. 389 + * maybe it took a little bit longer. 390 + * But all should be well? 391 + */ 392 + break; 393 + 394 + case 1: /* (No result yet! */ 395 + dev_err(&pdev->dev, "FW Load timedout"); 396 + return -ETIMEDOUT; 397 + 398 + default: 399 + return err; 400 + } 401 + } 402 + 403 + return 0; 404 + } 405 + 406 + static void renesas_rom_erase(struct pci_dev *pdev) 407 + { 408 + int retval, i; 409 + u8 status; 410 + 411 + dev_dbg(&pdev->dev, "Performing ROM Erase...\n"); 412 + retval = pci_write_config_dword(pdev, RENESAS_DATA0, 413 + RENESAS_ROM_ERASE_MAGIC); 414 + if (retval) { 415 + dev_err(&pdev->dev, "ROM erase, magic word write failed: %d\n", 416 + pcibios_err_to_errno(retval)); 417 + return; 418 + } 419 + 420 + retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); 421 + if (retval) { 422 + dev_err(&pdev->dev, "ROM status read failed: %d\n", 423 + pcibios_err_to_errno(retval)); 424 + return; 425 + } 426 + status |= RENESAS_ROM_STATUS_ERASE; 427 + retval = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, status); 428 + if (retval) { 429 + dev_err(&pdev->dev, "ROM erase set word write failed\n"); 430 + return; 431 + } 432 + 433 + /* sleep a bit while ROM is erased */ 434 + msleep(20); 435 + 436 + for (i = 0; i < RENESAS_RETRY; i++) { 437 + retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, 438 + &status); 439 + status &= RENESAS_ROM_STATUS_ERASE; 440 + if (!status) 441 + break; 442 + 443 + mdelay(RENESAS_DELAY); 444 + } 445 + 446 + if (i == RENESAS_RETRY) 447 + dev_dbg(&pdev->dev, "Chip erase timedout: %x\n", status); 448 + 449 + dev_dbg(&pdev->dev, "ROM Erase... Done success\n"); 450 + } 451 + 452 + static bool renesas_setup_rom(struct pci_dev *pdev, const struct firmware *fw) 453 + { 454 + const u32 *fw_data = (const u32 *)fw->data; 455 + int err, i; 456 + u8 status; 457 + 458 + /* 2. Write magic word to Data0 */ 459 + err = pci_write_config_dword(pdev, RENESAS_DATA0, 460 + RENESAS_ROM_WRITE_MAGIC); 461 + if (err) 462 + return false; 463 + 464 + /* 3. Set External ROM access */ 465 + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 466 + RENESAS_ROM_STATUS_ACCESS); 467 + if (err) 468 + goto remove_bypass; 469 + 470 + /* 4. Check the result */ 471 + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); 472 + if (err) 473 + goto remove_bypass; 474 + status &= GENMASK(6, 4); 475 + if (status) { 476 + dev_err(&pdev->dev, 477 + "setting external rom failed: %x\n", status); 478 + goto remove_bypass; 479 + } 480 + 481 + /* 5 to 16 Write FW to DATA0/1 while checking SetData0/1 */ 482 + for (i = 0; i < fw->size / 4; i++) { 483 + err = renesas_fw_download_image(pdev, fw_data, i, true); 484 + if (err) { 485 + dev_err(&pdev->dev, 486 + "ROM Download Step %d failed at position %d bytes with (%d)\n", 487 + i, i * 4, err); 488 + goto remove_bypass; 489 + } 490 + } 491 + 492 + /* 493 + * wait till DATA0/1 is cleared 494 + */ 495 + for (i = 0; i < RENESAS_RETRY; i++) { 496 + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS_MSB, 497 + &status); 498 + if (err) 499 + goto remove_bypass; 500 + if (!(status & (BIT(0) | BIT(1)))) 501 + break; 502 + 503 + udelay(RENESAS_DELAY); 504 + } 505 + if (i == RENESAS_RETRY) { 506 + dev_err(&pdev->dev, "Final Firmware ROM Download step timed out\n"); 507 + goto remove_bypass; 508 + } 509 + 510 + /* 17. Remove bypass */ 511 + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0); 512 + if (err) 513 + return false; 514 + 515 + udelay(10); 516 + 517 + /* 18. check result */ 518 + for (i = 0; i < RENESAS_RETRY; i++) { 519 + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); 520 + if (err) { 521 + dev_err(&pdev->dev, "Read ROM status failed:%d\n", 522 + pcibios_err_to_errno(err)); 523 + return false; 524 + } 525 + status &= RENESAS_ROM_STATUS_RESULT; 526 + if (status == RENESAS_ROM_STATUS_SUCCESS) { 527 + dev_dbg(&pdev->dev, "Download ROM success\n"); 528 + break; 529 + } 530 + udelay(RENESAS_DELAY); 531 + } 532 + if (i == RENESAS_RETRY) { /* Timed out */ 533 + dev_err(&pdev->dev, 534 + "Download to external ROM TO: %x\n", status); 535 + return false; 536 + } 537 + 538 + dev_dbg(&pdev->dev, "Download to external ROM succeeded\n"); 539 + 540 + /* Last step set Reload */ 541 + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 542 + RENESAS_ROM_STATUS_RELOAD); 543 + if (err) { 544 + dev_err(&pdev->dev, "Set ROM execute failed: %d\n", 545 + pcibios_err_to_errno(err)); 546 + return false; 547 + } 548 + 549 + /* 550 + * wait till Reload is cleared 551 + */ 552 + for (i = 0; i < RENESAS_RETRY; i++) { 553 + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); 554 + if (err) 555 + return false; 556 + if (!(status & RENESAS_ROM_STATUS_RELOAD)) 557 + break; 558 + 559 + udelay(RENESAS_DELAY); 560 + } 561 + if (i == RENESAS_RETRY) { 562 + dev_err(&pdev->dev, "ROM Exec timed out: %x\n", status); 563 + return false; 564 + } 565 + 566 + return true; 567 + 568 + remove_bypass: 569 + pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0); 570 + return false; 571 + } 572 + 573 + static int renesas_load_fw(struct pci_dev *pdev, const struct firmware *fw) 574 + { 575 + int err = 0; 576 + bool rom; 577 + 578 + /* Check if the device has external ROM */ 579 + rom = renesas_check_rom(pdev); 580 + if (rom) { 581 + /* perform chip erase first */ 582 + renesas_rom_erase(pdev); 583 + 584 + /* lets try loading fw on ROM first */ 585 + rom = renesas_setup_rom(pdev, fw); 586 + if (!rom) { 587 + dev_dbg(&pdev->dev, 588 + "ROM load failed, falling back on FW load\n"); 589 + } else { 590 + dev_dbg(&pdev->dev, 591 + "ROM load success\n"); 592 + goto exit; 593 + } 594 + } 595 + 596 + err = renesas_fw_download(pdev, fw); 597 + 598 + exit: 599 + if (err) 600 + dev_err(&pdev->dev, "firmware failed to download (%d).", err); 601 + return err; 602 + } 603 + 604 + int renesas_xhci_check_request_fw(struct pci_dev *pdev, 605 + const struct pci_device_id *id) 606 + { 607 + struct xhci_driver_data *driver_data = 608 + (struct xhci_driver_data *)id->driver_data; 609 + const char *fw_name = driver_data->firmware; 610 + const struct firmware *fw; 611 + int err; 612 + 613 + err = renesas_fw_check_running(pdev); 614 + /* Continue ahead, if the firmware is already running. */ 615 + if (err == 0) 616 + return 0; 617 + 618 + if (err != 1) 619 + return err; 620 + 621 + pci_dev_get(pdev); 622 + err = request_firmware(&fw, fw_name, &pdev->dev); 623 + pci_dev_put(pdev); 624 + if (err) { 625 + dev_err(&pdev->dev, "request_firmware failed: %d\n", err); 626 + return err; 627 + } 628 + 629 + err = renesas_fw_verify(fw->data, fw->size); 630 + if (err) 631 + goto exit; 632 + 633 + err = renesas_load_fw(pdev, fw); 634 + exit: 635 + release_firmware(fw); 636 + return err; 637 + } 638 + EXPORT_SYMBOL_GPL(renesas_xhci_check_request_fw); 639 + 640 + void renesas_xhci_pci_exit(struct pci_dev *dev) 641 + { 642 + } 643 + EXPORT_SYMBOL_GPL(renesas_xhci_pci_exit); 644 + 645 + MODULE_LICENSE("GPL v2");
+38 -9
drivers/usb/host/xhci-pci.c
··· 15 15 16 16 #include "xhci.h" 17 17 #include "xhci-trace.h" 18 + #include "xhci-pci.h" 18 19 19 20 #define SSIC_PORT_NUM 2 20 21 #define SSIC_PORT_CFG2 0x880c ··· 88 87 89 88 static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) 90 89 { 91 - struct pci_dev *pdev = to_pci_dev(dev); 90 + struct pci_dev *pdev = to_pci_dev(dev); 91 + struct xhci_driver_data *driver_data; 92 + const struct pci_device_id *id; 93 + 94 + id = pci_match_id(pdev->driver->id_table, pdev); 95 + 96 + if (id && id->driver_data) { 97 + driver_data = (struct xhci_driver_data *)id->driver_data; 98 + xhci->quirks |= driver_data->quirks; 99 + } 92 100 93 101 /* Look for vendor-specific quirks */ 94 102 if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && ··· 337 327 { 338 328 int retval; 339 329 struct xhci_hcd *xhci; 340 - struct hc_driver *driver; 341 330 struct usb_hcd *hcd; 331 + struct xhci_driver_data *driver_data; 342 332 343 - driver = (struct hc_driver *)id->driver_data; 333 + driver_data = (struct xhci_driver_data *)id->driver_data; 334 + if (driver_data && driver_data->quirks & XHCI_RENESAS_FW_QUIRK) { 335 + retval = renesas_xhci_check_request_fw(dev, id); 336 + if (retval) 337 + return retval; 338 + } 344 339 345 340 /* Prevent runtime suspending between USB-2 and USB-3 initialization */ 346 341 pm_runtime_get_noresume(&dev->dev); ··· 356 341 * to say USB 2.0, but I'm not sure what the implications would be in 357 342 * the other parts of the HCD code. 358 343 */ 359 - retval = usb_hcd_pci_probe(dev, id); 344 + retval = usb_hcd_pci_probe(dev, id, &xhci_pci_hc_driver); 360 345 361 346 if (retval) 362 347 goto put_runtime_pm; ··· 364 349 /* USB 2.0 roothub is stored in the PCI device now. */ 365 350 hcd = dev_get_drvdata(&dev->dev); 366 351 xhci = hcd_to_xhci(hcd); 367 - xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, 368 - pci_name(dev), hcd); 352 + xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev, 353 + pci_name(dev), hcd); 369 354 if (!xhci->shared_hcd) { 370 355 retval = -ENOMEM; 371 356 goto dealloc_usb2_hcd; ··· 407 392 struct xhci_hcd *xhci; 408 393 409 394 xhci = hcd_to_xhci(pci_get_drvdata(dev)); 395 + if (xhci->quirks & XHCI_RENESAS_FW_QUIRK) 396 + renesas_xhci_pci_exit(dev); 397 + 410 398 xhci->xhc_state |= XHCI_STATE_REMOVING; 411 399 412 400 if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) ··· 561 543 562 544 /*-------------------------------------------------------------------------*/ 563 545 546 + static const struct xhci_driver_data reneses_data = { 547 + .quirks = XHCI_RENESAS_FW_QUIRK, 548 + .firmware = "renesas_usb_fw.mem", 549 + }; 550 + 564 551 /* PCI driver selection metadata; PCI hotplugging uses this */ 565 - static const struct pci_device_id pci_ids[] = { { 552 + static const struct pci_device_id pci_ids[] = { 553 + { PCI_DEVICE(0x1912, 0x0014), 554 + .driver_data = (unsigned long)&reneses_data, 555 + }, 556 + { PCI_DEVICE(0x1912, 0x0015), 557 + .driver_data = (unsigned long)&reneses_data, 558 + }, 566 559 /* handle any USB 3.0 xHCI controller */ 567 - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), 568 - .driver_data = (unsigned long) &xhci_pci_hc_driver, 560 + { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), 569 561 }, 570 562 { /* end: all zeroes */ } 571 563 }; 572 564 MODULE_DEVICE_TABLE(pci, pci_ids); 565 + MODULE_FIRMWARE("renesas_usb_fw.mem"); 573 566 574 567 /* pci driver glue; this is a "new style" PCI driver module */ 575 568 static struct pci_driver xhci_pci_driver = {
+28
drivers/usb/host/xhci-pci.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (C) 2019-2020 Linaro Limited */ 3 + 4 + #ifndef XHCI_PCI_H 5 + #define XHCI_PCI_H 6 + 7 + #if IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) 8 + int renesas_xhci_check_request_fw(struct pci_dev *dev, 9 + const struct pci_device_id *id); 10 + void renesas_xhci_pci_exit(struct pci_dev *dev); 11 + 12 + #else 13 + static int renesas_xhci_check_request_fw(struct pci_dev *dev, 14 + const struct pci_device_id *id) 15 + { 16 + return 0; 17 + } 18 + 19 + static void renesas_xhci_pci_exit(struct pci_dev *dev) { }; 20 + 21 + #endif 22 + 23 + struct xhci_driver_data { 24 + u64 quirks; 25 + const char *firmware; 26 + }; 27 + 28 + #endif
+19 -1
drivers/usb/host/xhci-plat.c
··· 112 112 SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3) 113 113 }; 114 114 115 + static const struct xhci_plat_priv xhci_plat_brcm = { 116 + .quirks = XHCI_RESET_ON_RESUME, 117 + }; 118 + 115 119 static const struct of_device_id usb_xhci_of_match[] = { 116 120 { 117 121 .compatible = "generic-xhci", ··· 151 147 }, { 152 148 .compatible = "renesas,rcar-gen3-xhci", 153 149 .data = &xhci_plat_renesas_rcar_gen3, 150 + }, { 151 + .compatible = "brcm,xhci-brcm-v2", 152 + .data = &xhci_plat_brcm, 153 + }, { 154 + .compatible = "brcm,bcm7445-xhci", 155 + .data = &xhci_plat_brcm, 154 156 }, 155 157 {}, 156 158 }; ··· 419 409 if (ret) 420 410 return ret; 421 411 422 - return xhci_resume(xhci, 0); 412 + ret = xhci_resume(xhci, 0); 413 + if (ret) 414 + return ret; 415 + 416 + pm_runtime_disable(dev); 417 + pm_runtime_set_active(dev); 418 + pm_runtime_enable(dev); 419 + 420 + return 0; 423 421 } 424 422 425 423 static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
+1 -1
drivers/usb/host/xhci-plat.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * xhci-plat.h - xHCI host controller driver platform Bus Glue. 4 4 *
+1 -1
drivers/usb/host/xhci-rcar.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * drivers/usb/host/xhci-rcar.h 4 4 *
+1 -1
drivers/usb/host/xhci-trace.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * xHCI host controller driver 4 4 *
+2 -1
drivers/usb/host/xhci.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 3 3 /* 4 4 * xHCI host controller driver ··· 1873 1873 #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) 1874 1874 #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) 1875 1875 #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) 1876 + #define XHCI_RENESAS_FW_QUIRK BIT_ULL(36) 1876 1877 1877 1878 unsigned int num_active_eps; 1878 1879 unsigned int limit_active_eps;
+1 -1
drivers/usb/isp1760/isp1760-core.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Driver for the NXP ISP1760 chip 4 4 *
+1 -1
drivers/usb/isp1760/isp1760-regs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Driver for the NXP ISP1760 chip 4 4 *
+1 -1
drivers/usb/isp1760/isp1760-udc.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Driver for the NXP ISP1761 device controller 4 4 *
+1 -1
drivers/usb/misc/sisusbvga/sisusb.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 2 /* 3 3 * sisusb - usb kernel driver for Net2280/SiS315 based USB2VGA dongles 4 4 *
+1 -1
drivers/usb/misc/sisusbvga/sisusb_init.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* $XFree86$ */ 3 3 /* $XdotOrg$ */ 4 4 /*
+1 -1
drivers/usb/misc/sisusbvga/sisusb_struct.h
··· 1 - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 2 /* 3 3 * General structure definitions for universal mode switching modules 4 4 *
+1 -1
drivers/usb/misc/usb_u132.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Common Header File for the Elan Digital Systems U132 adapter 4 4 * this file should be included by both the "ftdi-u132" and
+1 -1
drivers/usb/mtu3/mtu3.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * mtu3.h - MediaTek USB3 DRD header 4 4 *
+1 -1
drivers/usb/mtu3/mtu3_debug.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * mtu3_debug.h - debug header 4 4 *
+1 -1
drivers/usb/mtu3/mtu3_dr.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * mtu3_dr.h - dual role switch and host glue layer header 4 4 *
+1 -1
drivers/usb/mtu3/mtu3_hw_regs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * mtu3_hw_regs.h - MediaTek USB3 DRD register and field definitions 4 4 *
+1 -1
drivers/usb/mtu3/mtu3_qmu.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * mtu3_qmu.h - Queue Management Unit driver header 4 4 *
+1 -1
drivers/usb/mtu3/mtu3_trace.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /** 3 3 * mtu3_trace.h - trace support 4 4 *
+1 -1
drivers/usb/musb/davinci.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Copyright (C) 2005-2006 by Texas Instruments 4 4 */
+2 -2
drivers/usb/musb/jz4740.c
··· 30 30 irqreturn_t retval = IRQ_NONE, retval_dma = IRQ_NONE; 31 31 struct musb *musb = __hci; 32 32 33 - spin_lock_irqsave(&musb->lock, flags); 34 - 35 33 if (IS_ENABLED(CONFIG_USB_INVENTRA_DMA) && musb->dma_controller) 36 34 retval_dma = dma_controller_irq(irq, musb->dma_controller); 35 + 36 + spin_lock_irqsave(&musb->lock, flags); 37 37 38 38 musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); 39 39 musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+6
drivers/usb/musb/mediatek.c
··· 208 208 musb->int_rx = musb_clearw(musb->mregs, MUSB_INTRRX); 209 209 musb->int_tx = musb_clearw(musb->mregs, MUSB_INTRTX); 210 210 211 + if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) { 212 + /* ep0 FADDR must be 0 when (re)entering peripheral mode */ 213 + musb_ep_select(musb->mregs, 0); 214 + musb_writeb(musb->mregs, MUSB_FADDR, 0); 215 + } 216 + 211 217 if (musb->int_usb || musb->int_tx || musb->int_rx) 212 218 retval = musb_interrupt(musb); 213 219
+8 -1
drivers/usb/musb/musb_core.c
··· 1795 1795 EXPORT_SYMBOL_GPL(musb_interrupt); 1796 1796 1797 1797 #ifndef CONFIG_MUSB_PIO_ONLY 1798 - static bool use_dma = 1; 1798 + static bool use_dma = true; 1799 1799 1800 1800 /* "modprobe ... use_dma=0" etc */ 1801 1801 module_param(use_dma, bool, 0644); ··· 2876 2876 2877 2877 musb_enable_interrupts(musb); 2878 2878 musb_platform_enable(musb); 2879 + 2880 + /* session might be disabled in suspend */ 2881 + if (musb->port_mode == MUSB_HOST && 2882 + !(musb->ops->quirks & MUSB_PRESERVE_SESSION)) { 2883 + devctl |= MUSB_DEVCTL_SESSION; 2884 + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 2885 + } 2879 2886 2880 2887 spin_lock_irqsave(&musb->lock, flags); 2881 2888 error = musb_run_resume_work(musb);
+1 -1
drivers/usb/musb/musb_core.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver defines 4 4 *
+1 -1
drivers/usb/musb/musb_debug.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver debug defines 4 4 *
+5 -5
drivers/usb/musb/musb_debugfs.c
··· 168 168 u8 test; 169 169 char buf[24]; 170 170 171 + memset(buf, 0x00, sizeof(buf)); 172 + 173 + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 174 + return -EFAULT; 175 + 171 176 pm_runtime_get_sync(musb->controller); 172 177 test = musb_readb(musb->mregs, MUSB_TESTMODE); 173 178 if (test) { ··· 180 175 "Please do USB Bus Reset to start a new test.\n"); 181 176 goto ret; 182 177 } 183 - 184 - memset(buf, 0x00, sizeof(buf)); 185 - 186 - if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 187 - return -EFAULT; 188 178 189 179 if (strstarts(buf, "force host full-speed")) 190 180 test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_FS;
+1 -1
drivers/usb/musb/musb_dma.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver DMA controller abstraction 4 4 *
+1 -1
drivers/usb/musb/musb_gadget.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver peripheral defines 4 4 *
+8 -2
drivers/usb/musb/musb_host.c
··· 1774 1774 status = -EPIPE; 1775 1775 1776 1776 } else if (rx_csr & MUSB_RXCSR_H_ERROR) { 1777 - musb_dbg(musb, "end %d RX proto error", epnum); 1777 + dev_err(musb->controller, "ep%d RX three-strikes error", epnum); 1778 1778 1779 - status = -EPROTO; 1779 + /* 1780 + * The three-strikes error could only happen when the USB 1781 + * device is not accessible, for example detached or powered 1782 + * off. So return the fatal error -ESHUTDOWN so hopefully the 1783 + * USB device drivers won't immediately resubmit the same URB. 1784 + */ 1785 + status = -ESHUTDOWN; 1780 1786 musb_writeb(epio, MUSB_RXINTERVAL, 0); 1781 1787 1782 1788 rx_csr &= ~MUSB_RXCSR_H_ERROR;
+1 -1
drivers/usb/musb/musb_host.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver host defines 4 4 *
+1 -1
drivers/usb/musb/musb_io.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver register I/O 4 4 *
+1 -1
drivers/usb/musb/musb_regs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * MUSB OTG driver register defines 4 4 *
+1 -1
drivers/usb/musb/musb_trace.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * musb_trace.h - MUSB Controller Trace Support 4 4 *
+1 -1
drivers/usb/musb/omap2430.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Copyright (C) 2005-2006 by Texas Instruments 4 4 */
+1 -1
drivers/usb/musb/tusb6010.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 3 * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller 4 4 *
+1 -1
drivers/usb/phy/phy-fsl-usb.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. */ 3 3 4 4 #include <linux/usb/otg-fsm.h>
+6 -6
drivers/usb/phy/phy-jz4770.c
··· 125 125 126 126 err = regulator_enable(priv->vcc_supply); 127 127 if (err) { 128 - dev_err(priv->dev, "Unable to enable VCC: %d", err); 128 + dev_err(priv->dev, "Unable to enable VCC: %d\n", err); 129 129 return err; 130 130 } 131 131 132 132 err = clk_prepare_enable(priv->clk); 133 133 if (err) { 134 - dev_err(priv->dev, "Unable to start clock: %d", err); 134 + dev_err(priv->dev, "Unable to start clock: %d\n", err); 135 135 return err; 136 136 } 137 137 ··· 191 191 192 192 priv->base = devm_platform_ioremap_resource(pdev, 0); 193 193 if (IS_ERR(priv->base)) { 194 - dev_err(dev, "Failed to map registers"); 194 + dev_err(dev, "Failed to map registers\n"); 195 195 return PTR_ERR(priv->base); 196 196 } 197 197 ··· 199 199 if (IS_ERR(priv->clk)) { 200 200 err = PTR_ERR(priv->clk); 201 201 if (err != -EPROBE_DEFER) 202 - dev_err(dev, "Failed to get clock"); 202 + dev_err(dev, "Failed to get clock\n"); 203 203 return err; 204 204 } 205 205 ··· 207 207 if (IS_ERR(priv->vcc_supply)) { 208 208 err = PTR_ERR(priv->vcc_supply); 209 209 if (err != -EPROBE_DEFER) 210 - dev_err(dev, "failed to get regulator"); 210 + dev_err(dev, "Failed to get regulator\n"); 211 211 return err; 212 212 } 213 213 214 214 err = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); 215 215 if (err) { 216 216 if (err != -EPROBE_DEFER) 217 - dev_err(dev, "Unable to register PHY"); 217 + dev_err(dev, "Unable to register PHY\n"); 218 218 return err; 219 219 } 220 220
+1 -1
drivers/usb/phy/phy-mv-usb.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Copyright (C) 2011 Marvell International Ltd. All rights reserved. 4 4 */
+1 -1
drivers/usb/renesas_usbhs/common.h
··· 1 - // SPDX-License-Identifier: GPL-1.0+ 1 + /* SPDX-License-Identifier: GPL-1.0+ */ 2 2 /* 3 3 * Renesas USB driver 4 4 *
+1 -1
drivers/usb/renesas_usbhs/fifo.h
··· 1 - // SPDX-License-Identifier: GPL-1.0+ 1 + /* SPDX-License-Identifier: GPL-1.0+ */ 2 2 /* 3 3 * Renesas USB driver 4 4 *
+1 -1
drivers/usb/renesas_usbhs/mod.h
··· 1 - // SPDX-License-Identifier: GPL-1.0+ 1 + /* SPDX-License-Identifier: GPL-1.0+ */ 2 2 /* 3 3 * Renesas USB driver 4 4 *
+1 -1
drivers/usb/renesas_usbhs/pipe.h
··· 1 - // SPDX-License-Identifier: GPL-1.0+ 1 + /* SPDX-License-Identifier: GPL-1.0+ */ 2 2 /* 3 3 * Renesas USB driver 4 4 *
+1 -1
drivers/usb/renesas_usbhs/rcar2.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #include "common.h" 3 3 4 4 extern const struct renesas_usbhs_platform_info usbhs_rcar_gen2_plat_info;
+1 -1
drivers/usb/renesas_usbhs/rcar3.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #include "common.h" 3 3 4 4 extern const struct renesas_usbhs_platform_info usbhs_rcar_gen3_plat_info;
+1 -1
drivers/usb/renesas_usbhs/rza.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #include "common.h" 3 3 4 4 extern const struct renesas_usbhs_platform_info usbhs_rza1_plat_info;
+3 -1
drivers/usb/roles/class.c
··· 49 49 mutex_lock(&sw->lock); 50 50 51 51 ret = sw->set(sw, role); 52 - if (!ret) 52 + if (!ret) { 53 53 sw->role = role; 54 + kobject_uevent(&sw->dev.kobj, KOBJ_CHANGE); 55 + } 54 56 55 57 mutex_unlock(&sw->lock); 56 58
+1 -1
drivers/usb/serial/belkin_sa.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Definitions for Belkin USB Serial Adapter Driver 4 4 *
+65 -3
drivers/usb/serial/ch341.c
··· 73 73 #define CH341_LCR_CS6 0x01 74 74 #define CH341_LCR_CS5 0x00 75 75 76 + #define CH341_QUIRK_LIMITED_PRESCALER BIT(0) 77 + 76 78 static const struct usb_device_id id_table[] = { 77 79 { USB_DEVICE(0x4348, 0x5523) }, 78 80 { USB_DEVICE(0x1a86, 0x7523) }, ··· 89 87 u8 mcr; 90 88 u8 msr; 91 89 u8 lcr; 90 + unsigned long quirks; 92 91 }; 93 92 94 93 static void ch341_set_termios(struct tty_struct *tty, ··· 162 159 * 2 <= div <= 256 if fact = 0, or 163 160 * 9 <= div <= 256 if fact = 1 164 161 */ 165 - static int ch341_get_divisor(speed_t speed) 162 + static int ch341_get_divisor(struct ch341_private *priv) 166 163 { 167 164 unsigned int fact, div, clk_div; 165 + speed_t speed = priv->baud_rate; 166 + bool force_fact0 = false; 168 167 int ps; 169 168 170 169 /* ··· 192 187 clk_div = CH341_CLK_DIV(ps, fact); 193 188 div = CH341_CLKRATE / (clk_div * speed); 194 189 190 + /* Some devices require a lower base clock if ps < 3. */ 191 + if (ps < 3 && (priv->quirks & CH341_QUIRK_LIMITED_PRESCALER)) 192 + force_fact0 = true; 193 + 195 194 /* Halve base clock (fact = 0) if required. */ 196 - if (div < 9 || div > 255) { 195 + if (div < 9 || div > 255 || force_fact0) { 197 196 div /= 2; 198 197 clk_div *= 2; 199 198 fact = 0; ··· 236 227 if (!priv->baud_rate) 237 228 return -EINVAL; 238 229 239 - val = ch341_get_divisor(priv->baud_rate); 230 + val = ch341_get_divisor(priv); 240 231 if (val < 0) 241 232 return -EINVAL; 242 233 ··· 317 308 return r; 318 309 } 319 310 311 + static int ch341_detect_quirks(struct usb_serial_port *port) 312 + { 313 + struct ch341_private *priv = usb_get_serial_port_data(port); 314 + struct usb_device *udev = port->serial->dev; 315 + const unsigned int size = 2; 316 + unsigned long quirks = 0; 317 + char *buffer; 318 + int r; 319 + 320 + buffer = kmalloc(size, GFP_KERNEL); 321 + if (!buffer) 322 + return -ENOMEM; 323 + 324 + /* 325 + * A subset of CH34x devices does not support all features. The 326 + * prescaler is limited and there is no support for sending a RS232 327 + * break condition. A read failure when trying to set up the latter is 328 + * used to detect these devices. 329 + */ 330 + r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG, 331 + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 332 + CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); 333 + if (r == -EPIPE) { 334 + dev_dbg(&port->dev, "break control not supported\n"); 335 + quirks = CH341_QUIRK_LIMITED_PRESCALER; 336 + r = 0; 337 + goto out; 338 + } 339 + 340 + if (r != size) { 341 + if (r >= 0) 342 + r = -EIO; 343 + dev_err(&port->dev, "failed to read break control: %d\n", r); 344 + goto out; 345 + } 346 + 347 + r = 0; 348 + out: 349 + kfree(buffer); 350 + 351 + if (quirks) { 352 + dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks); 353 + priv->quirks |= quirks; 354 + } 355 + 356 + return r; 357 + } 358 + 320 359 static int ch341_port_probe(struct usb_serial_port *port) 321 360 { 322 361 struct ch341_private *priv; ··· 387 330 goto error; 388 331 389 332 usb_set_serial_port_data(port, priv); 333 + 334 + r = ch341_detect_quirks(port); 335 + if (r < 0) 336 + goto error; 337 + 390 338 return 0; 391 339 392 340 error: kfree(priv);
+1 -1
drivers/usb/serial/io_16654.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /************************************************************************ 3 3 * 4 4 * 16654.H Definitions for 16C654 UART used on EdgePorts
+1 -1
drivers/usb/serial/io_edgeport.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /************************************************************************ 3 3 * 4 4 * io_edgeport.h Edgeport Linux Interface definitions
+1 -1
drivers/usb/serial/io_ionsp.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /************************************************************************ 3 3 * 4 4 * IONSP.H Definitions for I/O Networks Serial Protocol
+1 -1
drivers/usb/serial/io_ti.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /***************************************************************************** 3 3 * 4 4 * Copyright (C) 1997-2002 Inside Out Networks, Inc.
+1 -1
drivers/usb/serial/io_usbvend.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /************************************************************************ 3 3 * 4 4 * USBVEND.H Vendor-specific USB definitions
+1 -1
drivers/usb/serial/iuu_phoenix.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Infinity Unlimited USB Phoenix driver 4 4 *
+1 -1
drivers/usb/serial/mct_u232.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Definitions for MCT (Magic Control Technology) USB-RS232 Converter Driver 4 4 *
+4
drivers/usb/serial/option.c
··· 1157 1157 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, 1158 1158 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, 1159 1159 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, 1160 + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */ 1161 + .driver_info = NCTRL(0) | RSVD(3) }, 1162 + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ 1163 + .driver_info = NCTRL(0) }, 1160 1164 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), 1161 1165 .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, 1162 1166 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
+1 -1
drivers/usb/serial/oti6858.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Ours Technology Inc. OTi-6858 USB to serial adapter driver. 4 4 */
+1 -1
drivers/usb/serial/pl2303.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Prolific PL2303 USB to serial adaptor driver header file 4 4 */
+1
drivers/usb/serial/qcserial.c
··· 173 173 {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ 174 174 {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ 175 175 {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ 176 + {DEVICE_SWI(0x413c, 0x81cb)}, /* Dell Wireless 5816e QDL */ 176 177 {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */ 177 178 {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ 178 179 {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */
+4
drivers/usb/serial/usb_wwan.c
··· 270 270 if (status) { 271 271 dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", 272 272 __func__, status, endpoint); 273 + 274 + /* don't resubmit on fatal errors */ 275 + if (status == -ESHUTDOWN || status == -ENOENT) 276 + return; 273 277 } else { 274 278 if (urb->actual_length) { 275 279 tty_insert_flip_string(&port->port, data,
+1 -1
drivers/usb/serial/visor.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * USB HandSpring Visor driver 4 4 *
+1 -1
drivers/usb/serial/whiteheat.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * USB ConnectTech WhiteHEAT driver 4 4 *
+1 -1
drivers/usb/storage/debug.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * Debugging Functions Header File
+1 -1
drivers/usb/storage/initializers.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Header file for Special Initializers for certain USB Mass Storage devices 4 4 *
+1 -1
drivers/usb/storage/protocol.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * Protocol Functions Header File
+1 -1
drivers/usb/storage/scsiglue.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * SCSI Connecting Glue Header File
-4
drivers/usb/storage/sierra_ms.c
··· 129 129 int result, retries; 130 130 struct swoc_info *swocInfo; 131 131 struct usb_device *udev; 132 - struct Scsi_Host *sh; 133 132 134 133 retries = 3; 135 134 result = 0; 136 135 udev = us->pusb_dev; 137 - 138 - sh = us_to_host(us); 139 - scsi_get_host_dev(sh); 140 136 141 137 /* Force Modem mode */ 142 138 if (swi_tru_install == TRU_FORCE_MODEM) {
+1 -1
drivers/usb/storage/transport.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * Transport Functions Header File
+1 -1
drivers/usb/storage/unusual_alauda.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Alauda-based card readers 4 4 */
+1 -1
drivers/usb/storage/unusual_cypress.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for devices based on the Cypress USB/ATA bridge 4 4 * with support for ATACB
+1 -1
drivers/usb/storage/unusual_datafab.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Datafab USB Compact Flash reader 4 4 */
+1 -1
drivers/usb/storage/unusual_devs.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * Unusual Devices File
+1 -1
drivers/usb/storage/unusual_ene_ub6250.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 #if defined(CONFIG_USB_STORAGE_ENE_UB6250) || \ 3 3 defined(CONFIG_USB_STORAGE_ENE_UB6250_MODULE) 4 4
+1 -1
drivers/usb/storage/unusual_freecom.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Freecom USB/IDE adaptor 4 4 */
+1 -1
drivers/usb/storage/unusual_isd200.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for In-System Design, Inc. ISD200 ASIC 4 4 */
+1 -1
drivers/usb/storage/unusual_jumpshot.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader 4 4 */
+1 -1
drivers/usb/storage/unusual_karma.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Rio Karma 4 4 */
+1 -1
drivers/usb/storage/unusual_onetouch.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for the Maxtor OneTouch USB hard drive's button 4 4 */
+1 -1
drivers/usb/storage/unusual_realtek.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for Realtek RTS51xx USB card reader 4 4 *
+1 -1
drivers/usb/storage/unusual_sddr09.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for SanDisk SDDR-09 SmartMedia reader 4 4 */
+1 -1
drivers/usb/storage/unusual_sddr55.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for SanDisk SDDR-55 SmartMedia reader 4 4 */
+1 -1
drivers/usb/storage/unusual_uas.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Attached SCSI devices - Unusual Devices File 4 4 *
+1 -1
drivers/usb/storage/unusual_usbat.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable 4 4 */
+1 -1
drivers/usb/storage/usb.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Driver for USB Mass Storage compliant devices 4 4 * Main Header File
+2 -1
drivers/usb/typec/Kconfig
··· 64 64 config TYPEC_TPS6598X 65 65 tristate "TI TPS6598x USB Power Delivery controller driver" 66 66 depends on I2C 67 - select REGMAP_I2C 67 + depends on REGMAP_I2C 68 + depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH 68 69 help 69 70 Say Y or M here if your system has TI TPS65982 or TPS65983 USB Power 70 71 Delivery controller.
+23 -11
drivers/usb/typec/class.c
··· 917 917 /* ------------------------------------------------------------------------- */ 918 918 /* USB Type-C ports */ 919 919 920 + static const char * const typec_orientations[] = { 921 + [TYPEC_ORIENTATION_NONE] = "unknown", 922 + [TYPEC_ORIENTATION_NORMAL] = "normal", 923 + [TYPEC_ORIENTATION_REVERSE] = "reverse", 924 + }; 925 + 920 926 static const char * const typec_roles[] = { 921 927 [TYPEC_SINK] = "sink", 922 928 [TYPEC_SOURCE] = "source", ··· 1254 1248 struct device_attribute *attr, 1255 1249 char *buf) 1256 1250 { 1257 - struct typec_port *p = to_typec_port(dev); 1258 - enum typec_orientation orientation = typec_get_orientation(p); 1251 + struct typec_port *port = to_typec_port(dev); 1259 1252 1260 - switch (orientation) { 1261 - case TYPEC_ORIENTATION_NORMAL: 1262 - return sprintf(buf, "%s\n", "normal"); 1263 - case TYPEC_ORIENTATION_REVERSE: 1264 - return sprintf(buf, "%s\n", "reverse"); 1265 - case TYPEC_ORIENTATION_NONE: 1266 - default: 1267 - return sprintf(buf, "%s\n", "unknown"); 1268 - } 1253 + return sprintf(buf, "%s\n", typec_orientations[port->orientation]); 1269 1254 } 1270 1255 static DEVICE_ATTR_RO(orientation); 1271 1256 ··· 1447 1450 } 1448 1451 } 1449 1452 EXPORT_SYMBOL_GPL(typec_set_pwr_opmode); 1453 + 1454 + /** 1455 + * typec_find_orientation - Convert orientation string to enum typec_orientation 1456 + * @name: Orientation string 1457 + * 1458 + * This routine is used to find the typec_orientation by its string name @name. 1459 + * 1460 + * Returns the orientation value on success, otherwise negative error code. 1461 + */ 1462 + int typec_find_orientation(const char *name) 1463 + { 1464 + return match_string(typec_orientations, ARRAY_SIZE(typec_orientations), 1465 + name); 1466 + } 1467 + EXPORT_SYMBOL_GPL(typec_find_orientation); 1450 1468 1451 1469 /** 1452 1470 * typec_find_port_power_role - Get the typec port power capability
+36 -6
drivers/usb/typec/mux/intel_pmc_mux.c
··· 92 92 93 93 u8 usb2_port; 94 94 u8 usb3_port; 95 + 96 + enum typec_orientation sbu_orientation; 97 + enum typec_orientation hsl_orientation; 95 98 }; 96 99 97 100 struct pmc_usb { ··· 103 100 struct intel_scu_ipc_dev *ipc; 104 101 struct pmc_usb_port *port; 105 102 }; 103 + 104 + static int sbu_orientation(struct pmc_usb_port *port) 105 + { 106 + if (port->sbu_orientation) 107 + return port->sbu_orientation - 1; 108 + 109 + return port->orientation - 1; 110 + } 111 + 112 + static int hsl_orientation(struct pmc_usb_port *port) 113 + { 114 + if (port->hsl_orientation) 115 + return port->hsl_orientation - 1; 116 + 117 + return port->orientation - 1; 118 + } 106 119 107 120 static int pmc_usb_command(struct pmc_usb_port *port, u8 *msg, u32 len) 108 121 { ··· 171 152 172 153 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT; 173 154 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT; 174 - req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_AUX_SHIFT; 175 - req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_HSL_SHIFT; 155 + 156 + req.mode_data |= sbu_orientation(port) << PMC_USB_ALTMODE_ORI_AUX_SHIFT; 157 + req.mode_data |= hsl_orientation(port) << PMC_USB_ALTMODE_ORI_HSL_SHIFT; 176 158 177 159 req.mode_data |= (state->mode - TYPEC_STATE_MODAL) << 178 160 PMC_USB_ALTMODE_DP_MODE_SHIFT; ··· 197 177 198 178 req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT; 199 179 req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT; 200 - req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_AUX_SHIFT; 201 - req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_HSL_SHIFT; 180 + 181 + req.mode_data |= sbu_orientation(port) << PMC_USB_ALTMODE_ORI_AUX_SHIFT; 182 + req.mode_data |= hsl_orientation(port) << PMC_USB_ALTMODE_ORI_HSL_SHIFT; 202 183 203 184 if (TBT_ADAPTER(data->device_mode) == TBT_ADAPTER_TBT3) 204 185 req.mode_data |= PMC_USB_ALTMODE_TBT_TYPE; ··· 236 215 msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; 237 216 238 217 msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT; 239 - msg[1] |= (port->orientation - 1) << PMC_USB_MSG_ORI_HSL_SHIFT; 240 - msg[1] |= (port->orientation - 1) << PMC_USB_MSG_ORI_AUX_SHIFT; 218 + msg[1] |= hsl_orientation(port) << PMC_USB_MSG_ORI_HSL_SHIFT; 219 + msg[1] |= sbu_orientation(port) << PMC_USB_MSG_ORI_AUX_SHIFT; 241 220 242 221 return pmc_usb_command(port, msg, sizeof(msg)); 243 222 } ··· 321 300 struct usb_role_switch_desc desc = { }; 322 301 struct typec_switch_desc sw_desc = { }; 323 302 struct typec_mux_desc mux_desc = { }; 303 + const char *str; 324 304 int ret; 325 305 326 306 ret = fwnode_property_read_u8(fwnode, "usb2-port-number", &port->usb2_port); ··· 331 309 ret = fwnode_property_read_u8(fwnode, "usb3-port-number", &port->usb3_port); 332 310 if (ret) 333 311 return ret; 312 + 313 + ret = fwnode_property_read_string(fwnode, "sbu-orientation", &str); 314 + if (!ret) 315 + port->sbu_orientation = typec_find_orientation(str); 316 + 317 + ret = fwnode_property_read_string(fwnode, "hsl-orientation", &str); 318 + if (!ret) 319 + port->hsl_orientation = typec_find_orientation(str); 334 320 335 321 port->num = index; 336 322 port->pmc = pmc;
+9 -23
drivers/usb/typec/tcpm/fusb302.c
··· 9 9 #include <linux/delay.h> 10 10 #include <linux/errno.h> 11 11 #include <linux/extcon.h> 12 - #include <linux/gpio.h> 12 + #include <linux/gpio/consumer.h> 13 13 #include <linux/i2c.h> 14 14 #include <linux/interrupt.h> 15 15 #include <linux/kernel.h> 16 16 #include <linux/module.h> 17 17 #include <linux/mutex.h> 18 18 #include <linux/of_device.h> 19 - #include <linux/of_gpio.h> 20 19 #include <linux/pinctrl/consumer.h> 21 20 #include <linux/proc_fs.h> 22 21 #include <linux/regulator/consumer.h> ··· 82 83 struct work_struct irq_work; 83 84 bool irq_suspended; 84 85 bool irq_while_suspended; 85 - int gpio_int_n; 86 + struct gpio_desc *gpio_int_n; 86 87 int gpio_int_n_irq; 87 88 struct extcon_dev *extcon; 88 89 ··· 1617 1618 1618 1619 static int init_gpio(struct fusb302_chip *chip) 1619 1620 { 1620 - struct device_node *node; 1621 + struct device *dev = chip->dev; 1621 1622 int ret = 0; 1622 1623 1623 - node = chip->dev->of_node; 1624 - chip->gpio_int_n = of_get_named_gpio(node, "fcs,int_n", 0); 1625 - if (!gpio_is_valid(chip->gpio_int_n)) { 1626 - ret = chip->gpio_int_n; 1627 - dev_err(chip->dev, "cannot get named GPIO Int_N, ret=%d", ret); 1628 - return ret; 1624 + chip->gpio_int_n = devm_gpiod_get(dev, "fcs,int_n", GPIOD_IN); 1625 + if (IS_ERR(chip->gpio_int_n)) { 1626 + dev_err(dev, "failed to request gpio_int_n\n"); 1627 + return PTR_ERR(chip->gpio_int_n); 1629 1628 } 1630 - ret = devm_gpio_request(chip->dev, chip->gpio_int_n, "fcs,int_n"); 1629 + ret = gpiod_to_irq(chip->gpio_int_n); 1631 1630 if (ret < 0) { 1632 - dev_err(chip->dev, "cannot request GPIO Int_N, ret=%d", ret); 1633 - return ret; 1634 - } 1635 - ret = gpio_direction_input(chip->gpio_int_n); 1636 - if (ret < 0) { 1637 - dev_err(chip->dev, 1638 - "cannot set GPIO Int_N to input, ret=%d", ret); 1639 - return ret; 1640 - } 1641 - ret = gpio_to_irq(chip->gpio_int_n); 1642 - if (ret < 0) { 1643 - dev_err(chip->dev, 1631 + dev_err(dev, 1644 1632 "cannot request IRQ for GPIO Int_N, ret=%d", ret); 1645 1633 return ret; 1646 1634 }
+1 -1
drivers/usb/typec/tcpm/fusb302_reg.h
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 2 /* 3 3 * Copyright 2016-2017 Google, Inc 4 4 *
+57 -7
drivers/usb/typec/tps6598x.c
··· 12 12 #include <linux/regmap.h> 13 13 #include <linux/interrupt.h> 14 14 #include <linux/usb/typec.h> 15 + #include <linux/usb/role.h> 15 16 16 17 /* Register offsets */ 17 18 #define TPS_REG_VID 0x00 ··· 95 94 struct typec_port *port; 96 95 struct typec_partner *partner; 97 96 struct usb_pd_identity partner_identity; 97 + struct usb_role_switch *role_sw; 98 98 }; 99 99 100 100 /* ··· 192 190 return 0; 193 191 } 194 192 193 + static void tps6598x_set_data_role(struct tps6598x *tps, 194 + enum typec_data_role role, bool connected) 195 + { 196 + enum usb_role role_val; 197 + 198 + if (role == TYPEC_HOST) 199 + role_val = USB_ROLE_HOST; 200 + else 201 + role_val = USB_ROLE_DEVICE; 202 + 203 + if (!connected) 204 + role_val = USB_ROLE_NONE; 205 + 206 + usb_role_switch_set_role(tps->role_sw, role_val); 207 + typec_set_data_role(tps->port, role); 208 + } 209 + 195 210 static int tps6598x_connect(struct tps6598x *tps, u32 status) 196 211 { 197 212 struct typec_partner_desc desc; ··· 239 220 typec_set_pwr_opmode(tps->port, mode); 240 221 typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status)); 241 222 typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status)); 242 - typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status)); 223 + tps6598x_set_data_role(tps, TPS_STATUS_DATAROLE(status), true); 243 224 244 225 tps->partner = typec_register_partner(tps->port, &desc); 245 226 if (IS_ERR(tps->partner)) ··· 259 240 typec_set_pwr_opmode(tps->port, TYPEC_PWR_MODE_USB); 260 241 typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status)); 261 242 typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status)); 262 - typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status)); 243 + tps6598x_set_data_role(tps, TPS_STATUS_DATAROLE(status), false); 263 244 } 264 245 265 246 static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, ··· 347 328 goto out_unlock; 348 329 } 349 330 350 - typec_set_data_role(tps->port, role); 331 + tps6598x_set_data_role(tps, role, true); 351 332 352 333 out_unlock: 353 334 mutex_unlock(&tps->lock); ··· 471 452 { 472 453 struct typec_capability typec_cap = { }; 473 454 struct tps6598x *tps; 455 + struct fwnode_handle *fwnode; 474 456 u32 status; 475 457 u32 conf; 476 458 u32 vid; ··· 515 495 if (ret < 0) 516 496 return ret; 517 497 498 + fwnode = device_get_named_child_node(&client->dev, "connector"); 499 + if (IS_ERR(fwnode)) 500 + return PTR_ERR(fwnode); 501 + 502 + tps->role_sw = fwnode_usb_role_switch_get(fwnode); 503 + if (IS_ERR(tps->role_sw)) { 504 + ret = PTR_ERR(tps->role_sw); 505 + goto err_fwnode_put; 506 + } 507 + 518 508 typec_cap.revision = USB_TYPEC_REV_1_2; 519 509 typec_cap.pd_revision = 0x200; 520 510 typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE; 521 511 typec_cap.driver_data = tps; 522 512 typec_cap.ops = &tps6598x_ops; 513 + typec_cap.fwnode = fwnode; 523 514 524 515 switch (TPS_SYSCONF_PORTINFO(conf)) { 525 516 case TPS_PORTINFO_SINK_ACCESSORY: ··· 556 525 typec_cap.data = TYPEC_PORT_DFP; 557 526 break; 558 527 default: 559 - return -ENODEV; 528 + ret = -ENODEV; 529 + goto err_role_put; 560 530 } 561 531 562 532 tps->port = typec_register_port(&client->dev, &typec_cap); 563 - if (IS_ERR(tps->port)) 564 - return PTR_ERR(tps->port); 533 + if (IS_ERR(tps->port)) { 534 + ret = PTR_ERR(tps->port); 535 + goto err_role_put; 536 + } 537 + fwnode_handle_put(fwnode); 565 538 566 539 if (status & TPS_STATUS_PLUG_PRESENT) { 567 540 ret = tps6598x_connect(tps, status); ··· 580 545 if (ret) { 581 546 tps6598x_disconnect(tps, 0); 582 547 typec_unregister_port(tps->port); 583 - return ret; 548 + goto err_role_put; 584 549 } 585 550 586 551 i2c_set_clientdata(client, tps); 587 552 588 553 return 0; 554 + 555 + err_role_put: 556 + usb_role_switch_put(tps->role_sw); 557 + err_fwnode_put: 558 + fwnode_handle_put(fwnode); 559 + 560 + return ret; 589 561 } 590 562 591 563 static int tps6598x_remove(struct i2c_client *client) ··· 601 559 602 560 tps6598x_disconnect(tps, 0); 603 561 typec_unregister_port(tps->port); 562 + usb_role_switch_put(tps->role_sw); 604 563 605 564 return 0; 606 565 } 566 + 567 + static const struct of_device_id tps6598x_of_match[] = { 568 + { .compatible = "ti,tps6598x", }, 569 + {} 570 + }; 571 + MODULE_DEVICE_TABLE(of, tps6598x_of_match); 607 572 608 573 static const struct i2c_device_id tps6598x_id[] = { 609 574 { "tps6598x" }, ··· 621 572 static struct i2c_driver tps6598x_i2c_driver = { 622 573 .driver = { 623 574 .name = "tps6598x", 575 + .of_match_table = tps6598x_of_match, 624 576 }, 625 577 .probe_new = tps6598x_probe, 626 578 .remove = tps6598x_remove,
+4
drivers/usb/typec/ucsi/Makefile
··· 7 7 8 8 typec_ucsi-$(CONFIG_TRACING) += trace.o 9 9 10 + ifneq ($(CONFIG_POWER_SUPPLY),) 11 + typec_ucsi-y += psy.o 12 + endif 13 + 10 14 ifneq ($(CONFIG_TYPEC_DP_ALTMODE),) 11 15 typec_ucsi-y += displayport.o 12 16 endif
+241
drivers/usb/typec/ucsi/psy.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Power Supply for UCSI 4 + * 5 + * Copyright (C) 2020, Intel Corporation 6 + * Author: K V, Abhilash <abhilash.k.v@intel.com> 7 + * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 8 + */ 9 + 10 + #include <linux/property.h> 11 + #include <linux/usb/pd.h> 12 + 13 + #include "ucsi.h" 14 + 15 + /* Power Supply access to expose source power information */ 16 + enum ucsi_psy_online_states { 17 + UCSI_PSY_OFFLINE = 0, 18 + UCSI_PSY_FIXED_ONLINE, 19 + UCSI_PSY_PROG_ONLINE, 20 + }; 21 + 22 + static enum power_supply_property ucsi_psy_props[] = { 23 + POWER_SUPPLY_PROP_USB_TYPE, 24 + POWER_SUPPLY_PROP_ONLINE, 25 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 26 + POWER_SUPPLY_PROP_VOLTAGE_MAX, 27 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 28 + POWER_SUPPLY_PROP_CURRENT_MAX, 29 + POWER_SUPPLY_PROP_CURRENT_NOW, 30 + }; 31 + 32 + static int ucsi_psy_get_online(struct ucsi_connector *con, 33 + union power_supply_propval *val) 34 + { 35 + val->intval = UCSI_PSY_OFFLINE; 36 + if (con->status.flags & UCSI_CONSTAT_CONNECTED && 37 + (con->status.flags & UCSI_CONSTAT_PWR_DIR) == TYPEC_SINK) 38 + val->intval = UCSI_PSY_FIXED_ONLINE; 39 + return 0; 40 + } 41 + 42 + static int ucsi_psy_get_voltage_min(struct ucsi_connector *con, 43 + union power_supply_propval *val) 44 + { 45 + u32 pdo; 46 + 47 + switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { 48 + case UCSI_CONSTAT_PWR_OPMODE_PD: 49 + pdo = con->src_pdos[0]; 50 + val->intval = pdo_fixed_voltage(pdo) * 1000; 51 + break; 52 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: 53 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 54 + case UCSI_CONSTAT_PWR_OPMODE_BC: 55 + case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: 56 + val->intval = UCSI_TYPEC_VSAFE5V * 1000; 57 + break; 58 + default: 59 + val->intval = 0; 60 + break; 61 + } 62 + return 0; 63 + } 64 + 65 + static int ucsi_psy_get_voltage_max(struct ucsi_connector *con, 66 + union power_supply_propval *val) 67 + { 68 + u32 pdo; 69 + 70 + switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { 71 + case UCSI_CONSTAT_PWR_OPMODE_PD: 72 + if (con->num_pdos > 0) { 73 + pdo = con->src_pdos[con->num_pdos - 1]; 74 + val->intval = pdo_fixed_voltage(pdo) * 1000; 75 + } else { 76 + val->intval = 0; 77 + } 78 + break; 79 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: 80 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 81 + case UCSI_CONSTAT_PWR_OPMODE_BC: 82 + case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: 83 + val->intval = UCSI_TYPEC_VSAFE5V * 1000; 84 + break; 85 + default: 86 + val->intval = 0; 87 + break; 88 + } 89 + return 0; 90 + } 91 + 92 + static int ucsi_psy_get_voltage_now(struct ucsi_connector *con, 93 + union power_supply_propval *val) 94 + { 95 + int index; 96 + u32 pdo; 97 + 98 + switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { 99 + case UCSI_CONSTAT_PWR_OPMODE_PD: 100 + index = rdo_index(con->rdo); 101 + if (index > 0) { 102 + pdo = con->src_pdos[index - 1]; 103 + val->intval = pdo_fixed_voltage(pdo) * 1000; 104 + } else { 105 + val->intval = 0; 106 + } 107 + break; 108 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: 109 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 110 + case UCSI_CONSTAT_PWR_OPMODE_BC: 111 + case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: 112 + val->intval = UCSI_TYPEC_VSAFE5V * 1000; 113 + break; 114 + default: 115 + val->intval = 0; 116 + break; 117 + } 118 + return 0; 119 + } 120 + 121 + static int ucsi_psy_get_current_max(struct ucsi_connector *con, 122 + union power_supply_propval *val) 123 + { 124 + u32 pdo; 125 + 126 + switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { 127 + case UCSI_CONSTAT_PWR_OPMODE_PD: 128 + if (con->num_pdos > 0) { 129 + pdo = con->src_pdos[con->num_pdos - 1]; 130 + val->intval = pdo_max_current(pdo) * 1000; 131 + } else { 132 + val->intval = 0; 133 + } 134 + break; 135 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 136 + val->intval = UCSI_TYPEC_1_5_CURRENT * 1000; 137 + break; 138 + case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: 139 + val->intval = UCSI_TYPEC_3_0_CURRENT * 1000; 140 + break; 141 + case UCSI_CONSTAT_PWR_OPMODE_BC: 142 + case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: 143 + /* UCSI can't tell b/w DCP/CDP or USB2/3x1/3x2 SDP chargers */ 144 + default: 145 + val->intval = 0; 146 + break; 147 + } 148 + return 0; 149 + } 150 + 151 + static int ucsi_psy_get_current_now(struct ucsi_connector *con, 152 + union power_supply_propval *val) 153 + { 154 + u16 flags = con->status.flags; 155 + 156 + if (UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD) 157 + val->intval = rdo_op_current(con->rdo) * 1000; 158 + else 159 + val->intval = 0; 160 + return 0; 161 + } 162 + 163 + static int ucsi_psy_get_usb_type(struct ucsi_connector *con, 164 + union power_supply_propval *val) 165 + { 166 + u16 flags = con->status.flags; 167 + 168 + val->intval = POWER_SUPPLY_USB_TYPE_C; 169 + if (flags & UCSI_CONSTAT_CONNECTED && 170 + UCSI_CONSTAT_PWR_OPMODE(flags) == UCSI_CONSTAT_PWR_OPMODE_PD) 171 + val->intval = POWER_SUPPLY_USB_TYPE_PD; 172 + 173 + return 0; 174 + } 175 + 176 + static int ucsi_psy_get_prop(struct power_supply *psy, 177 + enum power_supply_property psp, 178 + union power_supply_propval *val) 179 + { 180 + struct ucsi_connector *con = power_supply_get_drvdata(psy); 181 + 182 + switch (psp) { 183 + case POWER_SUPPLY_PROP_USB_TYPE: 184 + return ucsi_psy_get_usb_type(con, val); 185 + case POWER_SUPPLY_PROP_ONLINE: 186 + return ucsi_psy_get_online(con, val); 187 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 188 + return ucsi_psy_get_voltage_min(con, val); 189 + case POWER_SUPPLY_PROP_VOLTAGE_MAX: 190 + return ucsi_psy_get_voltage_max(con, val); 191 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 192 + return ucsi_psy_get_voltage_now(con, val); 193 + case POWER_SUPPLY_PROP_CURRENT_MAX: 194 + return ucsi_psy_get_current_max(con, val); 195 + case POWER_SUPPLY_PROP_CURRENT_NOW: 196 + return ucsi_psy_get_current_now(con, val); 197 + default: 198 + return -EINVAL; 199 + } 200 + } 201 + 202 + static enum power_supply_usb_type ucsi_psy_usb_types[] = { 203 + POWER_SUPPLY_USB_TYPE_C, 204 + POWER_SUPPLY_USB_TYPE_PD, 205 + POWER_SUPPLY_USB_TYPE_PD_PPS, 206 + }; 207 + 208 + int ucsi_register_port_psy(struct ucsi_connector *con) 209 + { 210 + struct power_supply_config psy_cfg = {}; 211 + struct device *dev = con->ucsi->dev; 212 + char *psy_name; 213 + 214 + psy_cfg.drv_data = con; 215 + psy_cfg.fwnode = dev_fwnode(dev); 216 + 217 + psy_name = devm_kasprintf(dev, GFP_KERNEL, "ucsi-source-psy-%s%d", 218 + dev_name(dev), con->num); 219 + if (!psy_name) 220 + return -ENOMEM; 221 + 222 + con->psy_desc.name = psy_name; 223 + con->psy_desc.type = POWER_SUPPLY_TYPE_USB, 224 + con->psy_desc.usb_types = ucsi_psy_usb_types; 225 + con->psy_desc.num_usb_types = ARRAY_SIZE(ucsi_psy_usb_types); 226 + con->psy_desc.properties = ucsi_psy_props, 227 + con->psy_desc.num_properties = ARRAY_SIZE(ucsi_psy_props), 228 + con->psy_desc.get_property = ucsi_psy_get_prop; 229 + 230 + con->psy = power_supply_register(dev, &con->psy_desc, &psy_cfg); 231 + 232 + return PTR_ERR_OR_ZERO(con->psy); 233 + } 234 + 235 + void ucsi_unregister_port_psy(struct ucsi_connector *con) 236 + { 237 + if (IS_ERR_OR_NULL(con->psy)) 238 + return; 239 + 240 + power_supply_unregister(con->psy); 241 + }
+5 -5
drivers/usb/typec/ucsi/trace.c
··· 35 35 36 36 const char *ucsi_cci_str(u32 cci) 37 37 { 38 - if (cci & GENMASK(7, 0)) { 39 - if (cci & BIT(29)) 38 + if (UCSI_CCI_CONNECTOR(cci)) { 39 + if (cci & UCSI_CCI_ACK_COMPLETE) 40 40 return "Event pending (ACK completed)"; 41 - if (cci & BIT(31)) 41 + if (cci & UCSI_CCI_COMMAND_COMPLETE) 42 42 return "Event pending (command completed)"; 43 43 return "Connector Change"; 44 44 } 45 - if (cci & BIT(29)) 45 + if (cci & UCSI_CCI_ACK_COMPLETE) 46 46 return "ACK completed"; 47 - if (cci & BIT(31)) 47 + if (cci & UCSI_CCI_COMMAND_COMPLETE) 48 48 return "Command completed"; 49 49 50 50 return "";
+40 -1
drivers/usb/typec/ucsi/ucsi.c
··· 492 492 } 493 493 } 494 494 495 + static void ucsi_get_pdos(struct ucsi_connector *con, int is_partner) 496 + { 497 + struct ucsi *ucsi = con->ucsi; 498 + u64 command; 499 + int ret; 500 + 501 + command = UCSI_COMMAND(UCSI_GET_PDOS) | UCSI_CONNECTOR_NUMBER(con->num); 502 + command |= UCSI_GET_PDOS_PARTNER_PDO(is_partner); 503 + command |= UCSI_GET_PDOS_NUM_PDOS(UCSI_MAX_PDOS - 1); 504 + command |= UCSI_GET_PDOS_SRC_PDOS; 505 + ret = ucsi_run_command(ucsi, command, con->src_pdos, 506 + sizeof(con->src_pdos)); 507 + if (ret < 0) { 508 + dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret); 509 + return; 510 + } 511 + con->num_pdos = ret / sizeof(u32); /* number of bytes to 32-bit PDOs */ 512 + if (ret == 0) 513 + dev_warn(ucsi->dev, "UCSI_GET_PDOS returned 0 bytes\n"); 514 + } 515 + 495 516 static void ucsi_pwr_opmode_change(struct ucsi_connector *con) 496 517 { 497 518 switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { 498 519 case UCSI_CONSTAT_PWR_OPMODE_PD: 520 + con->rdo = con->status.request_data_obj; 499 521 typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD); 522 + ucsi_get_pdos(con, 1); 500 523 break; 501 524 case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: 525 + con->rdo = 0; 502 526 typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_1_5A); 503 527 break; 504 528 case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: 529 + con->rdo = 0; 505 530 typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_3_0A); 506 531 break; 507 532 default: 533 + con->rdo = 0; 508 534 typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_USB); 509 535 break; 510 536 } ··· 592 566 593 567 switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { 594 568 case UCSI_CONSTAT_PARTNER_TYPE_UFP: 569 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE: 570 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: 595 571 typec_set_data_role(con->port, TYPEC_HOST); 596 572 break; 597 573 case UCSI_CONSTAT_PARTNER_TYPE_DFP: ··· 639 611 640 612 role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR); 641 613 642 - if (con->status.change & UCSI_CONSTAT_POWER_OPMODE_CHANGE) 614 + if (con->status.change & UCSI_CONSTAT_POWER_OPMODE_CHANGE || 615 + con->status.change & UCSI_CONSTAT_POWER_LEVEL_CHANGE) 643 616 ucsi_pwr_opmode_change(con); 644 617 645 618 if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) { ··· 656 627 657 628 switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { 658 629 case UCSI_CONSTAT_PARTNER_TYPE_UFP: 630 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE: 631 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: 659 632 typec_set_data_role(con->port, TYPEC_HOST); 660 633 break; 661 634 case UCSI_CONSTAT_PARTNER_TYPE_DFP: ··· 936 905 cap->driver_data = con; 937 906 cap->ops = &ucsi_ops; 938 907 908 + ret = ucsi_register_port_psy(con); 909 + if (ret) 910 + return ret; 911 + 939 912 /* Register the connector */ 940 913 con->port = typec_register_port(ucsi->dev, cap); 941 914 if (IS_ERR(con->port)) ··· 962 927 963 928 switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { 964 929 case UCSI_CONSTAT_PARTNER_TYPE_UFP: 930 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE: 931 + case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: 965 932 typec_set_data_role(con->port, TYPEC_HOST); 966 933 break; 967 934 case UCSI_CONSTAT_PARTNER_TYPE_DFP: ··· 1066 1029 for (con = ucsi->connector; con->port; con++) { 1067 1030 ucsi_unregister_partner(con); 1068 1031 ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); 1032 + ucsi_unregister_port_psy(con); 1069 1033 typec_unregister_port(con->port); 1070 1034 con->port = NULL; 1071 1035 } ··· 1190 1152 ucsi_unregister_partner(&ucsi->connector[i]); 1191 1153 ucsi_unregister_altmodes(&ucsi->connector[i], 1192 1154 UCSI_RECIPIENT_CON); 1155 + ucsi_unregister_port_psy(&ucsi->connector[i]); 1193 1156 typec_unregister_port(ucsi->connector[i].port); 1194 1157 } 1195 1158
+25 -1
drivers/usb/typec/ucsi/ucsi.h
··· 5 5 6 6 #include <linux/bitops.h> 7 7 #include <linux/device.h> 8 + #include <linux/power_supply.h> 8 9 #include <linux/types.h> 9 10 #include <linux/usb/typec.h> 10 11 ··· 22 21 #define UCSI_MESSAGE_OUT 32 23 22 24 23 /* Command Status and Connector Change Indication (CCI) bits */ 25 - #define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 0)) >> 1) 24 + #define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 1)) >> 1) 26 25 #define UCSI_CCI_LENGTH(_c_) (((_c_) & GENMASK(15, 8)) >> 8) 27 26 #define UCSI_CCI_NOT_SUPPORTED BIT(25) 28 27 #define UCSI_CCI_CANCEL_COMPLETE BIT(26) ··· 130 129 #define UCSI_ALTMODE_OFFSET(_r_) (((_r_) >> 32) & 0xff) 131 130 #define UCSI_GET_ALTMODE_OFFSET(_r_) ((u64)(_r_) << 32) 132 131 #define UCSI_GET_ALTMODE_NUM_ALTMODES(_r_) ((u64)(_r_) << 40) 132 + 133 + /* GET_PDOS command bits */ 134 + #define UCSI_GET_PDOS_PARTNER_PDO(_r_) ((u64)(_r_) << 23) 135 + #define UCSI_GET_PDOS_NUM_PDOS(_r_) ((u64)(_r_) << 32) 136 + #define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34) 133 137 134 138 /* -------------------------------------------------------------------------- */ 135 139 ··· 300 294 301 295 #define UCSI_MAX_SVID 5 302 296 #define UCSI_MAX_ALTMODES (UCSI_MAX_SVID * 6) 297 + #define UCSI_MAX_PDOS (4) 298 + 299 + #define UCSI_TYPEC_VSAFE5V 5000 300 + #define UCSI_TYPEC_1_5_CURRENT 1500 301 + #define UCSI_TYPEC_3_0_CURRENT 3000 303 302 304 303 struct ucsi_connector { 305 304 int num; ··· 324 313 325 314 struct ucsi_connector_status status; 326 315 struct ucsi_connector_capability cap; 316 + struct power_supply *psy; 317 + struct power_supply_desc psy_desc; 318 + u32 rdo; 319 + u32 src_pdos[UCSI_MAX_PDOS]; 320 + int num_pdos; 327 321 }; 328 322 329 323 int ucsi_send_command(struct ucsi *ucsi, u64 command, ··· 336 320 337 321 void ucsi_altmode_update_active(struct ucsi_connector *con); 338 322 int ucsi_resume(struct ucsi *ucsi); 323 + 324 + #if IS_ENABLED(CONFIG_POWER_SUPPLY) 325 + int ucsi_register_port_psy(struct ucsi_connector *con); 326 + void ucsi_unregister_port_psy(struct ucsi_connector *con); 327 + #else 328 + static inline int ucsi_register_port_psy(struct ucsi_connector *con) { return 0; } 329 + static inline void ucsi_unregister_port_psy(struct ucsi_connector *con) { } 330 + #endif /* CONFIG_POWER_SUPPLY */ 339 331 340 332 #if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE) 341 333 struct typec_altmode *
+1
include/dt-bindings/phy/phy.h
··· 17 17 #define PHY_TYPE_USB3 4 18 18 #define PHY_TYPE_UFS 5 19 19 #define PHY_TYPE_DP 6 20 + #define PHY_TYPE_XPCS 7 20 21 21 22 #endif /* _DT_BINDINGS_PHY */
+2 -67
include/linux/phy/omap_usb.h
··· 2 2 /* 3 3 * omap_usb.h -- omap usb2 phy header file 4 4 * 5 - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com 5 + * Copyright (C) 2012-2020 Texas Instruments Incorporated - http://www.ti.com 6 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 7 */ 8 8 9 9 #ifndef __DRIVERS_OMAP_USB2_H 10 10 #define __DRIVERS_OMAP_USB2_H 11 11 12 - #include <linux/io.h> 13 - #include <linux/usb/otg.h> 14 - 15 - struct usb_dpll_params { 16 - u16 m; 17 - u8 n; 18 - u8 freq:3; 19 - u8 sd; 20 - u32 mf; 21 - }; 22 - 23 - enum omap_usb_phy_type { 24 - TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ 25 - TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ 26 - TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ 27 - }; 28 - 29 - struct omap_usb { 30 - struct usb_phy phy; 31 - struct phy_companion *comparator; 32 - void __iomem *pll_ctrl_base; 33 - void __iomem *phy_base; 34 - struct device *dev; 35 - struct device *control_dev; 36 - struct clk *wkupclk; 37 - struct clk *optclk; 38 - u8 flags; 39 - enum omap_usb_phy_type type; 40 - struct regmap *syscon_phy_power; /* ctrl. reg. acces */ 41 - unsigned int power_reg; /* power reg. index within syscon */ 42 - u32 mask; 43 - u32 power_on; 44 - u32 power_off; 45 - }; 46 - 47 - struct usb_phy_data { 48 - const char *label; 49 - u8 flags; 50 - u32 mask; 51 - u32 power_on; 52 - u32 power_off; 53 - }; 54 - 55 - /* Driver Flags */ 56 - #define OMAP_USB2_HAS_START_SRP (1 << 0) 57 - #define OMAP_USB2_HAS_SET_VBUS (1 << 1) 58 - #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT (1 << 2) 59 - 60 - #define OMAP_DEV_PHY_PD BIT(0) 61 - #define OMAP_USB2_PHY_PD BIT(28) 62 - 63 - #define AM437X_USB2_PHY_PD BIT(0) 64 - #define AM437X_USB2_OTG_PD BIT(1) 65 - #define AM437X_USB2_OTGVDET_EN BIT(19) 66 - #define AM437X_USB2_OTGSESSEND_EN BIT(20) 12 + #include <linux/usb/phy_companion.h> 67 13 68 14 #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) 69 15 ··· 21 75 return -ENODEV; 22 76 } 23 77 #endif 24 - 25 - static inline u32 omap_usb_readl(void __iomem *addr, unsigned offset) 26 - { 27 - return __raw_readl(addr + offset); 28 - } 29 - 30 - static inline void omap_usb_writel(void __iomem *addr, unsigned offset, 31 - u32 data) 32 - { 33 - __raw_writel(data, addr + offset); 34 - } 35 78 36 79 #endif /* __DRIVERS_OMAP_USB_H */
+1 -1
include/linux/thunderbolt.h
··· 80 80 int index; 81 81 enum tb_security_level security_level; 82 82 size_t nboot_acl; 83 - unsigned long privdata[0]; 83 + unsigned long privdata[]; 84 84 }; 85 85 86 86 extern struct bus_type tb_bus_type;
+1
include/linux/usb/chipidea.h
··· 67 67 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 68 68 #define CI_HDRC_IMX_HSIC_ACTIVE_EVENT 2 69 69 #define CI_HDRC_IMX_HSIC_SUSPEND_EVENT 3 70 + #define CI_HDRC_CONTROLLER_VBUS_EVENT 4 70 71 int (*notify_event) (struct ci_hdrc *ci, unsigned event); 71 72 struct regulator *reg_vbus; 72 73 struct usb_otg_caps ci_otg_caps;
+3
include/linux/usb/composite.h
··· 249 249 250 250 int usb_interface_id(struct usb_configuration *, struct usb_function *); 251 251 252 + int config_ep_by_speed_and_alt(struct usb_gadget *g, struct usb_function *f, 253 + struct usb_ep *_ep, u8 alt); 254 + 252 255 int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, 253 256 struct usb_ep *_ep); 254 257
+8
include/linux/usb/gadget.h
··· 42 42 * @num_mapped_sgs: number of SG entries mapped to DMA (internal) 43 43 * @length: Length of that data 44 44 * @stream_id: The stream id, when USB3.0 bulk streams are being used 45 + * @is_last: Indicates if this is the last request of a stream_id before 46 + * switching to a different stream (required for DWC3 controllers). 45 47 * @no_interrupt: If true, hints that no completion irq is needed. 46 48 * Helpful sometimes with deep request queues that are handled 47 49 * directly by DMA controllers. ··· 106 104 unsigned num_mapped_sgs; 107 105 108 106 unsigned stream_id:16; 107 + unsigned is_last:1; 109 108 unsigned no_interrupt:1; 110 109 unsigned zero:1; 111 110 unsigned short_not_ok:1; ··· 376 373 * @connected: True if gadget is connected. 377 374 * @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag 378 375 * indicates that it supports LPM as per the LPM ECN & errata. 376 + * @irq: the interrupt number for device controller. 379 377 * 380 378 * Gadgets have a mostly-portable "gadget driver" implementing device 381 379 * functions, handling all usb configurations and interfaces. Gadget ··· 431 427 unsigned deactivated:1; 432 428 unsigned connected:1; 433 429 unsigned lpm_capable:1; 430 + int irq; 434 431 }; 435 432 #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) 436 433 ··· 777 772 778 773 /* put descriptor for string with that id into buf (buflen >= 256) */ 779 774 int usb_gadget_get_string(const struct usb_gadget_strings *table, int id, u8 *buf); 775 + 776 + /* check if the given language identifier is valid */ 777 + bool usb_validate_langid(u16 langid); 780 778 781 779 /*-------------------------------------------------------------------------*/ 782 780
+2 -1
include/linux/usb/hcd.h
··· 479 479 struct pci_dev; 480 480 struct pci_device_id; 481 481 extern int usb_hcd_pci_probe(struct pci_dev *dev, 482 - const struct pci_device_id *id); 482 + const struct pci_device_id *id, 483 + const struct hc_driver *driver); 483 484 extern void usb_hcd_pci_remove(struct pci_dev *dev); 484 485 extern void usb_hcd_pci_shutdown(struct pci_dev *dev); 485 486
+1
include/linux/usb/typec.h
··· 254 254 255 255 void *typec_get_drvdata(struct typec_port *port); 256 256 257 + int typec_find_orientation(const char *name); 257 258 int typec_find_port_power_role(const char *name); 258 259 int typec_find_power_role(const char *name); 259 260 int typec_find_port_data_role(const char *name);