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:
compatible:
contains:
enum:
- const: brcm,bcm4908-usb-phy
- const: brcm,brcmstb-usb-phy
- brcm,bcm4908-usb-phy
- brcm,brcmstb-usb-phy
then:
properties:
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:
"#phy-cells":
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:
- compatible
- reg
......
......@@ -35,6 +35,53 @@ properties:
description:
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:
- compatible
- 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: |
properties:
$nodename:
pattern: "combophy(@.*|-[0-9a-f])*$"
pattern: "combophy(@.*|-([0-9]|[1-9][0-9]+))?$"
compatible:
items:
......
......@@ -32,15 +32,6 @@ properties:
clock-names:
const: phy_ref
assigned-clocks:
maxItems: 1
assigned-clock-parents:
maxItems: 1
assigned-clock-rates:
maxItems: 1
"#phy-cells":
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:
"#phy-cells":
const: 0
power-domains:
maxItems: 1
vdda-phy-supply: true
vdda-pll-supply: true
......
......@@ -203,6 +203,7 @@ allOf:
compatible:
contains:
enum:
- qcom,sc8180x-qmp-pcie-phy
- qcom,sm8250-qmp-gen3x2-pcie-phy
- qcom,sm8250-qmp-modem-pcie-phy
- qcom,sm8450-qmp-gen4x2-pcie-phy
......@@ -224,7 +225,6 @@ allOf:
compatible:
contains:
enum:
- qcom,sc8180x-qmp-pcie-phy
- qcom,sdm845-qmp-pcie-phy
- qcom,sdx55-qmp-pcie-phy
- qcom,sm8250-qmp-gen3x1-pcie-phy
......
......@@ -160,6 +160,7 @@ allOf:
contains:
enum:
- qcom,msm8998-qmp-ufs-phy
- qcom,sc8180x-qmp-ufs-phy
- qcom,sdm845-qmp-ufs-phy
- qcom,sm6350-qmp-ufs-phy
- qcom,sm8150-qmp-ufs-phy
......@@ -178,23 +179,6 @@ allOf:
- description: TX 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:
properties:
compatible:
......
......@@ -23,14 +23,12 @@ properties:
- qcom,ipq8074-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy
- qcom,msm8998-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sc7180-qmp-usb3-phy
- qcom,sc8180x-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-uni-phy
- qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy
......@@ -248,29 +246,6 @@ allOf:
- const: phy
- 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:
properties:
compatible:
......@@ -318,12 +293,10 @@ allOf:
enum:
- qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sc7180-qmp-usb3-phy
- qcom,sc8180x-qmp-usb3-phy
- qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
- qcom,sm8150-qmp-usb3-uni-phy
- qcom,sm8250-qmp-usb3-phy
then:
......
......@@ -18,13 +18,14 @@ properties:
oneOf:
- items:
- enum:
- qcom,ipq6018-qusb2-phy
- qcom,ipq8074-qusb2-phy
- qcom,ipq9574-qusb2-phy
- qcom,msm8953-qusb2-phy
- qcom,msm8996-qusb2-phy
- qcom,msm8998-qusb2-phy
- qcom,qcm2290-qusb2-phy
- qcom,sdm660-qusb2-phy
- qcom,ipq6018-qusb2-phy
- qcom,sm4250-qusb2-phy
- qcom,sm6115-qusb2-phy
- 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:
then:
properties:
clocks:
maxItems: 3
minItems: 3
clock-names:
maxItems: 3
minItems: 3
else:
properties:
clocks:
......
......@@ -16,7 +16,11 @@ description:
properties:
compatible:
enum:
- qcom,ipq9574-qmp-usb3-phy
- qcom,qcm2290-qmp-usb3-phy
- qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8280xp-qmp-usb3-uni-phy
- qcom,sm6115-qmp-usb3-phy
reg:
maxItems: 1
......@@ -25,11 +29,7 @@ properties:
maxItems: 4
clock-names:
items:
- const: aux
- const: ref
- const: com_aux
- const: pipe
maxItems: 4
power-domains:
maxItems: 1
......@@ -60,7 +60,6 @@ required:
- reg
- clocks
- clock-names
- power-domains
- resets
- reset-names
- vdda-phy-supply
......@@ -69,6 +68,60 @@ required:
- clock-output-names
- "#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
examples:
......
......@@ -60,6 +60,26 @@ properties:
description:
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:
- compatible
- reg
......@@ -98,6 +118,37 @@ examples:
vdda-phy-supply = <&vreg_l9d>;
vdda-pll-supply = <&vreg_l4d>;
orientation-switch;
#clock-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:
properties:
compatible:
contains:
const: qcom,usb-hs-phy-apq8064
enum:
- qcom,usb-hs-phy-apq8064
- qcom,usb-hs-phy-msm8960
then:
properties:
resets:
......@@ -40,6 +42,7 @@ properties:
- qcom,usb-hs-phy-apq8064
- qcom,usb-hs-phy-msm8226
- qcom,usb-hs-phy-msm8916
- qcom,usb-hs-phy-msm8960
- qcom,usb-hs-phy-msm8974
- const: qcom,usb-hs-phy
......
......@@ -20,6 +20,7 @@ properties:
- qcom,usb-snps-femto-v2-phy
- items:
- enum:
- qcom,sa8775p-usb-hs-phy
- qcom,sc8280xp-usb-hs-phy
- const: qcom,usb-snps-hs-5nm-phy
- items:
......
......@@ -24,6 +24,7 @@ properties:
- qcom,msm8998-dwc3
- qcom,qcm2290-dwc3
- qcom,qcs404-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3
- qcom,sc7280-dwc3
- qcom,sc8280xp-dwc3
......@@ -181,6 +182,7 @@ allOf:
- qcom,msm8953-dwc3
- qcom,msm8996-dwc3
- qcom,msm8998-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3
- qcom,sc7280-dwc3
- qcom,sdm670-dwc3
......@@ -456,6 +458,25 @@ allOf:
- const: dm_hs_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
examples:
......
......@@ -172,10 +172,16 @@ static int phy_meson_g12a_usb2_init(struct phy *phy)
int ret;
unsigned int value;
ret = reset_control_reset(priv->reset);
ret = clk_prepare_enable(priv->clk);
if (ret)
return ret;
ret = reset_control_reset(priv->reset);
if (ret) {
clk_disable_unprepare(priv->clk);
return ret;
}
udelay(RESET_COMPLETE_TIME);
/* usb2_otg_aca_en == 0 */
......@@ -277,8 +283,13 @@ static int phy_meson_g12a_usb2_init(struct phy *phy)
static int phy_meson_g12a_usb2_exit(struct phy *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 */
......
......@@ -59,6 +59,8 @@
#define USB_CTLR_TP_DIAG1_wake_MASK BIT(1)
#define USB_CTRL_CTLR_CSHCR 0x50
#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 */
#define USB_PHY_PLL_CTL 0x00
......@@ -90,6 +92,8 @@
#define BDC_EC_AXIRDA_RTS_MASK GENMASK(31, 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,
uint8_t addr, uint16_t data)
......@@ -140,13 +144,17 @@ static void xhci_soft_reset(struct brcm_usb_init_params *params,
int on_off)
{
void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
void __iomem *xhci_gbl = params->regs[BRCM_REGS_XHCI_GBL];
/* Assert reset */
if (on_off)
if (on_off) {
USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
/* De-assert reset */
else
} else {
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)
......@@ -320,6 +328,9 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params)
/* 1 millisecond - for USB clocks to settle down */
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_init_common(params);
}
......
......@@ -35,6 +35,11 @@
#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_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_PLL_CTL 0x04
#define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK BIT(27)
......@@ -114,6 +119,8 @@ enum {
USB_CTRL_SETUP_SCB2_EN_SELECTOR,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_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 */
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
USB_CTRL_SETUP_SCB2_EN_MASK,
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_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_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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] = {
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
0, /*USB_CTRL_SETUP_SS_EHCI64BIT_EN_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,
0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
......@@ -872,6 +899,13 @@ static void usb_init_common(struct brcm_usb_init_params *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)) {
reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1,
......
......@@ -34,6 +34,14 @@ enum brcmusb_reg_sel {
brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg), \
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_ops {
......
......@@ -6,6 +6,7 @@
* Copyright (c) 2019-2020 NXP
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
......@@ -15,7 +16,9 @@
#include <linux/of.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 TB_ADDR_CMN_DIAG_HSCLK_SEL 0x01e0
#define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR 0x0084
......@@ -87,8 +90,35 @@
#define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40f2
#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 */
#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 {
u16 val;
......@@ -106,19 +136,27 @@ struct cdns_salvo_phy {
struct clk *clk;
void __iomem *base;
struct cdns_salvo_data *data;
enum usb2_disconn_threshold usb2_disconn;
};
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));
}
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)
{
writel(val, salvo_phy->base +
writel(val, salvo_phy->base + offset +
reg * (1 << salvo_phy->data->reg_offset_shift));
}
......@@ -219,15 +257,27 @@ static int cdns_salvo_phy_init(struct phy *phy)
for (i = 0; i < data->init_sequence_length; 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 */
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;
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);
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);
clk_disable_unprepare(salvo_phy->clk);
......@@ -251,11 +301,29 @@ static int cdns_salvo_phy_power_off(struct phy *phy)
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 = {
.init = cdns_salvo_phy_init,
.power_on = cdns_salvo_phy_power_on,
.power_off = cdns_salvo_phy_power_off,
.owner = THIS_MODULE,
.set_mode = cdns_salvo_set_mode,
};
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 cdns_salvo_phy *salvo_phy;
struct cdns_salvo_data *data;
u32 val;
data = (struct cdns_salvo_data *)of_device_get_match_data(dev);
salvo_phy = devm_kzalloc(dev, sizeof(*salvo_phy), GFP_KERNEL);
......@@ -275,6 +344,16 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev)
if (IS_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);
if (IS_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)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct imx8_pcie_phy *imx8_phy;
struct resource *res;
imx8_phy = devm_kzalloc(dev, sizeof(*imx8_phy), GFP_KERNEL);
if (!imx8_phy)
......@@ -259,8 +258,7 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
"Failed to get PCIE PHY PERST control\n");
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
imx8_phy->base = devm_ioremap_resource(dev, res);
imx8_phy->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(imx8_phy->base))
return PTR_ERR(imx8_phy->base);
......
......@@ -27,17 +27,231 @@
#define PHY_CTRL2_TXENABLEN0 BIT(8)
#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_ALT_CLK_EN BIT(1)
#define PHY_CTRL6_ALT_CLK_SEL BIT(0)
#define PHY_TUNE_DEFAULT 0xffffffff
struct imx8mq_usb_phy {
struct phy *phy;
struct clk *clk;
void __iomem *base;
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)
{
struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
......@@ -99,6 +313,8 @@ static int imx8mp_usb_phy_init(struct phy *phy)
value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET);
writel(value, imx_phy->base + PHY_CTRL1);
imx8m_phy_tune(imx_phy);
return 0;
}
......@@ -182,6 +398,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
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);
return PTR_ERR_OR_ZERO(phy_provider);
......
......@@ -54,7 +54,7 @@ config PHY_HISTB_COMBPHY
config PHY_HISI_INNO_USB2
tristate "HiSilicon INNO USB2 PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
depends on ARCH_HISI || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
......
......@@ -9,7 +9,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/reset.h>
......@@ -20,12 +20,25 @@
#define PHY_CLK_STABLE_TIME 2 /* unit:ms */
#define UTMI_RST_COMPLETE_TIME 2 /* unit:ms */
#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_ADDR GENMASK(15, 8)
#define PHY_TEST_PORT GENMASK(18, 16)
#define PHY_TEST_WREN BIT(21)
#define PHY_TEST_CLK BIT(22) /* rising edge active */
#define PHY_TEST_RST BIT(23) /* low active */
#define PHY_TEST_ADDR_OFFSET 8
#define PHY0_TEST_ADDR GENMASK(15, 8)
#define PHY0_TEST_PORT_OFFSET 16
#define PHY0_TEST_PORT GENMASK(18, 16)
#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)
struct hisi_inno_phy_port {
......@@ -37,6 +50,7 @@ struct hisi_inno_phy_priv {
void __iomem *mmio;
struct clk *ref_clk;
struct reset_control *por_rst;
unsigned int type;
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,
{
void __iomem *reg = priv->mmio;
u32 val;
val = (data & PHY_TEST_DATA) |
((addr << 8) & PHY_TEST_ADDR) |
((port << 16) & PHY_TEST_PORT) |
PHY_TEST_WREN | PHY_TEST_RST;
u32 value;
if (priv->type == PHY_TYPE_0)
val = (data & PHY_TEST_DATA) |
((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);
val |= PHY_TEST_CLK;
writel(val, reg);
value = val;
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);
}
......@@ -135,6 +159,8 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
if (IS_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) {
struct reset_control *rst;
struct phy *phy;
......@@ -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[] = {
{ .compatible = "hisilicon,inno-usb2-phy", },
{ .compatible = "hisilicon,hi3798cv200-usb2-phy", },
{ .compatible = "hisilicon,inno-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);
......
......@@ -7,6 +7,7 @@
#include <dt-bindings/phy/phy.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
......@@ -264,6 +265,8 @@
#define TPHY_CLKS_CNT 2
#define USER_BUF_LEN(count) min_t(size_t, 8, (count))
enum mtk_phy_version {
MTK_PHY_V1 = 1,
MTK_PHY_V2,
......@@ -336,6 +339,358 @@ struct mtk_tphy {
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,
struct mtk_phy_instance *instance)
{
......@@ -1140,6 +1495,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
phy_parse_property(tphy, instance);
phy_type_set(instance);
phy_debugfs_init(instance);
return instance->phy;
}
......
This diff is collapsed.
......@@ -30,7 +30,6 @@ struct sparx5_serdes_private {
struct device *dev;
void __iomem *regs[NUM_TARGETS];
struct phy *phys[SPX5_SERDES_MAX];
bool cmu_enabled;
unsigned long coreclock;
};
......
......@@ -2149,6 +2149,92 @@ enum sparx5_serdes_target {
#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)
/* 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 */
#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 {
#define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(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 */
#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 {
#define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(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_ */
......@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/of.h>
......@@ -20,6 +21,7 @@
#include <linux/regulator/consumer.h>
static struct class *phy_class;
static struct dentry *phy_debugfs_root;
static DEFINE_MUTEX(phy_provider_mutex);
static LIST_HEAD(phy_provider_list);
static LIST_HEAD(phys);
......@@ -996,6 +998,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
pm_runtime_no_callbacks(&phy->dev);
}
phy->debugfs = debugfs_create_dir(dev_name(&phy->dev), phy_debugfs_root);
return phy;
put_dev:
......@@ -1226,6 +1230,7 @@ static void phy_release(struct device *dev)
phy = to_phy(dev);
dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
debugfs_remove_recursive(phy->debugfs);
regulator_put(phy->pwr);
ida_simple_remove(&phy_ida, phy->id);
kfree(phy);
......@@ -1242,6 +1247,15 @@ static int __init phy_core_init(void)
phy_class->dev_release = phy_release;
phy_debugfs_root = debugfs_create_dir("phy", NULL);
return 0;
}
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
config PHY_QCOM_QMP_COMBO
tristate "Qualcomm QMP Combo PHY Driver"
default PHY_QCOM_QMP
depends on TYPEC || TYPEC=n
depends on DRM || DRM=n
select GENERIC_PHY
select MFD_SYSCON
select DRM_PANEL_BRIDGE if DRM
help
Enable this to support the QMP Combo PHY transceiver that is used
with USB3 and DisplayPort controllers on Qualcomm chips.
......@@ -185,3 +188,12 @@ config PHY_QCOM_IPQ806X_USB
This option enables support for the Synopsis PHYs present inside the
Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver supports
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
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_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] = {
[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[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
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[] = {
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 {
u16 serdes;
u16 pcs;
u16 pcs_misc;
u16 pcs_usb;
u16 tx;
u16 rx;
/* for PHYs with >= 2 lanes */
u16 tx2;
u16 rx2;
};
/* struct qmp_phy_cfg - per-PHY initialization config */
......@@ -1558,6 +1664,24 @@ static const char * const qmp_phy_vreg_l[] = {
"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 = {
.serdes = 0,
.pcs = 0x0200,
......@@ -1586,6 +1710,28 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
.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 = {
.lanes = 1,
......@@ -1629,6 +1775,28 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
.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 = {
.lanes = 2,
......@@ -1922,6 +2090,8 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
.lanes = 2,
.offsets = &qmp_usb_offsets_v3,
.serdes_tbl = qcm2290_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
.tx_tbl = qcm2290_usb3_tx_tbl,
......@@ -2493,10 +2663,16 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp)
qmp->serdes = base + offs->serdes;
qmp->pcs = base + offs->pcs;
qmp->pcs_misc = base + offs->pcs_misc;
qmp->pcs_usb = base + offs->pcs_usb;
qmp->tx = base + offs->tx;
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");
if (IS_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[] = {
}, {
.compatible = "qcom,ipq8074-qmp-usb3-phy",
.data = &ipq8074_usb3phy_cfg,
}, {
.compatible = "qcom,ipq9574-qmp-usb3-phy",
.data = &ipq9574_usb3phy_cfg,
}, {
.compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg,
......@@ -2597,6 +2776,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, {
.compatible = "qcom,qcm2290-qmp-usb3-phy",
.data = &qcm2290_usb3phy_cfg,
}, {
.compatible = "qcom,sa8775p-qmp-usb3-uni-phy",
.data = &sa8775p_usb3_uniphy_cfg,
}, {
.compatible = "qcom,sc7180-qmp-usb3-phy",
.data = &sc7180_usb3phy_cfg,
......
......@@ -911,6 +911,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = {
}, {
.compatible = "qcom,ipq8074-qusb2-phy",
.data = &msm8996_phy_cfg,
}, {
.compatible = "qcom,ipq9574-qusb2-phy",
.data = &ipq6018_phy_cfg,
}, {
.compatible = "qcom,msm8953-qusb2-phy",
.data = &msm8996_phy_cfg,
......
This diff is collapsed.
......@@ -59,7 +59,7 @@ config PHY_EXYNOS4210_USB2
config PHY_EXYNOS4X12_USB2
bool
depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS3250 || SOC_EXYNOS4412
default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
config PHY_EXYNOS5250_USB2
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