Commit 7afb9d76 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull phy updates from Vinod Koul:
 "New Support:
   - Debugfs support for phy core and mediatek driver
   - Hisilicon inno-usb2-phy driver supporting Hi3798MV100
   - Qualcomm SGMII SerDes PHY driver, SM6115 & QCM2290 QMP-USB support,
     SA8775P USB PHY & USB3 UNI support, QUSB2 support for IPQ9574,
     IPQ9574 USB3 PHY

  UpdatesL
   - Sparx5 serdes phy power optimzation
   - cadence salvo usb properties and updates and torrent DP with PCIe &
     USB support
   - Yaml conversion for Broadcom kona USB bindings and MXS USB binding"

* tag 'phy-for-6.5_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (67 commits)
  dt-bindings: phy: brcm,brcmstb-usb-phy: Fix error in "compatible" conditional schema
  dt-bindings: phy: mixel,mipi-dsi-phy: Remove assigned-clock* properties
  dt-bindings: phy: intel,combo-phy: restrict node name suffixes
  dt-bindings: phy: qcom,usb-hs-phy: Add compatible
  phy: tegra: xusb: check return value of devm_kzalloc()
  phy: qcom: qmp-combo: fix Display Port PHY configuration for SM8550
  phy: qcom: add the SGMII SerDes PHY driver
  dt-bindings: phy: describe the Qualcomm SGMII PHY
  phy: qualcomm: fix indentation in Makefile
  phy: usb: suppress OC condition for 7439b2
  phy: usb: Turn off phy when port is in suspend
  phy: tegra: xusb: Clear the driver reference in usb-phy dev
  dt-bindings: phy: mxs-usb-phy: add imx8ulp and imx8qm compatible
  dt-bindings: phy: mxs-usb-phy: convert to DT schema format
  dt-bindings: phy: qcom,qmp-usb: fix bindings error
  dt-bindings: phy: qcom,qmp-ufs: fix the sc8180x regs
  dt-bindings: phy: qcom,qmp-pcie: fix the sc8180x regs
  phy: mediatek: tphy: add debugfs files
  phy: core: add debugfs files
  phy: fsl-imx8mp-usb: add support for phy tuning
  ...
parents 68433066 a454850a
...@@ -115,8 +115,8 @@ allOf: ...@@ -115,8 +115,8 @@ allOf:
compatible: compatible:
contains: contains:
enum: enum:
- const: brcm,bcm4908-usb-phy - brcm,bcm4908-usb-phy
- const: brcm,brcmstb-usb-phy - brcm,brcmstb-usb-phy
then: then:
properties: properties:
reg: reg:
......
BROADCOM KONA USB2 PHY
Required properties:
- compatible: brcm,kona-usb2-phy
- reg: offset and length of the PHY registers
- #phy-cells: must be 0
Refer to phy/phy-bindings.txt for the generic PHY binding properties
Example:
usbphy: usb-phy@3f130000 {
compatible = "brcm,kona-usb2-phy";
reg = <0x3f130000 0x28>;
#phy-cells = <0>;
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/brcm,kona-usb2-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom Kona family USB 2.0 PHY
maintainers:
- Florian Fainelli <f.fainelli@gmail.com>
properties:
compatible:
const: brcm,kona-usb2-phy
reg:
maxItems: 1
'#phy-cells':
const: 0
required:
- compatible
- reg
- '#phy-cells'
additionalProperties: false
examples:
- |
usb-phy@3f130000 {
compatible = "brcm,kona-usb2-phy";
reg = <0x3f130000 0x28>;
#phy-cells = <0>;
};
...
...@@ -31,6 +31,12 @@ properties: ...@@ -31,6 +31,12 @@ properties:
"#phy-cells": "#phy-cells":
const: 0 const: 0
cdns,usb2-disconnect-threshold-microvolt:
description: The microvolt threshold value utilized for detecting
USB disconnection event.
enum: [575, 610, 645]
default: 575
required: required:
- compatible - compatible
- reg - reg
......
...@@ -35,6 +35,53 @@ properties: ...@@ -35,6 +35,53 @@ properties:
description: description:
A phandle to the regulator for USB VBUS. A phandle to the regulator for USB VBUS.
fsl,phy-tx-vref-tune-percent:
description:
Tunes the HS DC level relative to the nominal level
minimum: 94
maximum: 124
fsl,phy-tx-rise-tune-percent:
description:
Adjusts the rise/fall time duration of the HS waveform relative to
its nominal value
minimum: 97
maximum: 103
fsl,phy-tx-preemp-amp-tune-microamp:
description:
Adjust amount of current sourced to DPn and DMn after a J-to-K
or K-to-J transition. Default is 0 (disabled).
minimum: 0
maximum: 1800
fsl,phy-tx-vboost-level-microvolt:
description:
Adjust the boosted transmit launch pk-pk differential amplitude
minimum: 880
maximum: 1120
fsl,phy-comp-dis-tune-percent:
description:
Adjust the voltage level used to detect a disconnect event at the host
relative to the nominal value
minimum: 91
maximum: 115
fsl,phy-pcs-tx-deemph-3p5db-attenuation-db:
description:
Adjust TX de-emphasis attenuation in dB at nominal
3.5dB point as per USB specification
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 36
fsl,phy-pcs-tx-swing-full-percent:
description:
Scaling of the voltage defined by fsl,phy-tx-vboost-level-microvolt
minimum: 0
maximum: 100
required: required:
- compatible - compatible
- reg - reg
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/fsl,mxs-usbphy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale MXS USB Phy Device
maintainers:
- Xu Yang <xu.yang_2@nxp.com>
properties:
compatible:
oneOf:
- enum:
- fsl,imx23-usbphy
- fsl,imx7ulp-usbphy
- fsl,vf610-usbphy
- items:
- enum:
- fsl,imx28-usbphy
- fsl,imx6ul-usbphy
- fsl,imx6sl-usbphy
- fsl,imx6sx-usbphy
- fsl,imx6q-usbphy
- const: fsl,imx23-usbphy
- items:
- const: fsl,imx6sll-usbphy
- const: fsl,imx6ul-usbphy
- const: fsl,imx23-usbphy
- items:
- enum:
- fsl,imx8dxl-usbphy
- fsl,imx8qm-usbphy
- fsl,imx8ulp-usbphy
- const: fsl,imx7ulp-usbphy
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
'#phy-cells':
const: 0
power-domains:
maxItems: 1
fsl,anatop:
description:
phandle for anatop register, it is only for imx6 SoC series.
$ref: /schemas/types.yaml#/definitions/phandle
phy-3p0-supply:
description:
One of USB PHY's power supply. Can be used to keep a good signal
quality.
fsl,tx-cal-45-dn-ohms:
description:
Resistance (in ohms) of switchable high-speed trimming resistor
connected in parallel with the 45 ohm resistor that terminates
the DN output signal.
minimum: 35
maximum: 54
default: 45
fsl,tx-cal-45-dp-ohms:
description:
Resistance (in ohms) of switchable high-speed trimming resistor
connected in parallel with the 45 ohm resistor that terminates
the DP output signal.
minimum: 35
maximum: 54
default: 45
fsl,tx-d-cal:
description:
Current trimming value (as a percentage) of the 17.78 mA TX
reference current.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 79
maximum: 119
default: 100
required:
- compatible
- reg
- clocks
allOf:
- if:
properties:
compatible:
oneOf:
- enum:
- fsl,imx6q-usbphy
- fsl,imx6sl-usbphy
- fsl,imx6sx-usbphy
- fsl,imx6sll-usbphy
- fsl,vf610-usbphy
- items:
- const: fsl,imx6ul-usbphy
- const: fsl,imx23-usbphy
then:
required:
- fsl,anatop
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/imx6qdl-clock.h>
usbphy1: usb-phy@20c9000 {
compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
reg = <0x020c9000 0x1000>;
clocks = <&clks IMX6QDL_CLK_USBPHY1>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
fsl,anatop = <&anatop>;
};
...
...@@ -15,7 +15,7 @@ description: | ...@@ -15,7 +15,7 @@ description: |
properties: properties:
$nodename: $nodename:
pattern: "combophy(@.*|-[0-9a-f])*$" pattern: "combophy(@.*|-([0-9]|[1-9][0-9]+))?$"
compatible: compatible:
items: items:
......
...@@ -32,15 +32,6 @@ properties: ...@@ -32,15 +32,6 @@ properties:
clock-names: clock-names:
const: phy_ref const: phy_ref
assigned-clocks:
maxItems: 1
assigned-clock-parents:
maxItems: 1
assigned-clock-rates:
maxItems: 1
"#phy-cells": "#phy-cells":
const: 0 const: 0
......
* Freescale MXS USB Phy Device
Required properties:
- compatible: should contain:
* "fsl,imx23-usbphy" for imx23 and imx28
* "fsl,imx6q-usbphy" for imx6dq and imx6dl
* "fsl,imx6sl-usbphy" for imx6sl
* "fsl,vf610-usbphy" for Vybrid vf610
* "fsl,imx6sx-usbphy" for imx6sx
* "fsl,imx7ulp-usbphy" for imx7ulp
* "fsl,imx8dxl-usbphy" for imx8dxl
"fsl,imx23-usbphy" is still a fallback for other strings
- reg: Should contain registers location and length
- interrupts: Should contain phy interrupt
- fsl,anatop: phandle for anatop register, it is only for imx6 SoC series
Optional properties:
- fsl,tx-cal-45-dn-ohms: Integer [35-54]. Resistance (in ohms) of switchable
high-speed trimming resistor connected in parallel with the 45 ohm resistor
that terminates the DN output signal. Default: 45
- fsl,tx-cal-45-dp-ohms: Integer [35-54]. Resistance (in ohms) of switchable
high-speed trimming resistor connected in parallel with the 45 ohm resistor
that terminates the DP output signal. Default: 45
- fsl,tx-d-cal: Integer [79-119]. Current trimming value (as a percentage) of
the 17.78mA TX reference current. Default: 100
Example:
usbphy1: usb-phy@20c9000 {
compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
reg = <0x020c9000 0x1000>;
interrupts = <0 44 0x04>;
fsl,anatop = <&anatop>;
};
...@@ -43,6 +43,9 @@ properties: ...@@ -43,6 +43,9 @@ properties:
"#phy-cells": "#phy-cells":
const: 0 const: 0
power-domains:
maxItems: 1
vdda-phy-supply: true vdda-phy-supply: true
vdda-pll-supply: true vdda-pll-supply: true
......
...@@ -203,6 +203,7 @@ allOf: ...@@ -203,6 +203,7 @@ allOf:
compatible: compatible:
contains: contains:
enum: enum:
- qcom,sc8180x-qmp-pcie-phy
- qcom,sm8250-qmp-gen3x2-pcie-phy - qcom,sm8250-qmp-gen3x2-pcie-phy
- qcom,sm8250-qmp-modem-pcie-phy - qcom,sm8250-qmp-modem-pcie-phy
- qcom,sm8450-qmp-gen4x2-pcie-phy - qcom,sm8450-qmp-gen4x2-pcie-phy
...@@ -224,7 +225,6 @@ allOf: ...@@ -224,7 +225,6 @@ allOf:
compatible: compatible:
contains: contains:
enum: enum:
- qcom,sc8180x-qmp-pcie-phy
- qcom,sdm845-qmp-pcie-phy - qcom,sdm845-qmp-pcie-phy
- qcom,sdx55-qmp-pcie-phy - qcom,sdx55-qmp-pcie-phy
- qcom,sm8250-qmp-gen3x1-pcie-phy - qcom,sm8250-qmp-gen3x1-pcie-phy
......
...@@ -160,6 +160,7 @@ allOf: ...@@ -160,6 +160,7 @@ allOf:
contains: contains:
enum: enum:
- qcom,msm8998-qmp-ufs-phy - qcom,msm8998-qmp-ufs-phy
- qcom,sc8180x-qmp-ufs-phy
- qcom,sdm845-qmp-ufs-phy - qcom,sdm845-qmp-ufs-phy
- qcom,sm6350-qmp-ufs-phy - qcom,sm6350-qmp-ufs-phy
- qcom,sm8150-qmp-ufs-phy - qcom,sm8150-qmp-ufs-phy
...@@ -178,23 +179,6 @@ allOf: ...@@ -178,23 +179,6 @@ allOf:
- description: TX lane 2 - description: TX lane 2
- description: RX lane 2 - description: RX lane 2
- if:
properties:
compatible:
contains:
enum:
- qcom,sc8180x-qmp-ufs-phy
then:
patternProperties:
"^phy@[0-9a-f]+$":
properties:
reg:
items:
- description: TX
- description: RX
- description: PCS
- description: PCS_MISC
- if: - if:
properties: properties:
compatible: compatible:
......
...@@ -23,14 +23,12 @@ properties: ...@@ -23,14 +23,12 @@ properties:
- qcom,ipq8074-qmp-usb3-phy - qcom,ipq8074-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy - qcom,msm8996-qmp-usb3-phy
- qcom,msm8998-qmp-usb3-phy - qcom,msm8998-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sc7180-qmp-usb3-phy - qcom,sc7180-qmp-usb3-phy
- qcom,sc8180x-qmp-usb3-phy - qcom,sc8180x-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-phy - qcom,sdm845-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-uni-phy - qcom,sdm845-qmp-usb3-uni-phy
- qcom,sdx55-qmp-usb3-uni-phy - qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy - qcom,sdx65-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-phy - qcom,sm8150-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy - qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy - qcom,sm8250-qmp-usb3-phy
...@@ -248,29 +246,6 @@ allOf: ...@@ -248,29 +246,6 @@ allOf:
- const: phy - const: phy
- const: common - const: common
- if:
properties:
compatible:
contains:
enum:
- qcom,qcm2290-qmp-usb3-phy
- qcom,sm6115-qmp-usb3-phy
then:
properties:
clocks:
maxItems: 3
clock-names:
items:
- const: cfg_ahb
- const: ref
- const: com_aux
resets:
maxItems: 2
reset-names:
items:
- const: phy_phy
- const: phy
- if: - if:
properties: properties:
compatible: compatible:
...@@ -318,12 +293,10 @@ allOf: ...@@ -318,12 +293,10 @@ allOf:
enum: enum:
- qcom,ipq6018-qmp-usb3-phy - qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy - qcom,ipq8074-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sc7180-qmp-usb3-phy - qcom,sc7180-qmp-usb3-phy
- qcom,sc8180x-qmp-usb3-phy - qcom,sc8180x-qmp-usb3-phy
- qcom,sdx55-qmp-usb3-uni-phy - qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy - qcom,sdx65-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy - qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy - qcom,sm8250-qmp-usb3-phy
then: then:
......
...@@ -18,13 +18,14 @@ properties: ...@@ -18,13 +18,14 @@ properties:
oneOf: oneOf:
- items: - items:
- enum: - enum:
- qcom,ipq6018-qusb2-phy
- qcom,ipq8074-qusb2-phy - qcom,ipq8074-qusb2-phy
- qcom,ipq9574-qusb2-phy
- qcom,msm8953-qusb2-phy - qcom,msm8953-qusb2-phy
- qcom,msm8996-qusb2-phy - qcom,msm8996-qusb2-phy
- qcom,msm8998-qusb2-phy - qcom,msm8998-qusb2-phy
- qcom,qcm2290-qusb2-phy - qcom,qcm2290-qusb2-phy
- qcom,sdm660-qusb2-phy - qcom,sdm660-qusb2-phy
- qcom,ipq6018-qusb2-phy
- qcom,sm4250-qusb2-phy - qcom,sm4250-qusb2-phy
- qcom,sm6115-qusb2-phy - qcom,sm6115-qusb2-phy
- items: - items:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/qcom,sa8775p-dwmac-sgmii-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SerDes/SGMII ethernet PHY controller
maintainers:
- Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
description:
The SerDes PHY sits between the MAC and the external PHY and provides
separate Rx Tx lines.
properties:
compatible:
const: qcom,sa8775p-dwmac-sgmii-phy
reg:
items:
- description: serdes
clocks:
maxItems: 1
clock-names:
const: sgmi_ref
phy-supply:
description:
Phandle to a regulator that provides power to the PHY.
"#phy-cells":
const: 0
required:
- compatible
- reg
- "#phy-cells"
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
serdes_phy: phy@8901000 {
compatible = "qcom,sa8775p-dwmac-sgmii-phy";
reg = <0x08901000 0xe10>;
clocks = <&gcc GCC_SGMI_CLKREF_EN>;
clock-names = "sgmi_ref";
#phy-cells = <0>;
};
...@@ -78,9 +78,9 @@ allOf: ...@@ -78,9 +78,9 @@ allOf:
then: then:
properties: properties:
clocks: clocks:
maxItems: 3 minItems: 3
clock-names: clock-names:
maxItems: 3 minItems: 3
else: else:
properties: properties:
clocks: clocks:
......
...@@ -16,7 +16,11 @@ description: ...@@ -16,7 +16,11 @@ description:
properties: properties:
compatible: compatible:
enum: enum:
- qcom,ipq9574-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8280xp-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
reg: reg:
maxItems: 1 maxItems: 1
...@@ -25,11 +29,7 @@ properties: ...@@ -25,11 +29,7 @@ properties:
maxItems: 4 maxItems: 4
clock-names: clock-names:
items: maxItems: 4
- const: aux
- const: ref
- const: com_aux
- const: pipe
power-domains: power-domains:
maxItems: 1 maxItems: 1
...@@ -60,7 +60,6 @@ required: ...@@ -60,7 +60,6 @@ required:
- reg - reg
- clocks - clocks
- clock-names - clock-names
- power-domains
- resets - resets
- reset-names - reset-names
- vdda-phy-supply - vdda-phy-supply
...@@ -69,6 +68,60 @@ required: ...@@ -69,6 +68,60 @@ required:
- clock-output-names - clock-output-names
- "#phy-cells" - "#phy-cells"
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,ipq9574-qmp-usb3-phy
then:
properties:
clock-names:
items:
- const: aux
- const: ref
- const: cfg_ahb
- const: pipe
- if:
properties:
compatible:
contains:
enum:
- qcom,qcm2290-qmp-usb3-phy
- qcom,sm6115-qmp-usb3-phy
then:
properties:
clocks:
maxItems: 4
clock-names:
items:
- const: cfg_ahb
- const: ref
- const: com_aux
- const: pipe
- if:
properties:
compatible:
contains:
enum:
- qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8280xp-qmp-usb3-uni-phy
then:
properties:
clocks:
maxItems: 4
clock-names:
items:
- const: aux
- const: ref
- const: com_aux
- const: pipe
required:
- power-domains
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -60,6 +60,26 @@ properties: ...@@ -60,6 +60,26 @@ properties:
description: description:
See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h
orientation-switch:
description:
Flag the PHY as possible handler of USB Type-C orientation switching
type: boolean
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Output endpoint of the PHY
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: Incoming endpoint from the USB controller
port@2:
$ref: /schemas/graph.yaml#/properties/port
description: Incoming endpoint from the DisplayPort controller
required: required:
- compatible - compatible
- reg - reg
...@@ -98,6 +118,37 @@ examples: ...@@ -98,6 +118,37 @@ examples:
vdda-phy-supply = <&vreg_l9d>; vdda-phy-supply = <&vreg_l9d>;
vdda-pll-supply = <&vreg_l4d>; vdda-pll-supply = <&vreg_l4d>;
orientation-switch;
#clock-cells = <1>; #clock-cells = <1>;
#phy-cells = <1>; #phy-cells = <1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&typec_connector_ss>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&dwc3_ss_out>;
};
};
port@2 {
reg = <2>;
endpoint {
remote-endpoint = <&mdss_dp_out>;
};
};
};
}; };
...@@ -13,7 +13,9 @@ if: ...@@ -13,7 +13,9 @@ if:
properties: properties:
compatible: compatible:
contains: contains:
const: qcom,usb-hs-phy-apq8064 enum:
- qcom,usb-hs-phy-apq8064
- qcom,usb-hs-phy-msm8960
then: then:
properties: properties:
resets: resets:
...@@ -40,6 +42,7 @@ properties: ...@@ -40,6 +42,7 @@ properties:
- qcom,usb-hs-phy-apq8064 - qcom,usb-hs-phy-apq8064
- qcom,usb-hs-phy-msm8226 - qcom,usb-hs-phy-msm8226
- qcom,usb-hs-phy-msm8916 - qcom,usb-hs-phy-msm8916
- qcom,usb-hs-phy-msm8960
- qcom,usb-hs-phy-msm8974 - qcom,usb-hs-phy-msm8974
- const: qcom,usb-hs-phy - const: qcom,usb-hs-phy
......
...@@ -20,6 +20,7 @@ properties: ...@@ -20,6 +20,7 @@ properties:
- qcom,usb-snps-femto-v2-phy - qcom,usb-snps-femto-v2-phy
- items: - items:
- enum: - enum:
- qcom,sa8775p-usb-hs-phy
- qcom,sc8280xp-usb-hs-phy - qcom,sc8280xp-usb-hs-phy
- const: qcom,usb-snps-hs-5nm-phy - const: qcom,usb-snps-hs-5nm-phy
- items: - items:
......
...@@ -24,6 +24,7 @@ properties: ...@@ -24,6 +24,7 @@ properties:
- qcom,msm8998-dwc3 - qcom,msm8998-dwc3
- qcom,qcm2290-dwc3 - qcom,qcm2290-dwc3
- qcom,qcs404-dwc3 - qcom,qcs404-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3 - qcom,sc7180-dwc3
- qcom,sc7280-dwc3 - qcom,sc7280-dwc3
- qcom,sc8280xp-dwc3 - qcom,sc8280xp-dwc3
...@@ -181,6 +182,7 @@ allOf: ...@@ -181,6 +182,7 @@ allOf:
- qcom,msm8953-dwc3 - qcom,msm8953-dwc3
- qcom,msm8996-dwc3 - qcom,msm8996-dwc3
- qcom,msm8998-dwc3 - qcom,msm8998-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3 - qcom,sc7180-dwc3
- qcom,sc7280-dwc3 - qcom,sc7280-dwc3
- qcom,sdm670-dwc3 - qcom,sdm670-dwc3
...@@ -456,6 +458,25 @@ allOf: ...@@ -456,6 +458,25 @@ allOf:
- const: dm_hs_phy_irq - const: dm_hs_phy_irq
- const: ss_phy_irq - const: ss_phy_irq
- if:
properties:
compatible:
contains:
enum:
- qcom,sa8775p-dwc3
then:
properties:
interrupts:
minItems: 3
maxItems: 4
interrupt-names:
minItems: 3
items:
- const: pwr_event
- const: dp_hs_phy_irq
- const: dm_hs_phy_irq
- const: ss_phy_irq
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -172,10 +172,16 @@ static int phy_meson_g12a_usb2_init(struct phy *phy) ...@@ -172,10 +172,16 @@ static int phy_meson_g12a_usb2_init(struct phy *phy)
int ret; int ret;
unsigned int value; unsigned int value;
ret = reset_control_reset(priv->reset); ret = clk_prepare_enable(priv->clk);
if (ret) if (ret)
return ret; return ret;
ret = reset_control_reset(priv->reset);
if (ret) {
clk_disable_unprepare(priv->clk);
return ret;
}
udelay(RESET_COMPLETE_TIME); udelay(RESET_COMPLETE_TIME);
/* usb2_otg_aca_en == 0 */ /* usb2_otg_aca_en == 0 */
...@@ -277,8 +283,13 @@ static int phy_meson_g12a_usb2_init(struct phy *phy) ...@@ -277,8 +283,13 @@ static int phy_meson_g12a_usb2_init(struct phy *phy)
static int phy_meson_g12a_usb2_exit(struct phy *phy) static int phy_meson_g12a_usb2_exit(struct phy *phy)
{ {
struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy);
int ret;
ret = reset_control_reset(priv->reset);
if (!ret)
clk_disable_unprepare(priv->clk);
return reset_control_reset(priv->reset); return ret;
} }
/* set_mode is not needed, mode setting is handled via the UTMI bus */ /* set_mode is not needed, mode setting is handled via the UTMI bus */
......
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
#define USB_CTLR_TP_DIAG1_wake_MASK BIT(1) #define USB_CTLR_TP_DIAG1_wake_MASK BIT(1)
#define USB_CTRL_CTLR_CSHCR 0x50 #define USB_CTRL_CTLR_CSHCR 0x50
#define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK BIT(18) #define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK BIT(18)
#define USB_CTRL_P0_U2PHY_CFG1 0x68
#define USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK BIT(10)
/* Register definitions for the USB_PHY block in 7211b0 */ /* Register definitions for the USB_PHY block in 7211b0 */
#define USB_PHY_PLL_CTL 0x00 #define USB_PHY_PLL_CTL 0x00
...@@ -90,6 +92,8 @@ ...@@ -90,6 +92,8 @@
#define BDC_EC_AXIRDA_RTS_MASK GENMASK(31, 28) #define BDC_EC_AXIRDA_RTS_MASK GENMASK(31, 28)
#define BDC_EC_AXIRDA_RTS_SHIFT 28 #define BDC_EC_AXIRDA_RTS_SHIFT 28
#define USB_XHCI_GBL_GUSB2PHYCFG 0x100
#define USB_XHCI_GBL_GUSB2PHYCFG_U2_FREECLK_EXISTS_MASK BIT(30)
static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params, static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
uint8_t addr, uint16_t data) uint8_t addr, uint16_t data)
...@@ -140,13 +144,17 @@ static void xhci_soft_reset(struct brcm_usb_init_params *params, ...@@ -140,13 +144,17 @@ static void xhci_soft_reset(struct brcm_usb_init_params *params,
int on_off) int on_off)
{ {
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
void __iomem *xhci_gbl = params->regs[BRCM_REGS_XHCI_GBL];
/* Assert reset */ /* Assert reset */
if (on_off) if (on_off) {
USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB); USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
/* De-assert reset */ /* De-assert reset */
else } else {
USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB); USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
/* Required for COMMONONN to be set */
USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG, U2_FREECLK_EXISTS);
}
} }
static void usb_init_ipp(struct brcm_usb_init_params *params) static void usb_init_ipp(struct brcm_usb_init_params *params)
...@@ -320,6 +328,9 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params) ...@@ -320,6 +328,9 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params)
/* 1 millisecond - for USB clocks to settle down */ /* 1 millisecond - for USB clocks to settle down */
usleep_range(1000, 2000); usleep_range(1000, 2000);
/* Disable PHY when port is suspended */
USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN);
usb_wake_enable_7216(params, false); usb_wake_enable_7216(params, false);
usb_init_common(params); usb_init_common(params);
} }
......
...@@ -35,6 +35,11 @@ ...@@ -35,6 +35,11 @@
#define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) /* option */ #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) /* option */
#define USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK BIT(26) /* option */ #define USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK BIT(26) /* option */
#define USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK BIT(27) /* opt */ #define USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK BIT(27) /* opt */
#define USB_CTRL_SETUP_OC_DISABLE_PORT0_MASK BIT(28)
#define USB_CTRL_SETUP_OC_DISABLE_PORT1_MASK BIT(29)
#define USB_CTRL_SETUP_OC_DISABLE_MASK GENMASK(29, 28) /* option */
#define USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK BIT(30)
#define USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK BIT(31)
#define USB_CTRL_SETUP_OC3_DISABLE_MASK GENMASK(31, 30) /* option */ #define USB_CTRL_SETUP_OC3_DISABLE_MASK GENMASK(31, 30) /* option */
#define USB_CTRL_PLL_CTL 0x04 #define USB_CTRL_PLL_CTL 0x04
#define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK BIT(27) #define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK BIT(27)
...@@ -114,6 +119,8 @@ enum { ...@@ -114,6 +119,8 @@ enum {
USB_CTRL_SETUP_SCB2_EN_SELECTOR, USB_CTRL_SETUP_SCB2_EN_SELECTOR,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR, USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR,
USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR, USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR,
USB_CTRL_SETUP_OC3_DISABLE_SELECTOR, USB_CTRL_SETUP_OC3_DISABLE_SELECTOR,
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR, USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR,
USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR, USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR,
...@@ -190,6 +197,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -190,6 +197,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -232,6 +241,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -232,6 +241,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -253,6 +264,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -253,6 +264,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
...@@ -274,6 +287,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -274,6 +287,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -295,6 +310,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -295,6 +310,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -316,6 +333,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -316,6 +333,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK */
0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK */
0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -337,6 +356,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -337,6 +356,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
...@@ -358,6 +379,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -358,6 +379,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
USB_CTRL_SETUP_SCB2_EN_MASK, USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
...@@ -379,6 +402,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -379,6 +402,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
...@@ -400,6 +425,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { ...@@ -400,6 +425,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
0, /*USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ 0, /*USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
USB_CTRL_SETUP_OC3_DISABLE_MASK, USB_CTRL_SETUP_OC3_DISABLE_MASK,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
...@@ -872,6 +899,13 @@ static void usb_init_common(struct brcm_usb_init_params *params) ...@@ -872,6 +899,13 @@ static void usb_init_common(struct brcm_usb_init_params *params)
brcmusb_memc_fix(params); brcmusb_memc_fix(params);
/* Workaround for false positive OC for 7439b2 in DRD/Device mode */
if ((params->family_id == 0x74390012) &&
(params->supported_port_modes != USB_CTLR_MODE_HOST)) {
USB_CTRL_SET(ctrl, SETUP, OC_DISABLE_PORT1);
USB_CTRL_SET_FAMILY(params, SETUP, OC3_DISABLE_PORT1);
}
if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) { if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) {
reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
......
...@@ -34,6 +34,14 @@ enum brcmusb_reg_sel { ...@@ -34,6 +34,14 @@ enum brcmusb_reg_sel {
brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg), \ brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg), \
USB_CTRL_##reg##_##field##_MASK) USB_CTRL_##reg##_##field##_MASK)
#define USB_XHCI_GBL_REG(base, reg) ((void __iomem *)base + USB_XHCI_GBL_##reg)
#define USB_XHCI_GBL_SET(base, reg, field) \
brcm_usb_ctrl_set(USB_XHCI_GBL_REG(base, reg), \
USB_XHCI_GBL_##reg##_##field##_MASK)
#define USB_XHCI_GBL_UNSET(base, reg, field) \
brcm_usb_ctrl_unset(USB_XHCI_GBL_REG(base, reg), \
USB_XHCI_GBL_##reg##_##field##_MASK)
struct brcm_usb_init_params; struct brcm_usb_init_params;
struct brcm_usb_init_ops { struct brcm_usb_init_ops {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright (c) 2019-2020 NXP * Copyright (c) 2019-2020 NXP
*/ */
#include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -15,7 +16,9 @@ ...@@ -15,7 +16,9 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
/* PHY register definition */ #define USB3_PHY_OFFSET 0x0
#define USB2_PHY_OFFSET 0x38000
/* USB3 PHY register definition */
#define PHY_PMA_CMN_CTRL1 0xC800 #define PHY_PMA_CMN_CTRL1 0xC800
#define TB_ADDR_CMN_DIAG_HSCLK_SEL 0x01e0 #define TB_ADDR_CMN_DIAG_HSCLK_SEL 0x01e0
#define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR 0x0084 #define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR 0x0084
...@@ -87,8 +90,35 @@ ...@@ -87,8 +90,35 @@
#define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2 #define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2
#define TB_ADDR_TX_RCVDETSC_CTRL 0x4124 #define TB_ADDR_TX_RCVDETSC_CTRL 0x4124
/* USB2 PHY register definition */
#define UTMI_REG15 0xaf
#define UTMI_AFE_RX_REG0 0x0d
#define UTMI_AFE_RX_REG5 0x12
#define UTMI_AFE_BC_REG4 0x29
/* Align UTMI_AFE_RX_REG0 bit[7:6] define */
enum usb2_disconn_threshold {
USB2_DISCONN_THRESHOLD_575 = 0x0,
USB2_DISCONN_THRESHOLD_610 = 0x1,
USB2_DISCONN_THRESHOLD_645 = 0x3,
};
#define RX_USB2_DISCONN_MASK GENMASK(7, 6)
/* TB_ADDR_TX_RCVDETSC_CTRL */ /* TB_ADDR_TX_RCVDETSC_CTRL */
#define RXDET_IN_P3_32KHZ BIT(0) #define RXDET_IN_P3_32KHZ BIT(0)
/*
* UTMI_REG15
*
* Gate how many us for the txvalid signal until analog
* HS/FS transmitters have powered up
*/
#define TXVALID_GATE_THRESHOLD_HS_MASK (BIT(4) | BIT(5))
/* 0us, txvalid is ready just after HS/FS transmitters have powered up */
#define TXVALID_GATE_THRESHOLD_HS_0US (BIT(4) | BIT(5))
#define SET_B_SESSION_VALID (BIT(6) | BIT(5))
#define CLR_B_SESSION_VALID (BIT(6))
struct cdns_reg_pairs { struct cdns_reg_pairs {
u16 val; u16 val;
...@@ -106,19 +136,27 @@ struct cdns_salvo_phy { ...@@ -106,19 +136,27 @@ struct cdns_salvo_phy {
struct clk *clk; struct clk *clk;
void __iomem *base; void __iomem *base;
struct cdns_salvo_data *data; struct cdns_salvo_data *data;
enum usb2_disconn_threshold usb2_disconn;
}; };
static const struct of_device_id cdns_salvo_phy_of_match[]; static const struct of_device_id cdns_salvo_phy_of_match[];
static u16 cdns_salvo_read(struct cdns_salvo_phy *salvo_phy, u32 reg) static const struct cdns_salvo_data cdns_nxp_salvo_data;
static bool cdns_is_nxp_phy(struct cdns_salvo_phy *salvo_phy)
{
return salvo_phy->data == &cdns_nxp_salvo_data;
}
static u16 cdns_salvo_read(struct cdns_salvo_phy *salvo_phy, u32 offset, u32 reg)
{ {
return (u16)readl(salvo_phy->base + return (u16)readl(salvo_phy->base + offset +
reg * (1 << salvo_phy->data->reg_offset_shift)); reg * (1 << salvo_phy->data->reg_offset_shift));
} }
static void cdns_salvo_write(struct cdns_salvo_phy *salvo_phy, static void cdns_salvo_write(struct cdns_salvo_phy *salvo_phy, u32 offset,
u32 reg, u16 val) u32 reg, u16 val)
{ {
writel(val, salvo_phy->base + writel(val, salvo_phy->base + offset +
reg * (1 << salvo_phy->data->reg_offset_shift)); reg * (1 << salvo_phy->data->reg_offset_shift));
} }
...@@ -219,15 +257,27 @@ static int cdns_salvo_phy_init(struct phy *phy) ...@@ -219,15 +257,27 @@ static int cdns_salvo_phy_init(struct phy *phy)
for (i = 0; i < data->init_sequence_length; i++) { for (i = 0; i < data->init_sequence_length; i++) {
const struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i; const struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i;
cdns_salvo_write(salvo_phy, reg_pair->off, reg_pair->val); cdns_salvo_write(salvo_phy, USB3_PHY_OFFSET, reg_pair->off, reg_pair->val);
} }
/* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */ /* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */
value = cdns_salvo_read(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL); value = cdns_salvo_read(salvo_phy, USB3_PHY_OFFSET, TB_ADDR_TX_RCVDETSC_CTRL);
value |= RXDET_IN_P3_32KHZ; value |= RXDET_IN_P3_32KHZ;
cdns_salvo_write(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL, cdns_salvo_write(salvo_phy, USB3_PHY_OFFSET, TB_ADDR_TX_RCVDETSC_CTRL,
RXDET_IN_P3_32KHZ); RXDET_IN_P3_32KHZ);
value = cdns_salvo_read(salvo_phy, USB2_PHY_OFFSET, UTMI_REG15);
value &= ~TXVALID_GATE_THRESHOLD_HS_MASK;
cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_REG15,
value | TXVALID_GATE_THRESHOLD_HS_0US);
cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_RX_REG5, 0x5);
value = cdns_salvo_read(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_RX_REG0);
value &= ~RX_USB2_DISCONN_MASK;
value = FIELD_PREP(RX_USB2_DISCONN_MASK, salvo_phy->usb2_disconn);
cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_RX_REG0, value);
udelay(10); udelay(10);
clk_disable_unprepare(salvo_phy->clk); clk_disable_unprepare(salvo_phy->clk);
...@@ -251,11 +301,29 @@ static int cdns_salvo_phy_power_off(struct phy *phy) ...@@ -251,11 +301,29 @@ static int cdns_salvo_phy_power_off(struct phy *phy)
return 0; return 0;
} }
static int cdns_salvo_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy);
if (!cdns_is_nxp_phy(salvo_phy))
return 0;
if (mode == PHY_MODE_USB_DEVICE)
cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_BC_REG4,
SET_B_SESSION_VALID);
else
cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_BC_REG4,
CLR_B_SESSION_VALID);
return 0;
}
static const struct phy_ops cdns_salvo_phy_ops = { static const struct phy_ops cdns_salvo_phy_ops = {
.init = cdns_salvo_phy_init, .init = cdns_salvo_phy_init,
.power_on = cdns_salvo_phy_power_on, .power_on = cdns_salvo_phy_power_on,
.power_off = cdns_salvo_phy_power_off, .power_off = cdns_salvo_phy_power_off,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.set_mode = cdns_salvo_set_mode,
}; };
static int cdns_salvo_phy_probe(struct platform_device *pdev) static int cdns_salvo_phy_probe(struct platform_device *pdev)
...@@ -264,6 +332,7 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev) ...@@ -264,6 +332,7 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct cdns_salvo_phy *salvo_phy; struct cdns_salvo_phy *salvo_phy;
struct cdns_salvo_data *data; struct cdns_salvo_data *data;
u32 val;
data = (struct cdns_salvo_data *)of_device_get_match_data(dev); data = (struct cdns_salvo_data *)of_device_get_match_data(dev);
salvo_phy = devm_kzalloc(dev, sizeof(*salvo_phy), GFP_KERNEL); salvo_phy = devm_kzalloc(dev, sizeof(*salvo_phy), GFP_KERNEL);
...@@ -275,6 +344,16 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev) ...@@ -275,6 +344,16 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev)
if (IS_ERR(salvo_phy->clk)) if (IS_ERR(salvo_phy->clk))
return PTR_ERR(salvo_phy->clk); return PTR_ERR(salvo_phy->clk);
if (of_property_read_u32(dev->of_node, "cdns,usb2-disconnect-threshold-microvolt", &val))
val = 575;
if (val < 610)
salvo_phy->usb2_disconn = USB2_DISCONN_THRESHOLD_575;
else if (val < 645)
salvo_phy->usb2_disconn = USB2_DISCONN_THRESHOLD_610;
else
salvo_phy->usb2_disconn = USB2_DISCONN_THRESHOLD_645;
salvo_phy->base = devm_platform_ioremap_resource(pdev, 0); salvo_phy->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(salvo_phy->base)) if (IS_ERR(salvo_phy->base))
return PTR_ERR(salvo_phy->base); return PTR_ERR(salvo_phy->base);
......
This diff is collapsed.
...@@ -206,7 +206,6 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev) ...@@ -206,7 +206,6 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct imx8_pcie_phy *imx8_phy; struct imx8_pcie_phy *imx8_phy;
struct resource *res;
imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy), GFP_KERNEL); imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy), GFP_KERNEL);
if (!imx8_phy) if (!imx8_phy)
...@@ -259,8 +258,7 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev) ...@@ -259,8 +258,7 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
"Failed to get PCIE PHY PERST control\n"); "Failed to get PCIE PHY PERST control\n");
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); imx8_phy->base = devm_platform_ioremap_resource(pdev, 0);
imx8_phy->base = devm_ioremap_resource(dev, res);
if (IS_ERR(imx8_phy->base)) if (IS_ERR(imx8_phy->base))
return PTR_ERR(imx8_phy->base); return PTR_ERR(imx8_phy->base);
......
...@@ -27,17 +27,231 @@ ...@@ -27,17 +27,231 @@
#define PHY_CTRL2_TXENABLEN0 BIT(8) #define PHY_CTRL2_TXENABLEN0 BIT(8)
#define PHY_CTRL2_OTG_DISABLE BIT(9) #define PHY_CTRL2_OTG_DISABLE BIT(9)
#define PHY_CTRL3 0xc
#define PHY_CTRL3_COMPDISTUNE_MASK GENMASK(2, 0)
#define PHY_CTRL3_TXPREEMP_TUNE_MASK GENMASK(16, 15)
#define PHY_CTRL3_TXRISE_TUNE_MASK GENMASK(21, 20)
#define PHY_CTRL3_TXVREF_TUNE_MASK GENMASK(25, 22)
#define PHY_CTRL3_TX_VBOOST_LEVEL_MASK GENMASK(31, 29)
#define PHY_CTRL4 0x10
#define PHY_CTRL4_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(20, 15)
#define PHY_CTRL5 0x14
#define PHY_CTRL5_DMPWD_OVERRIDE_SEL BIT(23)
#define PHY_CTRL5_DMPWD_OVERRIDE BIT(22)
#define PHY_CTRL5_DPPWD_OVERRIDE_SEL BIT(21)
#define PHY_CTRL5_DPPWD_OVERRIDE BIT(20)
#define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0)
#define PHY_CTRL6 0x18 #define PHY_CTRL6 0x18
#define PHY_CTRL6_ALT_CLK_EN BIT(1) #define PHY_CTRL6_ALT_CLK_EN BIT(1)
#define PHY_CTRL6_ALT_CLK_SEL BIT(0) #define PHY_CTRL6_ALT_CLK_SEL BIT(0)
#define PHY_TUNE_DEFAULT 0xffffffff
struct imx8mq_usb_phy { struct imx8mq_usb_phy {
struct phy *phy; struct phy *phy;
struct clk *clk; struct clk *clk;
void __iomem *base; void __iomem *base;
struct regulator *vbus; struct regulator *vbus;
u32 pcs_tx_swing_full;
u32 pcs_tx_deemph_3p5db;
u32 tx_vref_tune;
u32 tx_rise_tune;
u32 tx_preemp_amp_tune;
u32 tx_vboost_level;
u32 comp_dis_tune;
}; };
static u32 phy_tx_vref_tune_from_property(u32 percent)
{
percent = clamp(percent, 94U, 124U);
return DIV_ROUND_CLOSEST(percent - 94U, 2);
}
static u32 phy_tx_rise_tune_from_property(u32 percent)
{
switch (percent) {
case 0 ... 98:
return 3;
case 99:
return 2;
case 100 ... 101:
return 1;
default:
return 0;
}
}
static u32 phy_tx_preemp_amp_tune_from_property(u32 microamp)
{
microamp = min(microamp, 1800U);
return microamp / 600;
}
static u32 phy_tx_vboost_level_from_property(u32 microvolt)
{
switch (microvolt) {
case 0 ... 960:
return 0;
case 961 ... 1160:
return 2;
default:
return 3;
}
}
static u32 phy_pcs_tx_deemph_3p5db_from_property(u32 decibel)
{
return min(decibel, 36U);
}
static u32 phy_comp_dis_tune_from_property(u32 percent)
{
switch (percent) {
case 0 ... 92:
return 0;
case 93 ... 95:
return 1;
case 96 ... 97:
return 2;
case 98 ... 102:
return 3;
case 103 ... 105:
return 4;
case 106 ... 109:
return 5;
case 110 ... 113:
return 6;
default:
return 7;
}
}
static u32 phy_pcs_tx_swing_full_from_property(u32 percent)
{
percent = min(percent, 100U);
return (percent * 127) / 100;
}
static void imx8m_get_phy_tuning_data(struct imx8mq_usb_phy *imx_phy)
{
struct device *dev = imx_phy->phy->dev.parent;
if (device_property_read_u32(dev, "fsl,phy-tx-vref-tune-percent",
&imx_phy->tx_vref_tune))
imx_phy->tx_vref_tune = PHY_TUNE_DEFAULT;
else
imx_phy->tx_vref_tune =
phy_tx_vref_tune_from_property(imx_phy->tx_vref_tune);
if (device_property_read_u32(dev, "fsl,phy-tx-rise-tune-percent",
&imx_phy->tx_rise_tune))
imx_phy->tx_rise_tune = PHY_TUNE_DEFAULT;
else
imx_phy->tx_rise_tune =
phy_tx_rise_tune_from_property(imx_phy->tx_rise_tune);
if (device_property_read_u32(dev, "fsl,phy-tx-preemp-amp-tune-microamp",
&imx_phy->tx_preemp_amp_tune))
imx_phy->tx_preemp_amp_tune = PHY_TUNE_DEFAULT;
else
imx_phy->tx_preemp_amp_tune =
phy_tx_preemp_amp_tune_from_property(imx_phy->tx_preemp_amp_tune);
if (device_property_read_u32(dev, "fsl,phy-tx-vboost-level-microvolt",
&imx_phy->tx_vboost_level))
imx_phy->tx_vboost_level = PHY_TUNE_DEFAULT;
else
imx_phy->tx_vboost_level =
phy_tx_vboost_level_from_property(imx_phy->tx_vboost_level);
if (device_property_read_u32(dev, "fsl,phy-comp-dis-tune-percent",
&imx_phy->comp_dis_tune))
imx_phy->comp_dis_tune = PHY_TUNE_DEFAULT;
else
imx_phy->comp_dis_tune =
phy_comp_dis_tune_from_property(imx_phy->comp_dis_tune);
if (device_property_read_u32(dev, "fsl,pcs-tx-deemph-3p5db-attenuation-db",
&imx_phy->pcs_tx_deemph_3p5db))
imx_phy->pcs_tx_deemph_3p5db = PHY_TUNE_DEFAULT;
else
imx_phy->pcs_tx_deemph_3p5db =
phy_pcs_tx_deemph_3p5db_from_property(imx_phy->pcs_tx_deemph_3p5db);
if (device_property_read_u32(dev, "fsl,phy-pcs-tx-swing-full-percent",
&imx_phy->pcs_tx_swing_full))
imx_phy->pcs_tx_swing_full = PHY_TUNE_DEFAULT;
else
imx_phy->pcs_tx_swing_full =
phy_pcs_tx_swing_full_from_property(imx_phy->pcs_tx_swing_full);
}
static void imx8m_phy_tune(struct imx8mq_usb_phy *imx_phy)
{
u32 value;
/* PHY tuning */
if (imx_phy->pcs_tx_deemph_3p5db != PHY_TUNE_DEFAULT) {
value = readl(imx_phy->base + PHY_CTRL4);
value &= ~PHY_CTRL4_PCS_TX_DEEMPH_3P5DB_MASK;
value |= FIELD_PREP(PHY_CTRL4_PCS_TX_DEEMPH_3P5DB_MASK,
imx_phy->pcs_tx_deemph_3p5db);
writel(value, imx_phy->base + PHY_CTRL4);
}
if (imx_phy->pcs_tx_swing_full != PHY_TUNE_DEFAULT) {
value = readl(imx_phy->base + PHY_CTRL5);
value |= FIELD_PREP(PHY_CTRL5_PCS_TX_SWING_FULL_MASK,
imx_phy->pcs_tx_swing_full);
writel(value, imx_phy->base + PHY_CTRL5);
}
if ((imx_phy->tx_vref_tune & imx_phy->tx_rise_tune &
imx_phy->tx_preemp_amp_tune & imx_phy->comp_dis_tune &
imx_phy->tx_vboost_level) == PHY_TUNE_DEFAULT)
/* If all are the default values, no need update. */
return;
value = readl(imx_phy->base + PHY_CTRL3);
if (imx_phy->tx_vref_tune != PHY_TUNE_DEFAULT) {
value &= ~PHY_CTRL3_TXVREF_TUNE_MASK;
value |= FIELD_PREP(PHY_CTRL3_TXVREF_TUNE_MASK,
imx_phy->tx_vref_tune);
}
if (imx_phy->tx_rise_tune != PHY_TUNE_DEFAULT) {
value &= ~PHY_CTRL3_TXRISE_TUNE_MASK;
value |= FIELD_PREP(PHY_CTRL3_TXRISE_TUNE_MASK,
imx_phy->tx_rise_tune);
}
if (imx_phy->tx_preemp_amp_tune != PHY_TUNE_DEFAULT) {
value &= ~PHY_CTRL3_TXPREEMP_TUNE_MASK;
value |= FIELD_PREP(PHY_CTRL3_TXPREEMP_TUNE_MASK,
imx_phy->tx_preemp_amp_tune);
}
if (imx_phy->comp_dis_tune != PHY_TUNE_DEFAULT) {
value &= ~PHY_CTRL3_COMPDISTUNE_MASK;
value |= FIELD_PREP(PHY_CTRL3_COMPDISTUNE_MASK,
imx_phy->comp_dis_tune);
}
if (imx_phy->tx_vboost_level != PHY_TUNE_DEFAULT) {
value &= ~PHY_CTRL3_TX_VBOOST_LEVEL_MASK;
value |= FIELD_PREP(PHY_CTRL3_TX_VBOOST_LEVEL_MASK,
imx_phy->tx_vboost_level);
}
writel(value, imx_phy->base + PHY_CTRL3);
}
static int imx8mq_usb_phy_init(struct phy *phy) static int imx8mq_usb_phy_init(struct phy *phy)
{ {
struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
...@@ -99,6 +313,8 @@ static int imx8mp_usb_phy_init(struct phy *phy) ...@@ -99,6 +313,8 @@ static int imx8mp_usb_phy_init(struct phy *phy)
value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET); value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET);
writel(value, imx_phy->base + PHY_CTRL1); writel(value, imx_phy->base + PHY_CTRL1);
imx8m_phy_tune(imx_phy);
return 0; return 0;
} }
...@@ -182,6 +398,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev) ...@@ -182,6 +398,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
phy_set_drvdata(imx_phy->phy, imx_phy); phy_set_drvdata(imx_phy->phy, imx_phy);
imx8m_get_phy_tuning_data(imx_phy);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider); return PTR_ERR_OR_ZERO(phy_provider);
......
...@@ -54,7 +54,7 @@ config PHY_HISTB_COMBPHY ...@@ -54,7 +54,7 @@ config PHY_HISTB_COMBPHY
config PHY_HISI_INNO_USB2 config PHY_HISI_INNO_USB2
tristate "HiSilicon INNO USB2 PHY support" tristate "HiSilicon INNO USB2 PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST depends on ARCH_HISI || COMPILE_TEST
select GENERIC_PHY select GENERIC_PHY
select MFD_SYSCON select MFD_SYSCON
help help
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/of_device.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/reset.h> #include <linux/reset.h>
...@@ -20,12 +20,25 @@ ...@@ -20,12 +20,25 @@
#define PHY_CLK_STABLE_TIME 2 /* unit:ms */ #define PHY_CLK_STABLE_TIME 2 /* unit:ms */
#define UTMI_RST_COMPLETE_TIME 2 /* unit:ms */ #define UTMI_RST_COMPLETE_TIME 2 /* unit:ms */
#define POR_RST_COMPLETE_TIME 300 /* unit:us */ #define POR_RST_COMPLETE_TIME 300 /* unit:us */
#define PHY_TYPE_0 0
#define PHY_TYPE_1 1
#define PHY_TEST_DATA GENMASK(7, 0) #define PHY_TEST_DATA GENMASK(7, 0)
#define PHY_TEST_ADDR GENMASK(15, 8) #define PHY_TEST_ADDR_OFFSET 8
#define PHY_TEST_PORT GENMASK(18, 16) #define PHY0_TEST_ADDR GENMASK(15, 8)
#define PHY_TEST_WREN BIT(21) #define PHY0_TEST_PORT_OFFSET 16
#define PHY_TEST_CLK BIT(22) /* rising edge active */ #define PHY0_TEST_PORT GENMASK(18, 16)
#define PHY_TEST_RST BIT(23) /* low active */ #define PHY0_TEST_WREN BIT(21)
#define PHY0_TEST_CLK BIT(22) /* rising edge active */
#define PHY0_TEST_RST BIT(23) /* low active */
#define PHY1_TEST_ADDR GENMASK(11, 8)
#define PHY1_TEST_PORT_OFFSET 12
#define PHY1_TEST_PORT BIT(12)
#define PHY1_TEST_WREN BIT(13)
#define PHY1_TEST_CLK BIT(14) /* rising edge active */
#define PHY1_TEST_RST BIT(15) /* low active */
#define PHY_CLK_ENABLE BIT(2) #define PHY_CLK_ENABLE BIT(2)
struct hisi_inno_phy_port { struct hisi_inno_phy_port {
...@@ -37,6 +50,7 @@ struct hisi_inno_phy_priv { ...@@ -37,6 +50,7 @@ struct hisi_inno_phy_priv {
void __iomem *mmio; void __iomem *mmio;
struct clk *ref_clk; struct clk *ref_clk;
struct reset_control *por_rst; struct reset_control *por_rst;
unsigned int type;
struct hisi_inno_phy_port ports[INNO_PHY_PORT_NUM]; struct hisi_inno_phy_port ports[INNO_PHY_PORT_NUM];
}; };
...@@ -45,17 +59,27 @@ static void hisi_inno_phy_write_reg(struct hisi_inno_phy_priv *priv, ...@@ -45,17 +59,27 @@ static void hisi_inno_phy_write_reg(struct hisi_inno_phy_priv *priv,
{ {
void __iomem *reg = priv->mmio; void __iomem *reg = priv->mmio;
u32 val; u32 val;
u32 value;
val = (data & PHY_TEST_DATA) |
((addr << 8) & PHY_TEST_ADDR) | if (priv->type == PHY_TYPE_0)
((port << 16) & PHY_TEST_PORT) | val = (data & PHY_TEST_DATA) |
PHY_TEST_WREN | PHY_TEST_RST; ((addr << PHY_TEST_ADDR_OFFSET) & PHY0_TEST_ADDR) |
((port << PHY0_TEST_PORT_OFFSET) & PHY0_TEST_PORT) |
PHY0_TEST_WREN | PHY0_TEST_RST;
else
val = (data & PHY_TEST_DATA) |
((addr << PHY_TEST_ADDR_OFFSET) & PHY1_TEST_ADDR) |
((port << PHY1_TEST_PORT_OFFSET) & PHY1_TEST_PORT) |
PHY1_TEST_WREN | PHY1_TEST_RST;
writel(val, reg); writel(val, reg);
val |= PHY_TEST_CLK; value = val;
writel(val, reg); if (priv->type == PHY_TYPE_0)
value |= PHY0_TEST_CLK;
else
value |= PHY1_TEST_CLK;
writel(value, reg);
val &= ~PHY_TEST_CLK;
writel(val, reg); writel(val, reg);
} }
...@@ -135,6 +159,8 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) ...@@ -135,6 +159,8 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
if (IS_ERR(priv->por_rst)) if (IS_ERR(priv->por_rst))
return PTR_ERR(priv->por_rst); return PTR_ERR(priv->por_rst);
priv->type = (uintptr_t) of_device_get_match_data(dev);
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
struct reset_control *rst; struct reset_control *rst;
struct phy *phy; struct phy *phy;
...@@ -170,8 +196,12 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) ...@@ -170,8 +196,12 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
} }
static const struct of_device_id hisi_inno_phy_of_match[] = { static const struct of_device_id hisi_inno_phy_of_match[] = {
{ .compatible = "hisilicon,inno-usb2-phy", }, { .compatible = "hisilicon,inno-usb2-phy",
{ .compatible = "hisilicon,hi3798cv200-usb2-phy", }, .data = (void *) PHY_TYPE_0 },
{ .compatible = "hisilicon,hi3798cv200-usb2-phy",
.data = (void *) PHY_TYPE_0 },
{ .compatible = "hisilicon,hi3798mv100-usb2-phy",
.data = (void *) PHY_TYPE_1 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, hisi_inno_phy_of_match); MODULE_DEVICE_TABLE(of, hisi_inno_phy_of_match);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <dt-bindings/phy/phy.h> #include <dt-bindings/phy/phy.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
...@@ -264,6 +265,8 @@ ...@@ -264,6 +265,8 @@
#define TPHY_CLKS_CNT 2 #define TPHY_CLKS_CNT 2
#define USER_BUF_LEN(count) min_t(size_t, 8, (count))
enum mtk_phy_version { enum mtk_phy_version {
MTK_PHY_V1 = 1, MTK_PHY_V1 = 1,
MTK_PHY_V2, MTK_PHY_V2,
...@@ -336,6 +339,358 @@ struct mtk_tphy { ...@@ -336,6 +339,358 @@ struct mtk_tphy {
int src_coef; /* coefficient for slew rate calibrate */ int src_coef; /* coefficient for slew rate calibrate */
}; };
#if IS_ENABLED(CONFIG_DEBUG_FS)
enum u2_phy_params {
U2P_EYE_VRT = 0,
U2P_EYE_TERM,
U2P_EFUSE_EN,
U2P_EFUSE_INTR,
U2P_DISCTH,
U2P_PRE_EMPHASIS,
};
enum u3_phy_params {
U3P_EFUSE_EN = 0,
U3P_EFUSE_INTR,
U3P_EFUSE_TX_IMP,
U3P_EFUSE_RX_IMP,
};
static const char *const u2_phy_files[] = {
[U2P_EYE_VRT] = "vrt",
[U2P_EYE_TERM] = "term",
[U2P_EFUSE_EN] = "efuse",
[U2P_EFUSE_INTR] = "intr",
[U2P_DISCTH] = "discth",
[U2P_PRE_EMPHASIS] = "preemph",
};
static const char *const u3_phy_files[] = {
[U3P_EFUSE_EN] = "efuse",
[U3P_EFUSE_INTR] = "intr",
[U3P_EFUSE_TX_IMP] = "tx-imp",
[U3P_EFUSE_RX_IMP] = "rx-imp",
};
static int u2_phy_params_show(struct seq_file *sf, void *unused)
{
struct mtk_phy_instance *inst = sf->private;
const char *fname = file_dentry(sf->file)->d_iname;
struct u2phy_banks *u2_banks = &inst->u2_banks;
void __iomem *com = u2_banks->com;
u32 max = 0;
u32 tmp = 0;
u32 val = 0;
int ret;
ret = match_string(u2_phy_files, ARRAY_SIZE(u2_phy_files), fname);
if (ret < 0)
return ret;
switch (ret) {
case U2P_EYE_VRT:
tmp = readl(com + U3P_USBPHYACR1);
val = FIELD_GET(PA1_RG_VRT_SEL, tmp);
max = FIELD_MAX(PA1_RG_VRT_SEL);
break;
case U2P_EYE_TERM:
tmp = readl(com + U3P_USBPHYACR1);
val = FIELD_GET(PA1_RG_TERM_SEL, tmp);
max = FIELD_MAX(PA1_RG_TERM_SEL);
break;
case U2P_EFUSE_EN:
if (u2_banks->misc) {
tmp = readl(u2_banks->misc + U3P_MISC_REG1);
max = 1;
}
val = !!(tmp & MR1_EFUSE_AUTO_LOAD_DIS);
break;
case U2P_EFUSE_INTR:
tmp = readl(com + U3P_USBPHYACR1);
val = FIELD_GET(PA1_RG_INTR_CAL, tmp);
max = FIELD_MAX(PA1_RG_INTR_CAL);
break;
case U2P_DISCTH:
tmp = readl(com + U3P_USBPHYACR6);
val = FIELD_GET(PA6_RG_U2_DISCTH, tmp);
max = FIELD_MAX(PA6_RG_U2_DISCTH);
break;
case U2P_PRE_EMPHASIS:
tmp = readl(com + U3P_USBPHYACR6);
val = FIELD_GET(PA6_RG_U2_PRE_EMP, tmp);
max = FIELD_MAX(PA6_RG_U2_PRE_EMP);
break;
default:
seq_printf(sf, "invalid, %d\n", ret);
break;
}
seq_printf(sf, "%s : %d [0, %d]\n", fname, val, max);
return 0;
}
static int u2_phy_params_open(struct inode *inode, struct file *file)
{
return single_open(file, u2_phy_params_show, inode->i_private);
}
static ssize_t u2_phy_params_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
const char *fname = file_dentry(file)->d_iname;
struct seq_file *sf = file->private_data;
struct mtk_phy_instance *inst = sf->private;
struct u2phy_banks *u2_banks = &inst->u2_banks;
void __iomem *com = u2_banks->com;
ssize_t rc;
u32 val;
int ret;
rc = kstrtouint_from_user(ubuf, USER_BUF_LEN(count), 0, &val);
if (rc)
return rc;
ret = match_string(u2_phy_files, ARRAY_SIZE(u2_phy_files), fname);
if (ret < 0)
return (ssize_t)ret;
switch (ret) {
case U2P_EYE_VRT:
mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL, val);
break;
case U2P_EYE_TERM:
mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL, val);
break;
case U2P_EFUSE_EN:
if (u2_banks->misc)
mtk_phy_update_field(u2_banks->misc + U3P_MISC_REG1,
MR1_EFUSE_AUTO_LOAD_DIS, !!val);
break;
case U2P_EFUSE_INTR:
mtk_phy_update_field(com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, val);
break;
case U2P_DISCTH:
mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH, val);
break;
case U2P_PRE_EMPHASIS:
mtk_phy_update_field(com + U3P_USBPHYACR6, PA6_RG_U2_PRE_EMP, val);
break;
default:
break;
}
return count;
}
static const struct file_operations u2_phy_fops = {
.open = u2_phy_params_open,
.write = u2_phy_params_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void u2_phy_dbgfs_files_create(struct mtk_phy_instance *inst)
{
u32 count = ARRAY_SIZE(u2_phy_files);
int i;
for (i = 0; i < count; i++)
debugfs_create_file(u2_phy_files[i], 0644, inst->phy->debugfs,
inst, &u2_phy_fops);
}
static int u3_phy_params_show(struct seq_file *sf, void *unused)
{
struct mtk_phy_instance *inst = sf->private;
const char *fname = file_dentry(sf->file)->d_iname;
struct u3phy_banks *u3_banks = &inst->u3_banks;
u32 val = 0;
u32 max = 0;
u32 tmp;
int ret;
ret = match_string(u3_phy_files, ARRAY_SIZE(u3_phy_files), fname);
if (ret < 0)
return ret;
switch (ret) {
case U3P_EFUSE_EN:
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
val = !!(tmp & P3D_RG_EFUSE_AUTO_LOAD_DIS);
max = 1;
break;
case U3P_EFUSE_INTR:
tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
val = FIELD_GET(P3A_RG_IEXT_INTR, tmp);
max = FIELD_MAX(P3A_RG_IEXT_INTR);
break;
case U3P_EFUSE_TX_IMP:
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
val = FIELD_GET(P3D_RG_TX_IMPEL, tmp);
max = FIELD_MAX(P3D_RG_TX_IMPEL);
break;
case U3P_EFUSE_RX_IMP:
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
val = FIELD_GET(P3D_RG_RX_IMPEL, tmp);
max = FIELD_MAX(P3D_RG_RX_IMPEL);
break;
default:
seq_printf(sf, "invalid, %d\n", ret);
break;
}
seq_printf(sf, "%s : %d [0, %d]\n", fname, val, max);
return 0;
}
static int u3_phy_params_open(struct inode *inode, struct file *file)
{
return single_open(file, u3_phy_params_show, inode->i_private);
}
static ssize_t u3_phy_params_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
const char *fname = file_dentry(file)->d_iname;
struct seq_file *sf = file->private_data;
struct mtk_phy_instance *inst = sf->private;
struct u3phy_banks *u3_banks = &inst->u3_banks;
void __iomem *phyd = u3_banks->phyd;
ssize_t rc;
u32 val;
int ret;
rc = kstrtouint_from_user(ubuf, USER_BUF_LEN(count), 0, &val);
if (rc)
return rc;
ret = match_string(u3_phy_files, ARRAY_SIZE(u3_phy_files), fname);
if (ret < 0)
return (ssize_t)ret;
switch (ret) {
case U3P_EFUSE_EN:
mtk_phy_update_field(phyd + U3P_U3_PHYD_RSV,
P3D_RG_EFUSE_AUTO_LOAD_DIS, !!val);
break;
case U3P_EFUSE_INTR:
mtk_phy_update_field(u3_banks->phya + U3P_U3_PHYA_REG0,
P3A_RG_IEXT_INTR, val);
break;
case U3P_EFUSE_TX_IMP:
mtk_phy_update_field(phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_TX_IMPEL, val);
mtk_phy_set_bits(phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_FORCE_TX_IMPEL);
break;
case U3P_EFUSE_RX_IMP:
mtk_phy_update_field(phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_RX_IMPEL, val);
mtk_phy_set_bits(phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_FORCE_RX_IMPEL);
break;
default:
break;
}
return count;
}
static const struct file_operations u3_phy_fops = {
.open = u3_phy_params_open,
.write = u3_phy_params_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void u3_phy_dbgfs_files_create(struct mtk_phy_instance *inst)
{
u32 count = ARRAY_SIZE(u3_phy_files);
int i;
for (i = 0; i < count; i++)
debugfs_create_file(u3_phy_files[i], 0644, inst->phy->debugfs,
inst, &u3_phy_fops);
}
static int phy_type_show(struct seq_file *sf, void *unused)
{
struct mtk_phy_instance *inst = sf->private;
const char *type;
switch (inst->type) {
case PHY_TYPE_USB2:
type = "USB2";
break;
case PHY_TYPE_USB3:
type = "USB3";
break;
case PHY_TYPE_PCIE:
type = "PCIe";
break;
case PHY_TYPE_SGMII:
type = "SGMII";
break;
case PHY_TYPE_SATA:
type = "SATA";
break;
default:
type = "";
}
seq_printf(sf, "%s\n", type);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(phy_type);
/* these files will be removed when phy is released by phy core */
static void phy_debugfs_init(struct mtk_phy_instance *inst)
{
debugfs_create_file("type", 0444, inst->phy->debugfs, inst, &phy_type_fops);
switch (inst->type) {
case PHY_TYPE_USB2:
u2_phy_dbgfs_files_create(inst);
break;
case PHY_TYPE_USB3:
case PHY_TYPE_PCIE:
u3_phy_dbgfs_files_create(inst);
break;
default:
break;
}
}
#else
static void phy_debugfs_init(struct mtk_phy_instance *inst)
{}
#endif
static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, static void hs_slew_rate_calibrate(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance) struct mtk_phy_instance *instance)
{ {
...@@ -1140,6 +1495,7 @@ static struct phy *mtk_phy_xlate(struct device *dev, ...@@ -1140,6 +1495,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
phy_parse_property(tphy, instance); phy_parse_property(tphy, instance);
phy_type_set(instance); phy_type_set(instance);
phy_debugfs_init(instance);
return instance->phy; return instance->phy;
} }
......
This diff is collapsed.
...@@ -30,7 +30,6 @@ struct sparx5_serdes_private { ...@@ -30,7 +30,6 @@ struct sparx5_serdes_private {
struct device *dev; struct device *dev;
void __iomem *regs[NUM_TARGETS]; void __iomem *regs[NUM_TARGETS];
struct phy *phys[SPX5_SERDES_MAX]; struct phy *phys[SPX5_SERDES_MAX];
bool cmu_enabled;
unsigned long coreclock; unsigned long coreclock;
}; };
......
...@@ -2149,6 +2149,92 @@ enum sparx5_serdes_target { ...@@ -2149,6 +2149,92 @@ enum sparx5_serdes_target {
#define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_GET(x)\ #define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_GET(x)\
FIELD_GET(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x) FIELD_GET(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x)
/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_06 */
#define SD_CMU_CMU_06(t) \
__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 4, 0, 1, 4)
#define SD_CMU_CMU_06_CFG_DISLOS BIT(0)
#define SD_CMU_CMU_06_CFG_DISLOS_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_DISLOS, x)
#define SD_CMU_CMU_06_CFG_DISLOS_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_DISLOS, x)
#define SD_CMU_CMU_06_CFG_DISLOL BIT(1)
#define SD_CMU_CMU_06_CFG_DISLOL_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_DISLOL, x)
#define SD_CMU_CMU_06_CFG_DISLOL_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_DISLOL, x)
#define SD_CMU_CMU_06_CFG_DCLOL BIT(2)
#define SD_CMU_CMU_06_CFG_DCLOL_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_DCLOL, x)
#define SD_CMU_CMU_06_CFG_DCLOL_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_DCLOL, x)
#define SD_CMU_CMU_06_CFG_FORCE_RX_FILT BIT(3)
#define SD_CMU_CMU_06_CFG_FORCE_RX_FILT_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_FORCE_RX_FILT, x)
#define SD_CMU_CMU_06_CFG_FORCE_RX_FILT_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_FORCE_RX_FILT, x)
#define SD_CMU_CMU_06_CFG_CTRL_LOGIC_PD BIT(4)
#define SD_CMU_CMU_06_CFG_CTRL_LOGIC_PD_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_CTRL_LOGIC_PD, x)
#define SD_CMU_CMU_06_CFG_CTRL_LOGIC_PD_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_CTRL_LOGIC_PD, x)
#define SD_CMU_CMU_06_CFG_VCO_PD BIT(5)
#define SD_CMU_CMU_06_CFG_VCO_PD_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_VCO_PD, x)
#define SD_CMU_CMU_06_CFG_VCO_PD_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_VCO_PD, x)
#define SD_CMU_CMU_06_CFG_VCO_CAL_RESETN BIT(6)
#define SD_CMU_CMU_06_CFG_VCO_CAL_RESETN_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_VCO_CAL_RESETN, x)
#define SD_CMU_CMU_06_CFG_VCO_CAL_RESETN_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_VCO_CAL_RESETN, x)
#define SD_CMU_CMU_06_CFG_VCO_CAL_BYP BIT(7)
#define SD_CMU_CMU_06_CFG_VCO_CAL_BYP_SET(x)\
FIELD_PREP(SD_CMU_CMU_06_CFG_VCO_CAL_BYP, x)
#define SD_CMU_CMU_06_CFG_VCO_CAL_BYP_GET(x)\
FIELD_GET(SD_CMU_CMU_06_CFG_VCO_CAL_BYP, x)
/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_08 */
#define SD_CMU_CMU_08(t) \
__REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 12, 0, 1, 4)
#define SD_CMU_CMU_08_CFG_VFILT2PAD BIT(0)
#define SD_CMU_CMU_08_CFG_VFILT2PAD_SET(x)\
FIELD_PREP(SD_CMU_CMU_08_CFG_VFILT2PAD, x)
#define SD_CMU_CMU_08_CFG_VFILT2PAD_GET(x)\
FIELD_GET(SD_CMU_CMU_08_CFG_VFILT2PAD, x)
#define SD_CMU_CMU_08_CFG_EN_DUMMY BIT(1)
#define SD_CMU_CMU_08_CFG_EN_DUMMY_SET(x)\
FIELD_PREP(SD_CMU_CMU_08_CFG_EN_DUMMY, x)
#define SD_CMU_CMU_08_CFG_EN_DUMMY_GET(x)\
FIELD_GET(SD_CMU_CMU_08_CFG_EN_DUMMY, x)
#define SD_CMU_CMU_08_CFG_CK_TREE_PD BIT(2)
#define SD_CMU_CMU_08_CFG_CK_TREE_PD_SET(x)\
FIELD_PREP(SD_CMU_CMU_08_CFG_CK_TREE_PD, x)
#define SD_CMU_CMU_08_CFG_CK_TREE_PD_GET(x)\
FIELD_GET(SD_CMU_CMU_08_CFG_CK_TREE_PD, x)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN BIT(3)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_SET(x)\
FIELD_PREP(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN, x)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_GET(x)\
FIELD_GET(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN, x)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN BIT(4)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN_SET(x)\
FIELD_PREP(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN, x)
#define SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN_GET(x)\
FIELD_GET(SD_CMU_CMU_08_CFG_RST_TREE_PD_MAN_EN, x)
/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */ /* SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
#define SD_CMU_CMU_09(t) __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 16, 0, 1, 4) #define SD_CMU_CMU_09(t) __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 16, 0, 1, 4)
...@@ -2443,6 +2529,16 @@ enum sparx5_serdes_target { ...@@ -2443,6 +2529,16 @@ enum sparx5_serdes_target {
#define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(x)\ #define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(x)\
FIELD_GET(SD_LANE_SD_LANE_STAT_DBG_OBS, x) FIELD_GET(SD_LANE_SD_LANE_STAT_DBG_OBS, x)
/* SD_LANE_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
#define SD_LANE_QUIET_MODE_6G(t) \
__REG(TARGET_SD_LANE, t, 25, 24, 0, 1, 8, 4, 0, 1, 4)
#define SD_LANE_QUIET_MODE_6G_QUIET_MODE GENMASK(24, 0)
#define SD_LANE_QUIET_MODE_6G_QUIET_MODE_SET(x)\
FIELD_PREP(SD_LANE_QUIET_MODE_6G_QUIET_MODE, x)
#define SD_LANE_QUIET_MODE_6G_QUIET_MODE_GET(x)\
FIELD_GET(SD_LANE_QUIET_MODE_6G_QUIET_MODE, x)
/* SD_LANE_TARGET:CFG_STAT_FX100:MISC */ /* SD_LANE_TARGET:CFG_STAT_FX100:MISC */
#define SD_LANE_MISC(t) __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 0, 0, 1, 4) #define SD_LANE_MISC(t) __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 0, 0, 1, 4)
...@@ -2692,4 +2788,14 @@ enum sparx5_serdes_target { ...@@ -2692,4 +2788,14 @@ enum sparx5_serdes_target {
#define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(x)\ #define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(x)\
FIELD_GET(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x) FIELD_GET(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x)
/* SD25G_CFG_TARGET:SD_PWR_CFG:QUIET_MODE_6G */
#define SD_LANE_25G_QUIET_MODE_6G(t) \
__REG(TARGET_SD_LANE_25G, t, 8, 28, 0, 1, 8, 4, 0, 1, 4)
#define SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE GENMASK(24, 0)
#define SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE_SET(x)\
FIELD_PREP(SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE, x)
#define SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE_GET(x)\
FIELD_GET(SD_LANE_25G_QUIET_MODE_6G_QUIET_MODE, x)
#endif /* _SPARX5_SERDES_REGS_H_ */ #endif /* _SPARX5_SERDES_REGS_H_ */
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
static struct class *phy_class; static struct class *phy_class;
static struct dentry *phy_debugfs_root;
static DEFINE_MUTEX(phy_provider_mutex); static DEFINE_MUTEX(phy_provider_mutex);
static LIST_HEAD(phy_provider_list); static LIST_HEAD(phy_provider_list);
static LIST_HEAD(phys); static LIST_HEAD(phys);
...@@ -996,6 +998,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node, ...@@ -996,6 +998,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
pm_runtime_no_callbacks(&phy->dev); pm_runtime_no_callbacks(&phy->dev);
} }
phy->debugfs = debugfs_create_dir(dev_name(&phy->dev), phy_debugfs_root);
return phy; return phy;
put_dev: put_dev:
...@@ -1226,6 +1230,7 @@ static void phy_release(struct device *dev) ...@@ -1226,6 +1230,7 @@ static void phy_release(struct device *dev)
phy = to_phy(dev); phy = to_phy(dev);
dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
debugfs_remove_recursive(phy->debugfs);
regulator_put(phy->pwr); regulator_put(phy->pwr);
ida_simple_remove(&phy_ida, phy->id); ida_simple_remove(&phy_ida, phy->id);
kfree(phy); kfree(phy);
...@@ -1242,6 +1247,15 @@ static int __init phy_core_init(void) ...@@ -1242,6 +1247,15 @@ static int __init phy_core_init(void)
phy_class->dev_release = phy_release; phy_class->dev_release = phy_release;
phy_debugfs_root = debugfs_create_dir("phy", NULL);
return 0; return 0;
} }
device_initcall(phy_core_init); device_initcall(phy_core_init);
static void __exit phy_core_exit(void)
{
debugfs_remove_recursive(phy_debugfs_root);
class_destroy(phy_class);
}
module_exit(phy_core_exit);
...@@ -59,8 +59,11 @@ if PHY_QCOM_QMP ...@@ -59,8 +59,11 @@ if PHY_QCOM_QMP
config PHY_QCOM_QMP_COMBO config PHY_QCOM_QMP_COMBO
tristate "Qualcomm QMP Combo PHY Driver" tristate "Qualcomm QMP Combo PHY Driver"
default PHY_QCOM_QMP default PHY_QCOM_QMP
depends on TYPEC || TYPEC=n
depends on DRM || DRM=n
select GENERIC_PHY select GENERIC_PHY
select MFD_SYSCON select MFD_SYSCON
select DRM_PANEL_BRIDGE if DRM
help help
Enable this to support the QMP Combo PHY transceiver that is used Enable this to support the QMP Combo PHY transceiver that is used
with USB3 and DisplayPort controllers on Qualcomm chips. with USB3 and DisplayPort controllers on Qualcomm chips.
...@@ -185,3 +188,12 @@ config PHY_QCOM_IPQ806X_USB ...@@ -185,3 +188,12 @@ config PHY_QCOM_IPQ806X_USB
This option enables support for the Synopsis PHYs present inside the This option enables support for the Synopsis PHYs present inside the
Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver supports Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver supports
both HS and SS PHY controllers. both HS and SS PHY controllers.
config PHY_QCOM_SGMII_ETH
tristate "Qualcomm DWMAC SGMII SerDes/PHY driver"
depends on OF && (ARCH_QCOM || COMPILE_TEST)
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support the internal SerDes/SGMII PHY on various
Qualcomm chipsets.
...@@ -20,4 +20,5 @@ obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o ...@@ -20,4 +20,5 @@ obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2)+= phy-qcom-snps-femto-v2.o obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2)+= phy-qcom-snps-femto-v2.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_USB) += phy-qcom-ipq806x-usb.o obj-$(CONFIG_PHY_QCOM_IPQ806X_USB) += phy-qcom-ipq806x-usb.o
obj-$(CONFIG_PHY_QCOM_SGMII_ETH) += phy-qcom-sgmii-eth.o
This diff is collapsed.
...@@ -139,6 +139,88 @@ static const unsigned int qmp_v5_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { ...@@ -139,6 +139,88 @@ static const unsigned int qmp_v5_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
}; };
static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
/* PLL and Loop filter settings */
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x68),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0xab),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0xaa),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x02),
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x09),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0xa0),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xaa),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x29),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
/* SSC settings */
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x7d),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x05),
};
static const struct qmp_phy_init_tbl ipq9574_usb3_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
};
static const struct qmp_phy_init_tbl ipq9574_usb3_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x06),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x6c),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4c),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xb8),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x03),
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x0c),
};
static const struct qmp_phy_init_tbl ipq9574_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0e),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
};
static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = { static const struct qmp_phy_init_tbl ipq8074_usb3_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a), QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
...@@ -1408,12 +1490,36 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = { ...@@ -1408,12 +1490,36 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21),
}; };
static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG1, 0xc4),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG2, 0x89),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG3, 0x20),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG6, 0x13),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_POWER_STATE_CONFIG1, 0x6f),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG1, 0x4b),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG5, 0x10),
QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21),
};
struct qmp_usb_offsets { struct qmp_usb_offsets {
u16 serdes; u16 serdes;
u16 pcs; u16 pcs;
u16 pcs_misc;
u16 pcs_usb; u16 pcs_usb;
u16 tx; u16 tx;
u16 rx; u16 rx;
/* for PHYs with >= 2 lanes */
u16 tx2;
u16 rx2;
}; };
/* struct qmp_phy_cfg - per-PHY initialization config */ /* struct qmp_phy_cfg - per-PHY initialization config */
...@@ -1558,6 +1664,24 @@ static const char * const qmp_phy_vreg_l[] = { ...@@ -1558,6 +1664,24 @@ static const char * const qmp_phy_vreg_l[] = {
"vdda-phy", "vdda-pll", "vdda-phy", "vdda-pll",
}; };
static const struct qmp_usb_offsets qmp_usb_offsets_ipq9574 = {
.serdes = 0,
.pcs = 0x800,
.pcs_usb = 0x800,
.tx = 0x200,
.rx = 0x400,
};
static const struct qmp_usb_offsets qmp_usb_offsets_v3 = {
.serdes = 0,
.pcs = 0xc00,
.pcs_misc = 0xa00,
.tx = 0x200,
.rx = 0x400,
.tx2 = 0x600,
.rx2 = 0x800,
};
static const struct qmp_usb_offsets qmp_usb_offsets_v5 = { static const struct qmp_usb_offsets qmp_usb_offsets_v5 = {
.serdes = 0, .serdes = 0,
.pcs = 0x0200, .pcs = 0x0200,
...@@ -1586,6 +1710,28 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { ...@@ -1586,6 +1710,28 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
.regs = qmp_v3_usb3phy_regs_layout, .regs = qmp_v3_usb3phy_regs_layout,
}; };
static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = {
.lanes = 1,
.offsets = &qmp_usb_offsets_ipq9574,
.serdes_tbl = ipq9574_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(ipq9574_usb3_serdes_tbl),
.tx_tbl = ipq9574_usb3_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(ipq9574_usb3_tx_tbl),
.rx_tbl = ipq9574_usb3_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(ipq9574_usb3_rx_tbl),
.pcs_tbl = ipq9574_usb3_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(ipq9574_usb3_pcs_tbl),
.clk_list = msm8996_phy_clk_l,
.num_clks = ARRAY_SIZE(msm8996_phy_clk_l),
.reset_list = qcm2290_usb3phy_reset_l,
.num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = qmp_v3_usb3phy_regs_layout,
};
static const struct qmp_phy_cfg msm8996_usb3phy_cfg = { static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.lanes = 1, .lanes = 1,
...@@ -1629,6 +1775,28 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = { ...@@ -1629,6 +1775,28 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
.has_phy_dp_com_ctrl = true, .has_phy_dp_com_ctrl = true,
}; };
static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
.lanes = 1,
.offsets = &qmp_usb_offsets_v5,
.serdes_tbl = sc8280xp_usb3_uniphy_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_serdes_tbl),
.tx_tbl = sc8280xp_usb3_uniphy_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_tx_tbl),
.rx_tbl = sc8280xp_usb3_uniphy_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl),
.pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl),
.clk_list = qmp_v4_phy_clk_l,
.num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
.reset_list = qcm2290_usb3phy_reset_l,
.num_resets = ARRAY_SIZE(qcm2290_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = qmp_v5_usb3phy_regs_layout,
};
static const struct qmp_phy_cfg sc7180_usb3phy_cfg = { static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
.lanes = 2, .lanes = 2,
...@@ -1922,6 +2090,8 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = { ...@@ -1922,6 +2090,8 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
.lanes = 2, .lanes = 2,
.offsets = &qmp_usb_offsets_v3,
.serdes_tbl = qcm2290_usb3_serdes_tbl, .serdes_tbl = qcm2290_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
.tx_tbl = qcm2290_usb3_tx_tbl, .tx_tbl = qcm2290_usb3_tx_tbl,
...@@ -2493,10 +2663,16 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp) ...@@ -2493,10 +2663,16 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp)
qmp->serdes = base + offs->serdes; qmp->serdes = base + offs->serdes;
qmp->pcs = base + offs->pcs; qmp->pcs = base + offs->pcs;
qmp->pcs_misc = base + offs->pcs_misc;
qmp->pcs_usb = base + offs->pcs_usb; qmp->pcs_usb = base + offs->pcs_usb;
qmp->tx = base + offs->tx; qmp->tx = base + offs->tx;
qmp->rx = base + offs->rx; qmp->rx = base + offs->rx;
if (cfg->lanes >= 2) {
qmp->tx2 = base + offs->tx2;
qmp->rx2 = base + offs->rx2;
}
qmp->pipe_clk = devm_clk_get(dev, "pipe"); qmp->pipe_clk = devm_clk_get(dev, "pipe");
if (IS_ERR(qmp->pipe_clk)) { if (IS_ERR(qmp->pipe_clk)) {
return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
...@@ -2588,6 +2764,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = { ...@@ -2588,6 +2764,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, { }, {
.compatible = "qcom,ipq8074-qmp-usb3-phy", .compatible = "qcom,ipq8074-qmp-usb3-phy",
.data = &ipq8074_usb3phy_cfg, .data = &ipq8074_usb3phy_cfg,
}, {
.compatible = "qcom,ipq9574-qmp-usb3-phy",
.data = &ipq9574_usb3phy_cfg,
}, { }, {
.compatible = "qcom,msm8996-qmp-usb3-phy", .compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg, .data = &msm8996_usb3phy_cfg,
...@@ -2597,6 +2776,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = { ...@@ -2597,6 +2776,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, { }, {
.compatible = "qcom,qcm2290-qmp-usb3-phy", .compatible = "qcom,qcm2290-qmp-usb3-phy",
.data = &qcm2290_usb3phy_cfg, .data = &qcm2290_usb3phy_cfg,
}, {
.compatible = "qcom,sa8775p-qmp-usb3-uni-phy",
.data = &sa8775p_usb3_uniphy_cfg,
}, { }, {
.compatible = "qcom,sc7180-qmp-usb3-phy", .compatible = "qcom,sc7180-qmp-usb3-phy",
.data = &sc7180_usb3phy_cfg, .data = &sc7180_usb3phy_cfg,
......
...@@ -911,6 +911,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { ...@@ -911,6 +911,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = {
}, { }, {
.compatible = "qcom,ipq8074-qusb2-phy", .compatible = "qcom,ipq8074-qusb2-phy",
.data = &msm8996_phy_cfg, .data = &msm8996_phy_cfg,
}, {
.compatible = "qcom,ipq9574-qusb2-phy",
.data = &ipq6018_phy_cfg,
}, { }, {
.compatible = "qcom,msm8953-qusb2-phy", .compatible = "qcom,msm8953-qusb2-phy",
.data = &msm8996_phy_cfg, .data = &msm8996_phy_cfg,
......
This diff is collapsed.
...@@ -59,7 +59,7 @@ config PHY_EXYNOS4210_USB2 ...@@ -59,7 +59,7 @@ config PHY_EXYNOS4210_USB2
config PHY_EXYNOS4X12_USB2 config PHY_EXYNOS4X12_USB2
bool bool
depends on PHY_SAMSUNG_USB2 depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS3250 || SOC_EXYNOS4412 default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
config PHY_EXYNOS5250_USB2 config PHY_EXYNOS5250_USB2
bool bool
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment