phy-for-6.13

- New Support
   - ST STM32MP25 combophy support
   - Sparx5 support for lan969x serdes and updates to driver to support this
   - NXP PTN3222 eUSB2 to USB2 redriver
   - Qualcomm SAR2130P eusb2 support, QCS8300 USB DW3 and QMP USB2 support,
     X1E80100 QMP PCIe PHY Gen4 support, QCS615 and QCS8300 QMP UFS PHY
     support and SA8775P eDP PHY support
   - Rockchip rk3576 usbdp and rk3576 usb2 phy support
   - Binding for Microchip ATA6561 can phy
 
 - Updates
   - Freescale driver updates from hdmi support
   - Conversion of rockchip rk3228 hdmi phy binding to yaml
   - Broadcom usb2-phy deprecated support dropped and USB init array update
     for BCM4908
   - TI USXGMII mode support in J7200
   - Switch back to platform_driver::remove() subsystem update
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmdG0uwACgkQfBQHDyUj
 g0ftFg//ftcsFV6HQp+MXTzgBrlXk1EbIXSfG1R1k2jSSzwUMgQkNkIXJ9bUVSRA
 yvgn+JJ2OtoIBYVVyNbDghw6CBYc7TMcK+1PPcS43o63X/giXiQ+QLN+J19PxDOl
 fgDvRgp4SHxWW3DAQW0Kgle7VCTWBIHCR3C06RG7I2AlIoWyzkNsI4SM8hSrnaon
 9FzBqGZCSnGgorfUgEkWjv4TDK69xZOOG1bIbsX/xA1wY3vvRzJg3R7TGYqC35/F
 XII5oHpv0kBjNwZhU4xR5YF6IDqakRa5UNviXi7DKzbyD277lkrCCccvq0EU4Vau
 m7bv3nNTUKqk/EQBSEWCDYECD5Xw57Qa6i/qo3gMXIVoDm6jfUDP3MbPG0IllLBZ
 +X34i1pq24gZLl+2rSMHMi8IlyTrpCgBsCeH/xsgkEev6Sr9gHI9Hqd1mnMHNa3G
 U31kaY/eEfDy377k2l8hFKx3pT+Qsne9jbjOzdIuciL10+0xqwCOCrAJA6JjyxTI
 ONcbRZRIwHAg48gPyMmqRXd5xnr+8epCedaRo0j4O8gJpSBCXzXCIIS3DlBlwmIc
 WJkF5jN6WGunmI5yYd19256gVK2SPv0YA+UNFeQDF6d9djHaGaKvH2Is4zMe3JOW
 mBfYwJLC39d8v3u4rBNSAR8a1HM9haAdcNctkrNmONMEtS9hsg0=
 =5o8/
 -----END PGP SIGNATURE-----

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

Pull phy updates from Vinod Koul:
 "New hardware support:

   - ST STM32MP25 combophy support

   - Sparx5 support for lan969x serdes and updates to driver to support
     this

   - NXP PTN3222 eUSB2 to USB2 redriver

   - Qualcomm SAR2130P eusb2 support, QCS8300 USB DW3 and QMP USB2
     support, X1E80100 QMP PCIe PHY Gen4 support, QCS615 and QCS8300 QMP
     UFS PHY support and SA8775P eDP PHY support

   - Rockchip rk3576 usbdp and rk3576 usb2 phy support

   - Binding for Microchip ATA6561 can phy

  Updates:

   - Freescale driver updates from hdmi support

   - Conversion of rockchip rk3228 hdmi phy binding to yaml

   - Broadcom usb2-phy deprecated support dropped and USB init array
     update for BCM4908

   - TI USXGMII mode support in J7200

   - Switch back to platform_driver::remove() subsystem update"

* tag 'phy-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (59 commits)
  phy: qcom: qmp: Fix lecacy-legacy typo
  phy: lan969x-serdes: add support for lan969x serdes driver
  dt-bindings: phy: sparx5: document lan969x
  phy: sparx5-serdes: add support for branching on chip type
  phy: sparx5-serdes: add indirection layer to register macros
  phy: sparx5-serdes: add function for getting the CMU index
  phy: sparx5-serdes: add ops to match data
  phy: sparx5-serdes: add constant for the number of CMU's
  phy: sparx5-serdes: add constants to match data
  phy: sparx5-serdes: add support for private match data
  phy: bcm-ns-usb2: drop support for old binding variant
  dt-bindings: phy: bcm-ns-usb2-phy: drop deprecated variant
  dt-bindings: phy: Add QMP UFS PHY compatible for QCS8300
  dt-bindings: phy: qcom: snps-eusb2: Add SAR2130P compatible
  dt-bindings: phy: ti,tcan104x-can: Document Microchip ATA6561
  phy: airoha: Fix REG_CSR_2L_RX{0,1}_REV0 definitions
  phy: airoha: Fix REG_CSR_2L_JCPLL_SDM_HREN config in airoha_pcie_phy_init_ssc_jcpll()
  phy: airoha: Fix REG_PCIE_PMA_TX_RESET config in airoha_pcie_phy_init_csr_2l()
  phy: airoha: Fix REG_CSR_2L_PLL_CMN_RESERVE0 config in airoha_pcie_phy_init_clk_out()
  phy: phy-rockchip-samsung-hdptx: Don't request RST_PHY/RST_ROPLL/RST_LCPLL
  ...
This commit is contained in:
Linus Torvalds 2024-11-27 13:33:43 -08:00
commit 0ce9a5ffca
81 changed files with 3056 additions and 1069 deletions

View File

@ -18,16 +18,8 @@ properties:
const: brcm,ns-usb2-phy
reg:
anyOf:
- maxItems: 1
description: PHY control register
- maxItems: 1
description: iomem address range of DMU (Device Management Unit)
deprecated: true
reg-names:
items:
- const: dmu
maxItems: 1
description: PHY control register
brcm,syscon-clkset:
description: phandle to syscon for clkset register
@ -50,12 +42,7 @@ required:
- clocks
- clock-names
- "#phy-cells"
oneOf:
- required:
- brcm,syscon-clkset
- required:
- reg-names
- brcm,syscon-clkset
additionalProperties: false

View File

@ -32,6 +32,7 @@ properties:
- enum:
- fsl,imx8dxl-usbphy
- fsl,imx8qm-usbphy
- fsl,imx8qxp-usbphy
- fsl,imx8ulp-usbphy
- const: fsl,imx7ulp-usbphy

View File

@ -125,6 +125,16 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
default: 28
power-domains:
description:
The TPHY of MediaTek should exist within a power domain. The
developer should be aware that the hardware design of MediaTek TPHY
does not require the addition of MTCMOS. If the power to the TPHY
is turned off, it will impact other functions. From the current
perspective of USB hardware design, even if MTCMOS is added to the
TPHY, it should remain always on.
maxItems: 1
# Required child node:
patternProperties:
"^(usb|pcie|sata)-phy@[0-9a-f]+$":

View File

@ -8,6 +8,7 @@ title: Microchip Sparx5 Serdes controller
maintainers:
- Steen Hegelund <steen.hegelund@microchip.com>
- Daniel Machon <daniel.machon@microchip.com>
description: |
The Sparx5 SERDES interfaces share the same basic functionality, but
@ -62,12 +63,26 @@ description: |
* 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
* 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
lan969x has ten SERDES10G interfaces that share the same features, operating
modes and data rates as the equivalent Sparx5 SERDES10G interfaces.
properties:
$nodename:
pattern: "^serdes@[0-9a-f]+$"
compatible:
const: microchip,sparx5-serdes
oneOf:
- enum:
- microchip,sparx5-serdes
- microchip,lan9691-serdes
- items:
- enum:
- microchip,lan9698-serdes
- microchip,lan9696-serdes
- microchip,lan9694-serdes
- microchip,lan9693-serdes
- microchip,lan9692-serdes
- const: microchip,lan9691-serdes
reg:
minItems: 1

View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/nxp,ptn3222.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP PTN3222 1-port eUSB2 to USB2 redriver
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
properties:
compatible:
enum:
- nxp,ptn3222
reg:
maxItems: 1
"#phy-cells":
const: 0
vdd1v8-supply:
description: power supply (1.8V)
vdd3v3-supply:
description: power supply (3.3V)
reset-gpios: true
required:
- compatible
- reg
- '#phy-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
redriver@4f {
compatible = "nxp,ptn3222";
reg = <0x4f>;
#phy-cells = <0>;
vdd3v3-supply = <&vreg_3p3>;
vdd1v8-supply = <&vreg_1p8>;
reset-gpios = <&gpio_reset GPIO_ACTIVE_LOW>;
};
};
...

View File

@ -96,7 +96,7 @@ patternProperties:
Specifies the type of PHY for which the group of PHY lanes is used.
Refer include/dt-bindings/phy/phy.h. Constants from the header should be used.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [2, 4]
enum: [2, 4, 8, 9]
cdns,num-lanes:
description:

View File

@ -1,43 +0,0 @@
ROCKCHIP HDMI PHY WITH INNO IP BLOCK
Required properties:
- compatible : should be one of the listed compatibles:
* "rockchip,rk3228-hdmi-phy",
* "rockchip,rk3328-hdmi-phy";
- reg : Address and length of the hdmi phy control register set
- clocks : phandle + clock specifier for the phy clocks
- clock-names : string, clock name, must contain "sysclk" for system
control and register configuration, "refoclk" for crystal-
oscillator reference PLL clock input and "refpclk" for pclk-
based refeference PLL clock input.
- #clock-cells: should be 0.
- clock-output-names : shall be the name for the output clock.
- interrupts : phandle + interrupt specified for the hdmiphy interrupt
- #phy-cells : must be 0. See ./phy-bindings.txt for details.
Optional properties for rk3328-hdmi-phy:
- nvmem-cells = phandle + nvmem specifier for the cpu-version efuse
- nvmem-cell-names : "cpu-version" to read the chip version, required
for adjustment to some frequency settings
Example:
hdmi_phy: hdmi-phy@12030000 {
compatible = "rockchip,rk3228-hdmi-phy";
reg = <0x12030000 0x10000>;
#phy-cells = <0>;
clocks = <&cru PCLK_HDMI_PHY>, <&xin24m>, <&cru DCLK_HDMIPHY>;
clock-names = "sysclk", "refoclk", "refpclk";
#clock-cells = <0>;
clock-output-names = "hdmi_phy";
status = "disabled";
};
Then the PHY can be used in other nodes such as:
hdmi: hdmi@200a0000 {
compatible = "rockchip,rk3228-dw-hdmi";
...
phys = <&hdmi_phy>;
phy-names = "hdmi";
...
};

View File

@ -13,6 +13,7 @@ maintainers:
properties:
compatible:
enum:
- rockchip,rk3576-usbdp-phy
- rockchip,rk3588-usbdp-phy
reg:

View File

@ -17,6 +17,7 @@ description:
properties:
compatible:
enum:
- qcom,sa8775p-edp-phy
- qcom,sc7280-edp-phy
- qcom,sc8180x-edp-phy
- qcom,sc8280xp-dp-phy

View File

@ -15,7 +15,12 @@ description:
properties:
compatible:
const: qcom,sa8775p-dwmac-sgmii-phy
oneOf:
- items:
- enum:
- qcom,qcs8300-dwmac-sgmii-phy
- const: qcom,sa8775p-dwmac-sgmii-phy
- const: qcom,sa8775p-dwmac-sgmii-phy
reg:
items:

View File

@ -41,6 +41,7 @@ properties:
- qcom,x1e80100-qmp-gen3x2-pcie-phy
- qcom,x1e80100-qmp-gen4x2-pcie-phy
- qcom,x1e80100-qmp-gen4x4-pcie-phy
- qcom,x1e80100-qmp-gen4x8-pcie-phy
reg:
minItems: 1
@ -172,6 +173,7 @@ allOf:
- qcom,x1e80100-qmp-gen3x2-pcie-phy
- qcom,x1e80100-qmp-gen4x2-pcie-phy
- qcom,x1e80100-qmp-gen4x4-pcie-phy
- qcom,x1e80100-qmp-gen4x8-pcie-phy
then:
properties:
clocks:
@ -202,6 +204,7 @@ allOf:
- qcom,sm8650-qmp-gen4x2-pcie-phy
- qcom,x1e80100-qmp-gen4x2-pcie-phy
- qcom,x1e80100-qmp-gen4x4-pcie-phy
- qcom,x1e80100-qmp-gen4x8-pcie-phy
then:
properties:
resets:

View File

@ -15,26 +15,35 @@ description:
properties:
compatible:
enum:
- qcom,msm8996-qmp-ufs-phy
- qcom,msm8998-qmp-ufs-phy
- qcom,sa8775p-qmp-ufs-phy
- qcom,sc7180-qmp-ufs-phy
- qcom,sc7280-qmp-ufs-phy
- qcom,sc8180x-qmp-ufs-phy
- qcom,sc8280xp-qmp-ufs-phy
- qcom,sdm845-qmp-ufs-phy
- qcom,sm6115-qmp-ufs-phy
- qcom,sm6125-qmp-ufs-phy
- qcom,sm6350-qmp-ufs-phy
- qcom,sm7150-qmp-ufs-phy
- qcom,sm8150-qmp-ufs-phy
- qcom,sm8250-qmp-ufs-phy
- qcom,sm8350-qmp-ufs-phy
- qcom,sm8450-qmp-ufs-phy
- qcom,sm8475-qmp-ufs-phy
- qcom,sm8550-qmp-ufs-phy
- qcom,sm8650-qmp-ufs-phy
oneOf:
- items:
- enum:
- qcom,qcs615-qmp-ufs-phy
- const: qcom,sm6115-qmp-ufs-phy
- items:
- enum:
- qcom,qcs8300-qmp-ufs-phy
- const: qcom,sa8775p-qmp-ufs-phy
- enum:
- qcom,msm8996-qmp-ufs-phy
- qcom,msm8998-qmp-ufs-phy
- qcom,sa8775p-qmp-ufs-phy
- qcom,sc7180-qmp-ufs-phy
- qcom,sc7280-qmp-ufs-phy
- qcom,sc8180x-qmp-ufs-phy
- qcom,sc8280xp-qmp-ufs-phy
- qcom,sdm845-qmp-ufs-phy
- qcom,sm6115-qmp-ufs-phy
- qcom,sm6125-qmp-ufs-phy
- qcom,sm6350-qmp-ufs-phy
- qcom,sm7150-qmp-ufs-phy
- qcom,sm8150-qmp-ufs-phy
- qcom,sm8250-qmp-ufs-phy
- qcom,sm8350-qmp-ufs-phy
- qcom,sm8450-qmp-ufs-phy
- qcom,sm8475-qmp-ufs-phy
- qcom,sm8550-qmp-ufs-phy
- qcom,sm8650-qmp-ufs-phy
reg:
maxItems: 1

View File

@ -20,6 +20,7 @@ properties:
- qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy
- qcom,qcs8300-qmp-usb3-uni-phy
- qcom,qdu1000-qmp-usb3-uni-phy
- qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8180x-qmp-usb3-uni-phy
@ -111,6 +112,7 @@ allOf:
compatible:
contains:
enum:
- qcom,qcs8300-qmp-usb3-uni-phy
- qcom,qdu1000-qmp-usb3-uni-phy
- qcom,sa8775p-qmp-usb3-uni-phy
- qcom,sc8180x-qmp-usb3-uni-phy

View File

@ -17,6 +17,7 @@ properties:
oneOf:
- items:
- enum:
- qcom,sar2130p-snps-eusb2-phy
- qcom,sdx75-snps-eusb2-phy
- qcom,sm8650-snps-eusb2-phy
- qcom,x1e80100-snps-eusb2-phy

View File

@ -22,6 +22,7 @@ properties:
- const: qcom,usb-snps-hs-5nm-phy
- items:
- enum:
- qcom,qcs8300-usb-hs-phy
- qcom,qdu1000-usb-hs-phy
- qcom,sc7280-usb-hs-phy
- qcom,sc8180x-usb-hs-phy

View File

@ -20,6 +20,7 @@ properties:
- rockchip,rk3366-usb2phy
- rockchip,rk3399-usb2phy
- rockchip,rk3568-usb2phy
- rockchip,rk3576-usb2phy
- rockchip,rk3588-usb2phy
- rockchip,rv1108-usb2phy
@ -34,10 +35,15 @@ properties:
const: 0
clocks:
maxItems: 1
minItems: 1
maxItems: 3
clock-names:
const: phyclk
minItems: 1
items:
- const: phyclk
- const: aclk
- const: aclk_slv
assigned-clocks:
description:
@ -172,6 +178,41 @@ allOf:
- interrupts
- interrupt-names
- if:
properties:
compatible:
contains:
enum:
- rockchip,px30-usb2phy
- rockchip,rk3128-usb2phy
- rockchip,rk3228-usb2phy
- rockchip,rk3308-usb2phy
- rockchip,rk3328-usb2phy
- rockchip,rk3366-usb2phy
- rockchip,rk3399-usb2phy
- rockchip,rk3568-usb2phy
- rockchip,rk3588-usb2phy
- rockchip,rv1108-usb2phy
then:
properties:
clocks:
maxItems: 1
clock-names:
maxItems: 1
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3576-usb2phy
then:
properties:
clocks:
minItems: 3
clock-names:
minItems: 3
additionalProperties: false
examples:

View File

@ -0,0 +1,97 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/rockchip,rk3228-hdmi-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip HDMI PHY with Innosilicon IP block
maintainers:
- Heiko Stuebner <heiko@sntech.de>
properties:
compatible:
enum:
- rockchip,rk3228-hdmi-phy
- rockchip,rk3328-hdmi-phy
reg:
maxItems: 1
clocks:
maxItems: 3
clock-names:
items:
- const: sysclk
- const: refoclk
- const: refpclk
clock-output-names:
description:
The hdmiphy output clock name, that gets fed back to the CRU.
"#clock-cells":
const: 0
interrupts:
maxItems: 1
nvmem-cells:
maxItems: 1
description: A phandle + nvmem specifier for the cpu-version efuse
for adjustment to some frequency settings, depending on cpu-version
nvmem-cell-names:
items:
- const: cpu-version
'#phy-cells':
const: 0
required:
- compatible
- reg
- clocks
- clock-names
- clock-output-names
- '#clock-cells'
- '#phy-cells'
allOf:
- if:
properties:
compatible:
contains:
const: rockchip,rk3228-hdmi-phy
then:
properties:
interrupts: false
- if:
properties:
compatible:
contains:
const: rockchip,rk3328-hdmi-phy
then:
required:
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/rk3228-cru.h>
hdmi_phy: phy@12030000 {
compatible = "rockchip,rk3228-hdmi-phy";
reg = <0x12030000 0x10000>;
#phy-cells = <0>;
clocks = <&cru PCLK_HDMI_PHY>, <&xin24m>, <&cru DCLK_HDMI_PHY>;
clock-names = "sysclk", "refoclk", "refpclk";
#clock-cells = <0>;
clock-output-names = "hdmi_phy";
};

View File

@ -0,0 +1,119 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/st,stm32mp25-combophy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32MP25 USB3/PCIe COMBOPHY
maintainers:
- Christian Bruel <christian.bruel@foss.st.com>
description:
Single lane PHY shared (exclusive) between the USB3 and PCIe controllers.
Supports 5Gbit/s for USB3 and PCIe gen2 or 2.5Gbit/s for PCIe gen1.
properties:
compatible:
const: st,stm32mp25-combophy
reg:
maxItems: 1
"#phy-cells":
const: 1
clocks:
minItems: 2
items:
- description: apb Bus clock mandatory to access registers.
- description: ker Internal RCC reference clock for USB3 or PCIe
- description: pad Optional on board clock input for PCIe only. Typically an
external 100Mhz oscillator wired on dedicated CLKIN pad. Used as reference
clock input instead of the ker
clock-names:
minItems: 2
items:
- const: apb
- const: ker
- const: pad
resets:
maxItems: 1
reset-names:
const: phy
power-domains:
maxItems: 1
wakeup-source: true
interrupts:
maxItems: 1
description: interrupt used for wakeup
access-controllers:
maxItems: 1
description: Phandle to the rifsc device to check access right.
st,ssc-on:
$ref: /schemas/types.yaml#/definitions/flag
description:
A property whose presence indicates that the Spread Spectrum Clocking is active.
st,rx-equalizer:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
default: 2
description:
A 3 bit value to tune the RX fixed equalizer setting for optimal eye compliance
st,output-micro-ohms:
minimum: 3999000
maximum: 6090000
default: 4968000
description:
A value property to tune the Single Ended Output Impedance, simulations results
at 25C for a VDDP=0.8V. The hardware accepts discrete values in this range.
st,output-vswing-microvolt:
minimum: 442000
maximum: 803000
default: 803000
description:
A value property in microvolt to tune the Single Ended Output Voltage Swing to change the
Vlo, Vhi for a VDDP = 0.8V. The hardware accepts discrete values in this range.
required:
- compatible
- reg
- "#phy-cells"
- clocks
- clock-names
- resets
- reset-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/st,stm32mp25-rcc.h>
phy@480c0000 {
compatible = "st,stm32mp25-combophy";
reg = <0x480c0000 0x1000>;
#phy-cells = <1>;
clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
clock-names = "apb", "ker";
resets = <&rcc USB3PCIEPHY_R>;
reset-names = "phy";
access-controllers = <&rifsc 67>;
power-domains = <&CLUSTER_PD>;
wakeup-source;
interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
};

View File

@ -14,10 +14,15 @@ properties:
pattern: "^can-phy"
compatible:
enum:
- nxp,tjr1443
- ti,tcan1042
- ti,tcan1043
oneOf:
- items:
- enum:
- microchip,ata6561
- const: ti,tcan1042
- enum:
- ti,tcan1042
- ti,tcan1043
- nxp,tjr1443
'#phy-cells':
const: 0

View File

@ -26,6 +26,7 @@ properties:
- qcom,msm8998-dwc3
- qcom,qcm2290-dwc3
- qcom,qcs404-dwc3
- qcom,qcs8300-dwc3
- qcom,qdu1000-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3
@ -201,6 +202,7 @@ allOf:
- qcom,msm8953-dwc3
- qcom,msm8996-dwc3
- qcom,msm8998-dwc3
- qcom,qcs8300-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3
- qcom,sc7280-dwc3
@ -465,6 +467,7 @@ allOf:
- qcom,ipq4019-dwc3
- qcom,ipq8064-dwc3
- qcom,msm8994-dwc3
- qcom,qcs8300-dwc3
- qcom,qdu1000-dwc3
- qcom,sa8775p-dwc3
- qcom,sc7180-dwc3
@ -490,6 +493,7 @@ allOf:
minItems: 4
maxItems: 5
interrupt-names:
minItems: 4
items:
- const: pwr_event
- const: hs_phy_irq

View File

@ -22428,6 +22428,12 @@ F: drivers/*/stm32-*timer*
F: drivers/pwm/pwm-stm32*
F: include/linux/*/stm32-*tim*
STM32MP25 USB3/PCIE COMBOPHY DRIVER
M: Christian Bruel <christian.bruel@foss.st.com>
S: Maintained
F: Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
F: drivers/phy/st/phy-stm32-combophy.c
STMMAC ETHERNET DRIVER
M: Alexandre Torgue <alexandre.torgue@foss.st.com>
M: Jose Abreu <joabreu@synopsys.com>

View File

@ -82,6 +82,17 @@ config PHY_AIROHA_PCIE
This driver create the basic PHY instance and provides initialize
callback for PCIe GEN3 port.
config PHY_NXP_PTN3222
tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
depends on I2C
depends on OF
select GENERIC_PHY
help
Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
This redriver performs translation between eUSB2 and USB2 signalling
schemes. It supports all three USB 2.0 data rates: Low Speed, Full
Speed and High Speed.
source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/broadcom/Kconfig"

View File

@ -11,6 +11,7 @@ obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o
obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
obj-y += allwinner/ \
amlogic/ \
broadcom/ \

View File

@ -1049,11 +1049,11 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
static struct platform_driver sun4i_usb_phy_driver = {
.probe = sun4i_usb_phy_probe,
.remove_new = sun4i_usb_phy_remove,
.probe = sun4i_usb_phy_probe,
.remove = sun4i_usb_phy_remove,
.driver = {
.of_match_table = sun4i_usb_phy_of_match,
.name = "sun4i-usb-phy",
.of_match_table= sun4i_usb_phy_of_match,
.name = "sun4i-usb-phy",
}
};
module_platform_driver(sun4i_usb_phy_driver);

View File

@ -24,9 +24,6 @@ struct bcm_ns_usb2 {
struct phy *phy;
struct regmap *clkset;
void __iomem *base;
/* Deprecated binding */
void __iomem *dmu;
};
static int bcm_ns_usb2_phy_init(struct phy *phy)
@ -49,10 +46,7 @@ static int bcm_ns_usb2_phy_init(struct phy *phy)
goto err_clk_off;
}
if (usb2->base)
usb2ctl = readl(usb2->base);
else
usb2ctl = readl(usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
usb2ctl = readl(usb2->base);
if (usb2ctl & BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK) {
usb_pll_pdiv = usb2ctl;
@ -66,24 +60,16 @@ static int bcm_ns_usb2_phy_init(struct phy *phy)
usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
/* Unlock DMU PLL settings with some magic value */
if (usb2->clkset)
regmap_write(usb2->clkset, 0, 0x0000ea68);
else
writel(0x0000ea68, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
regmap_write(usb2->clkset, 0, 0x0000ea68);
/* Write USB 2.0 PLL control setting */
usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
if (usb2->base)
writel(usb2ctl, usb2->base);
else
writel(usb2ctl, usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
writel(usb2ctl, usb2->base);
/* Lock DMU PLL settings */
if (usb2->clkset)
regmap_write(usb2->clkset, 0, 0x00000000);
else
writel(0x00000000, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
regmap_write(usb2->clkset, 0, 0x00000000);
err_clk_off:
clk_disable_unprepare(usb2->ref_clk);
@ -107,27 +93,17 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev)
return -ENOMEM;
usb2->dev = dev;
if (of_property_present(dev->of_node, "brcm,syscon-clkset")) {
usb2->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(usb2->base)) {
dev_err(dev, "Failed to map control reg\n");
return PTR_ERR(usb2->base);
}
usb2->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(usb2->base)) {
dev_err(dev, "Failed to map control reg\n");
return PTR_ERR(usb2->base);
}
usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
"brcm,syscon-clkset");
if (IS_ERR(usb2->clkset)) {
dev_err(dev, "Failed to lookup clkset regmap\n");
return PTR_ERR(usb2->clkset);
}
} else {
usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
if (IS_ERR(usb2->dmu)) {
dev_err(dev, "Failed to map DMU regs\n");
return PTR_ERR(usb2->dmu);
}
dev_warn(dev, "using deprecated DT binding\n");
usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
"brcm,syscon-clkset");
if (IS_ERR(usb2->clkset)) {
dev_err(dev, "Failed to lookup clkset regmap\n");
return PTR_ERR(usb2->clkset);
}
usb2->ref_clk = devm_clk_get(dev, "phy-ref-clk");

View File

@ -193,256 +193,251 @@ static const u32
usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = {
/* 3390B0 */
[BRCM_FAMILY_3390A0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR] =
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 4908 */
[BRCM_FAMILY_4908] = {
0, /* USB_CTRL_SETUP_SCB1_EN_MASK */
0, /* USB_CTRL_SETUP_SCB2_EN_MASK */
0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_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_PLL_CTL_PLL_IDDQ_PWRDN_MASK */
0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK */
0, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
},
/* 7250b0 */
[BRCM_FAMILY_7250B0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7271a0 */
[BRCM_FAMILY_7271A0] = {
0, /* USB_CTRL_SETUP_SCB1_EN_MASK */
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,
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
USB_CTRL_USB_PM_SOFT_RESET_MASK,
USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR] =
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
[USB_CTRL_USB_PM_SOFT_RESET_SELECTOR] =
USB_CTRL_USB_PM_SOFT_RESET_MASK,
[USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_SELECTOR] =
USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
[USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7364a0 */
[BRCM_FAMILY_7364A0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7366c0 */
[BRCM_FAMILY_7366C0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 74371A0 */
[BRCM_FAMILY_74371A0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB30_CTL1_USB3_IOC_MASK,
USB_CTRL_USB30_CTL1_USB3_IPP_MASK,
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
[USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
[USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB30_CTL1_USB3_IOC_SELECTOR] =
USB_CTRL_USB30_CTL1_USB3_IOC_MASK,
[USB_CTRL_USB30_CTL1_USB3_IPP_SELECTOR] =
USB_CTRL_USB30_CTL1_USB3_IPP_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7439B0 */
[BRCM_FAMILY_7439B0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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,
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR] =
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7445d0 */
[BRCM_FAMILY_7445D0] = {
USB_CTRL_SETUP_SCB1_EN_MASK,
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 */
0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */
USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */
0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SCB1_EN_SELECTOR] =
USB_CTRL_SETUP_SCB1_EN_MASK,
[USB_CTRL_SETUP_SCB2_EN_SELECTOR] =
USB_CTRL_SETUP_SCB2_EN_MASK,
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
[USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7260a0 */
[BRCM_FAMILY_7260A0] = {
0, /* USB_CTRL_SETUP_SCB1_EN_MASK */
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,
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
USB_CTRL_USB_PM_SOFT_RESET_MASK,
USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR] =
USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK,
[USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR] =
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
[USB_CTRL_USB_PM_SOFT_RESET_SELECTOR] =
USB_CTRL_USB_PM_SOFT_RESET_MASK,
[USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_SELECTOR] =
USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK,
[USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK,
[USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR] =
USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
},
/* 7278a0 */
[BRCM_FAMILY_7278A0] = {
0, /* USB_CTRL_SETUP_SCB1_EN_MASK */
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,
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
USB_CTRL_USB_PM_USB_PWRDN_MASK,
0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */
0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
USB_CTRL_USB_PM_SOFT_RESET_MASK,
0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */
0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */
0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */
0, /* USB_CTRL_SETUP ENDIAN bits */
[USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR] =
USB_CTRL_SETUP_STRAP_IPP_SEL_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK,
[USB_CTRL_SETUP_OC3_DISABLE_SELECTOR] =
USB_CTRL_SETUP_OC3_DISABLE_MASK,
[USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
USB_CTRL_USB_PM_USB_PWRDN_MASK,
[USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR] =
USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
[USB_CTRL_USB_PM_SOFT_RESET_SELECTOR] =
USB_CTRL_USB_PM_SOFT_RESET_MASK,
},
};

View File

@ -667,7 +667,7 @@ MODULE_DEVICE_TABLE(of, brcm_usb_dt_ids);
static struct platform_driver brcm_usb_driver = {
.probe = brcm_usb_phy_probe,
.remove_new = brcm_usb_phy_remove,
.remove = brcm_usb_phy_remove,
.driver = {
.name = "brcmstb-usb-phy",
.pm = &brcm_usb_phy_pm_ops,

View File

@ -472,7 +472,7 @@ MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
static struct platform_driver cdns_dphy_platform_driver = {
.probe = cdns_dphy_probe,
.remove_new = cdns_dphy_remove,
.remove = cdns_dphy_remove,
.driver = {
.name = "cdns-mipi-dphy",
.of_match_table = cdns_dphy_of_match,

View File

@ -2731,7 +2731,7 @@ MODULE_DEVICE_TABLE(of, cdns_sierra_id_table);
static struct platform_driver cdns_sierra_driver = {
.probe = cdns_sierra_phy_probe,
.remove_new = cdns_sierra_phy_remove,
.remove = cdns_sierra_phy_remove,
.driver = {
.name = "cdns-sierra-phy",
.of_match_table = cdns_sierra_id_table,

View File

@ -5440,8 +5440,8 @@ MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match);
static struct platform_driver cdns_torrent_phy_driver = {
.probe = cdns_torrent_phy_probe,
.remove_new = cdns_torrent_phy_remove,
.driver = {
.remove = cdns_torrent_phy_remove,
.driver = {
.name = "cdns-torrent-phy",
.of_match_table = cdns_torrent_phy_of_match,
.pm = pm_sleep_ptr(&cdns_torrent_phy_pm_ops),

View File

@ -433,12 +433,12 @@ static const struct of_device_id mixel_lvds_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, mixel_lvds_phy_of_match);
static struct platform_driver mixel_lvds_phy_driver = {
.probe = mixel_lvds_phy_probe,
.remove_new = mixel_lvds_phy_remove,
.probe = mixel_lvds_phy_probe,
.remove = mixel_lvds_phy_remove,
.driver = {
.pm = &mixel_lvds_phy_pm_ops,
.name = "mixel-lvds-phy",
.of_match_table = mixel_lvds_phy_of_match,
.of_match_table = mixel_lvds_phy_of_match,
}
};
module_platform_driver(mixel_lvds_phy_driver);

View File

@ -631,9 +631,9 @@ static const struct of_device_id lynx_28g_of_match_table[] = {
MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table);
static struct platform_driver lynx_28g_driver = {
.probe = lynx_28g_probe,
.remove_new = lynx_28g_remove,
.driver = {
.probe = lynx_28g_probe,
.remove = lynx_28g_remove,
.driver = {
.name = "lynx-28g",
.of_match_table = lynx_28g_of_match_table,
},

View File

@ -14,352 +14,265 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#define PHY_REG_00 0x00
#define PHY_REG_01 0x04
#define PHY_REG_02 0x08
#define PHY_REG_08 0x20
#define PHY_REG_09 0x24
#define PHY_REG_10 0x28
#define PHY_REG_11 0x2c
#define PHY_REG(reg) (reg * 4)
#define PHY_REG_12 0x30
#define REG12_CK_DIV_MASK GENMASK(5, 4)
#define REG01_PMS_P_MASK GENMASK(3, 0)
#define REG03_PMS_S_MASK GENMASK(7, 4)
#define REG12_CK_DIV_MASK GENMASK(5, 4)
#define PHY_REG_13 0x34
#define REG13_TG_CODE_LOW_MASK GENMASK(7, 0)
#define REG13_TG_CODE_LOW_MASK GENMASK(7, 0)
#define PHY_REG_14 0x38
#define REG14_TOL_MASK GENMASK(7, 4)
#define REG14_RP_CODE_MASK GENMASK(3, 1)
#define REG14_TG_CODE_HIGH_MASK GENMASK(0, 0)
#define PHY_REG_15 0x3c
#define PHY_REG_16 0x40
#define PHY_REG_17 0x44
#define PHY_REG_18 0x48
#define PHY_REG_19 0x4c
#define PHY_REG_20 0x50
#define PHY_REG_21 0x54
#define REG21_SEL_TX_CK_INV BIT(7)
#define REG21_PMS_S_MASK GENMASK(3, 0)
#define PHY_REG_22 0x58
#define PHY_REG_23 0x5c
#define PHY_REG_24 0x60
#define PHY_REG_25 0x64
#define PHY_REG_26 0x68
#define PHY_REG_27 0x6c
#define PHY_REG_28 0x70
#define PHY_REG_29 0x74
#define PHY_REG_30 0x78
#define PHY_REG_31 0x7c
#define PHY_REG_32 0x80
#define REG14_TOL_MASK GENMASK(7, 4)
#define REG14_RP_CODE_MASK GENMASK(3, 1)
#define REG14_TG_CODE_HIGH_MASK GENMASK(0, 0)
#define REG21_SEL_TX_CK_INV BIT(7)
#define REG21_PMS_S_MASK GENMASK(3, 0)
/*
* REG33 does not match the ref manual. According to Sandor Yu from NXP,
* "There is a doc issue on the i.MX8MP latest RM"
* REG33 is being used per guidance from Sandor
*/
#define REG33_MODE_SET_DONE BIT(7)
#define REG33_FIX_DA BIT(1)
#define PHY_REG_33 0x84
#define REG33_MODE_SET_DONE BIT(7)
#define REG33_FIX_DA BIT(1)
#define REG34_PHY_READY BIT(7)
#define REG34_PLL_LOCK BIT(6)
#define REG34_PHY_CLK_READY BIT(5)
#define PHY_REG_34 0x88
#define REG34_PHY_READY BIT(7)
#define REG34_PLL_LOCK BIT(6)
#define REG34_PHY_CLK_READY BIT(5)
#ifndef MHZ
#define MHZ (1000UL * 1000UL)
#endif
#define PHY_REG_35 0x8c
#define PHY_REG_36 0x90
#define PHY_REG_37 0x94
#define PHY_REG_38 0x98
#define PHY_REG_39 0x9c
#define PHY_REG_40 0xa0
#define PHY_REG_41 0xa4
#define PHY_REG_42 0xa8
#define PHY_REG_43 0xac
#define PHY_REG_44 0xb0
#define PHY_REG_45 0xb4
#define PHY_REG_46 0xb8
#define PHY_REG_47 0xbc
#define PHY_PLL_DIV_REGS_NUM 6
#define PHY_PLL_DIV_REGS_NUM 7
struct phy_config {
u32 pixclk;
u8 pll_div_regs[PHY_PLL_DIV_REGS_NUM];
};
/*
* The calculated_phy_pll_cfg only handles integer divider for PMS,
* meaning the last four entries will be fixed, but the first three will
* be calculated by the PMS calculator.
*/
static struct phy_config calculated_phy_pll_cfg = {
.pixclk = 0,
.pll_div_regs = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
};
/* The lookup table contains values for which the fractional divder is used */
static const struct phy_config phy_pll_cfg[] = {
{
.pixclk = 22250000,
.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 23750000,
.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
}, {
.pixclk = 24000000,
.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
}, {
.pixclk = 24024000,
.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
}, {
.pixclk = 25175000,
.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
}, {
.pixclk = 25200000,
.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
}, {
.pixclk = 26750000,
.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 27000000,
.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 27027000,
.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 29500000,
.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
}, {
.pixclk = 30750000,
.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
}, {
.pixclk = 30888000,
.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
.pll_div_regs = { 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
}, {
.pixclk = 33750000,
.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
}, {
.pixclk = 35000000,
.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
}, {
.pixclk = 36000000,
.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
}, {
.pixclk = 36036000,
.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 40000000,
.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
}, {
.pixclk = 43200000,
.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
.pll_div_regs = { 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 43243200,
.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 44500000,
.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
.pll_div_regs = { 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
}, {
.pixclk = 47000000,
.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
}, {
.pixclk = 47500000,
.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
}, {
.pixclk = 50349650,
.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
}, {
.pixclk = 50400000,
.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
.pll_div_regs = { 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
}, {
.pixclk = 53250000,
.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
.pll_div_regs = { 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
}, {
.pixclk = 53500000,
.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 54000000,
.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 54054000,
.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 59000000,
.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
}, {
.pixclk = 59340659,
.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
}, {
.pixclk = 59400000,
.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
}, {
.pixclk = 61500000,
.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
.pll_div_regs = { 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
}, {
.pixclk = 63500000,
.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
}, {
.pixclk = 67500000,
.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
}, {
.pixclk = 70000000,
.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
}, {
.pixclk = 72000000,
.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
}, {
.pixclk = 72072000,
.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 74176000,
.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
.pll_div_regs = { 0xd1, 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
}, {
.pixclk = 74250000,
.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
.pll_div_regs = { 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
}, {
.pixclk = 78500000,
.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
}, {
.pixclk = 80000000,
.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
}, {
.pixclk = 82000000,
.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
.pll_div_regs = { 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
}, {
.pixclk = 82500000,
.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
.pll_div_regs = { 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
}, {
.pixclk = 89000000,
.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
}, {
.pixclk = 90000000,
.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
}, {
.pixclk = 94000000,
.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
}, {
.pixclk = 95000000,
.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
}, {
.pixclk = 98901099,
.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
.pll_div_regs = { 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
}, {
.pixclk = 99000000,
.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
.pll_div_regs = { 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
}, {
.pixclk = 100699300,
.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
}, {
.pixclk = 100800000,
.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
}, {
.pixclk = 102500000,
.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
.pll_div_regs = { 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
}, {
.pixclk = 104750000,
.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
.pll_div_regs = { 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
}, {
.pixclk = 106500000,
.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
.pll_div_regs = { 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
}, {
.pixclk = 107000000,
.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 108000000,
.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
}, {
.pixclk = 108108000,
.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 118000000,
.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
}, {
.pixclk = 118800000,
.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
}, {
.pixclk = 123000000,
.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
.pll_div_regs = { 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
}, {
.pixclk = 127000000,
.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
}, {
.pixclk = 135000000,
.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
}, {
.pixclk = 135580000,
.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
.pll_div_regs = { 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
}, {
.pixclk = 137520000,
.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
.pll_div_regs = { 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
}, {
.pixclk = 138750000,
.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
.pll_div_regs = { 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
}, {
.pixclk = 140000000,
.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
}, {
.pixclk = 144000000,
.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
}, {
.pixclk = 148352000,
.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
.pll_div_regs = { 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
}, {
.pixclk = 148500000,
.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
.pll_div_regs = { 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
}, {
.pixclk = 154000000,
.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
.pll_div_regs = { 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
}, {
.pixclk = 157000000,
.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
}, {
.pixclk = 160000000,
.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
}, {
.pixclk = 162000000,
.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
.pll_div_regs = { 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
}, {
.pixclk = 164000000,
.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
.pll_div_regs = { 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
}, {
.pixclk = 165000000,
.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
}, {
.pixclk = 180000000,
.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
.pll_div_regs = { 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
}, {
.pixclk = 185625000,
.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
}, {
.pixclk = 188000000,
.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
}, {
.pixclk = 198000000,
.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
.pll_div_regs = { 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
}, {
.pixclk = 205000000,
.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
.pll_div_regs = { 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
}, {
.pixclk = 209500000,
.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
.pll_div_regs = { 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
}, {
.pixclk = 213000000,
.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
}, {
.pixclk = 216000000,
.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
.pll_div_regs = { 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
}, {
.pixclk = 216216000,
.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 237600000,
.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
}, {
.pixclk = 254000000,
.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
.pll_div_regs = { 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
}, {
.pixclk = 277500000,
.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
}, {
.pixclk = 288000000,
.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
}, {
.pll_div_regs = { 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
}, {
.pixclk = 297000000,
.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
.pll_div_regs = { 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
},
};
@ -369,29 +282,30 @@ struct reg_settings {
};
static const struct reg_settings common_phy_cfg[] = {
{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
{ PHY_REG(0), 0x00 },
/* PHY_REG(1-7) pix clk specific */
{ PHY_REG(8), 0x4f }, { PHY_REG(9), 0x30 },
{ PHY_REG(10), 0x33 }, { PHY_REG(11), 0x65 },
/* REG12 pixclk specific */
/* REG13 pixclk specific */
/* REG14 pixclk specific */
{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
{ PHY_REG(15), 0x80 }, { PHY_REG(16), 0x6c },
{ PHY_REG(17), 0xf2 }, { PHY_REG(18), 0x67 },
{ PHY_REG(19), 0x00 }, { PHY_REG(20), 0x10 },
/* REG21 pixclk specific */
{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
{ PHY_REG(22), 0x30 }, { PHY_REG(23), 0x32 },
{ PHY_REG(24), 0x60 }, { PHY_REG(25), 0x8f },
{ PHY_REG(26), 0x00 }, { PHY_REG(27), 0x00 },
{ PHY_REG(28), 0x08 }, { PHY_REG(29), 0x00 },
{ PHY_REG(30), 0x00 }, { PHY_REG(31), 0x00 },
{ PHY_REG(32), 0x00 }, { PHY_REG(33), 0x80 },
{ PHY_REG(34), 0x00 }, { PHY_REG(35), 0x00 },
{ PHY_REG(36), 0x00 }, { PHY_REG(37), 0x00 },
{ PHY_REG(38), 0x00 }, { PHY_REG(39), 0x00 },
{ PHY_REG(40), 0x00 }, { PHY_REG(41), 0xe0 },
{ PHY_REG(42), 0x83 }, { PHY_REG(43), 0x0f },
{ PHY_REG(44), 0x3E }, { PHY_REG(45), 0xf8 },
{ PHY_REG(46), 0x00 }, { PHY_REG(47), 0x00 }
};
struct fsl_samsung_hdmi_phy {
@ -411,40 +325,6 @@ to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
}
static void
fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
const struct phy_config *cfg)
{
u8 div = 0x1;
switch (cfg->pixclk) {
case 22250000 ... 33750000:
div = 0xf;
break;
case 35000000 ... 40000000:
div = 0xb;
break;
case 43200000 ... 47500000:
div = 0x9;
break;
case 50349650 ... 63500000:
div = 0x7;
break;
case 67500000 ... 90000000:
div = 0x5;
break;
case 94000000 ... 148500000:
div = 0x3;
break;
case 154000000 ... 297000000:
div = 0x1;
break;
}
writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
phy->regs + PHY_REG_21);
}
static void
fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
const struct phy_config *cfg)
@ -469,7 +349,7 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
break;
}
writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
/*
* Calculation for the frequency lock detector target code (fld_tg_code)
@ -489,11 +369,88 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
phy->regs + PHY_REG_13);
phy->regs + PHY_REG(13));
writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
FIELD_PREP(REG14_RP_CODE_MASK, 2) |
FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
phy->regs + PHY_REG_14);
phy->regs + PHY_REG(14));
}
static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u16 *m, u8 *s)
{
unsigned long best_freq = 0;
u32 min_delta = 0xffffffff;
u8 _p, best_p;
u16 _m, best_m;
u8 _s, best_s;
/*
* Figure 13-78 of the reference manual states the PLL should be TMDS x 5
* while the TMDS_CLKO should be the PLL / 5. So to calculate the PLL,
* take the pix clock x 5, then return the value of the PLL / 5.
*/
fout *= 5;
/* The ref manual states the values of 'P' range from 1 to 11 */
for (_p = 1; _p <= 11; ++_p) {
for (_s = 1; _s <= 16; ++_s) {
u64 tmp;
u32 delta;
/* s must be one or even */
if (_s > 1 && (_s & 0x01) == 1)
_s++;
/* _s cannot be 14 per the TRM */
if (_s == 14)
continue;
/*
* TODO: Ref Manual doesn't state the range of _m
* so this should be further refined if possible.
* This range was set based on the original values
* in the lookup table
*/
tmp = (u64)fout * (_p * _s);
do_div(tmp, 24 * MHZ);
_m = tmp;
if (_m < 0x30 || _m > 0x7b)
continue;
/*
* Rev 2 of the Ref Manual states the
* VCO can range between 750MHz and
* 3GHz. The VCO is assumed to be
* Fvco = (M * f_ref) / P,
* where f_ref is 24MHz.
*/
tmp = (u64)_m * 24 * MHZ;
do_div(tmp, _p);
if (tmp < 750 * MHZ ||
tmp > 3000 * MHZ)
continue;
/* Final frequency after post-divider */
do_div(tmp, _s);
delta = abs(fout - tmp);
if (delta < min_delta) {
best_p = _p;
best_s = _s;
best_m = _m;
min_delta = delta;
best_freq = tmp;
}
}
}
if (best_freq) {
*p = best_p;
*m = best_m;
*s = best_s;
}
return best_freq / 5;
}
static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
@ -503,22 +460,25 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
u8 val;
/* HDMI PHY init */
writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
/* common PHY registers */
for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
/* set individual PLL registers PHY_REG1 ... PHY_REG7 */
for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG(1) + i * 4);
/* High nibble of PHY_REG3 and low nibble of PHY_REG21 both contain 'S' */
writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK,
cfg->pll_div_regs[2] >> 4), phy->regs + PHY_REG(21));
fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG(33));
ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
ret = readb_poll_timeout(phy->regs + PHY_REG(34), val,
val & REG34_PLL_LOCK, 50, 20000);
if (ret)
dev_err(phy->dev, "PLL failed to lock\n");
@ -537,34 +497,120 @@ static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
return phy->cur_cfg->pixclk;
}
static long phy_clk_round_rate(struct clk_hw *hw,
unsigned long rate, unsigned long *parent_rate)
/* Helper function to lookup the available fractional-divider rate */
static const struct phy_config *fsl_samsung_hdmi_phy_lookup_rate(unsigned long rate)
{
int i;
/* Search the lookup table */
for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
if (phy_pll_cfg[i].pixclk <= rate)
return phy_pll_cfg[i].pixclk;
break;
return -EINVAL;
return &phy_pll_cfg[i];
}
static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate,
u8 p, u16 m, u8 s)
{
cal_phy->pixclk = rate;
cal_phy->pll_div_regs[0] = FIELD_PREP(REG01_PMS_P_MASK, p);
cal_phy->pll_div_regs[1] = m;
cal_phy->pll_div_regs[2] = FIELD_PREP(REG03_PMS_S_MASK, s-1);
/* pll_div_regs 3-6 are fixed and pre-defined already */
}
static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
u32 int_div_clk, u32 frac_div_clk)
{
/* Calculate the absolute value of the differences and return whichever is closest */
if (abs((long)rate - (long)int_div_clk) < abs((long)(rate - (long)frac_div_clk)))
return int_div_clk;
return frac_div_clk;
}
static long phy_clk_round_rate(struct clk_hw *hw,
unsigned long rate, unsigned long *parent_rate)
{
const struct phy_config *fract_div_phy;
u32 int_div_clk;
u16 m;
u8 p, s;
/* If the clock is out of range return error instead of searching */
if (rate > 297000000 || rate < 22250000)
return -EINVAL;
/* Search the fractional divider lookup table */
fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
/* If the rate is an exact match, return that value */
if (rate == fract_div_phy->pixclk)
return fract_div_phy->pixclk;
/* If the exact match isn't found, calculate the integer divider */
int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
/* If the int_div_clk rate is an exact match, return that value */
if (int_div_clk == rate)
return int_div_clk;
/* If neither rate is an exact match, use the value from the LUT */
return fract_div_phy->pixclk;
}
static int phy_use_fract_div(struct fsl_samsung_hdmi_phy *phy, const struct phy_config *fract_div_phy)
{
phy->cur_cfg = fract_div_phy;
dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
phy->cur_cfg->pixclk);
return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
}
static int phy_use_integer_div(struct fsl_samsung_hdmi_phy *phy,
const struct phy_config *int_div_clk)
{
phy->cur_cfg = &calculated_phy_pll_cfg;
dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
phy->cur_cfg->pixclk);
return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
}
static int phy_clk_set_rate(struct clk_hw *hw,
unsigned long rate, unsigned long parent_rate)
{
struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
int i;
const struct phy_config *fract_div_phy;
u32 int_div_clk;
u16 m;
u8 p, s;
for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
if (phy_pll_cfg[i].pixclk <= rate)
break;
/* Search the fractional divider lookup table */
fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
if (i < 0)
return -EINVAL;
/* If the rate is an exact match, use that value */
if (fract_div_phy->pixclk == rate)
return phy_use_fract_div(phy, fract_div_phy);
phy->cur_cfg = &phy_pll_cfg[i];
/*
* If the rate from the fractional divider is not exact, check the integer divider,
* and use it if that value is an exact match.
*/
int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
if (int_div_clk == rate)
return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
/*
* Compare the difference between the integer clock and the fractional clock against
* the desired clock and which whichever is closest.
*/
if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
fract_div_phy->pixclk) == fract_div_phy->pixclk)
return phy_use_fract_div(phy, fract_div_phy);
else
return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
}
static const struct clk_ops phy_clk_ops = {
@ -703,8 +749,8 @@ static const struct of_device_id fsl_samsung_hdmi_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, fsl_samsung_hdmi_phy_of_match);
static struct platform_driver fsl_samsung_hdmi_phy_driver = {
.probe = fsl_samsung_hdmi_phy_probe,
.remove_new = fsl_samsung_hdmi_phy_remove,
.probe = fsl_samsung_hdmi_phy_probe,
.remove = fsl_samsung_hdmi_phy_remove,
.driver = {
.name = "fsl-samsung-hdmi-phy",
.of_match_table = fsl_samsung_hdmi_phy_of_match,

View File

@ -605,7 +605,7 @@ static const struct of_device_id of_intel_cbphy_match[] = {
static struct platform_driver intel_cbphy_driver = {
.probe = intel_cbphy_probe,
.remove_new = intel_cbphy_remove,
.remove = intel_cbphy_remove,
.driver = {
.name = "intel-combo-phy",
.of_match_table = of_intel_cbphy_match,

View File

@ -62,6 +62,8 @@
#define SQ_AMP_CAL_MASK GENMASK(2, 0)
#define SQ_AMP_CAL_VAL 1
#define SQ_AMP_CAL_EN BIT(3)
#define UTMI_DIG_CTRL1_REG 0x20
#define SWAP_DPDM BIT(15)
#define UTMI_CTRL_STATUS0_REG 0x24
#define SUSPENDM BIT(22)
#define TEST_SEL BIT(25)
@ -99,11 +101,13 @@ struct mvebu_cp110_utmi {
* @priv: PHY driver data
* @id: PHY port ID
* @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL
* @swap_dx: whether to swap d+/d- signals
*/
struct mvebu_cp110_utmi_port {
struct mvebu_cp110_utmi *priv;
u32 id;
enum usb_dr_mode dr_mode;
bool swap_dx;
};
static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
@ -159,6 +163,13 @@ static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
reg &= ~(VDAT_MASK | VSRC_MASK);
reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET);
writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
/* Swap D+/D- */
reg = readl(PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
reg &= ~(SWAP_DPDM);
if (port->swap_dx)
reg |= SWAP_DPDM;
writel(reg, PORT_REGS(port) + UTMI_DIG_CTRL1_REG);
}
static int mvebu_cp110_utmi_phy_power_off(struct phy *phy)
@ -286,6 +297,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
struct phy_provider *provider;
struct device_node *child;
u32 usb_devices = 0;
u32 swap_dx = 0;
utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
if (!utmi)
@ -345,6 +357,10 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
}
}
of_property_for_each_u32(dev->of_node, "swap-dx-lanes", swap_dx)
if (swap_dx == port_id)
port->swap_dx = 1;
/* Retrieve PHY capabilities */
utmi->ops = &mvebu_cp110_utmi_phy_ops;

View File

@ -21,23 +21,33 @@
#include "sparx5_serdes.h"
#define SPX5_CMU_MAX 14
#define SPX5_SERDES_10G_START 13
#define SPX5_SERDES_25G_START 25
#define SPX5_SERDES_6G10G_CNT SPX5_SERDES_25G_START
#define LAN969X_SERDES_10G_CNT 10
/* Optimal power settings from GUC */
#define SPX5_SERDES_QUIET_MODE_VAL 0x01ef4e0c
enum sparx5_10g28cmu_mode {
SPX5_SD10G28_CMU_MAIN = 0,
SPX5_SD10G28_CMU_AUX1 = 1,
SPX5_SD10G28_CMU_AUX2 = 3,
SPX5_SD10G28_CMU_NONE = 4,
SPX5_SD10G28_CMU_MAX,
/* Register target sizes */
const unsigned int sparx5_serdes_tsize[TSIZE_LAST] = {
[TC_SD10G_LANE] = 12,
[TC_SD_CMU] = 14,
[TC_SD_CMU_CFG] = 14,
[TC_SD_LANE] = 25,
};
const unsigned int lan969x_serdes_tsize[TSIZE_LAST] = {
[TC_SD10G_LANE] = 10,
[TC_SD_CMU] = 6,
[TC_SD_CMU_CFG] = 6,
[TC_SD_LANE] = 10,
};
/* Pointer to the register target size table */
const unsigned int *tsize;
enum sparx5_sd25g28_mode_preset_type {
SPX5_SD25G28_MODE_PRESET_25000,
SPX5_SD25G28_MODE_PRESET_10000,
@ -1095,13 +1105,31 @@ static int sparx5_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
return sparx5_serdes_cmu_map[mode][sd_index];
}
/* Map of 6G/10G serdes mode and index to CMU index. */
static const int
lan969x_serdes_cmu_map[SPX5_SD10G28_CMU_MAX][LAN969X_SERDES_10G_CNT] = {
[SPX5_SD10G28_CMU_MAIN] = { 2, 2, 2, 2, 2,
2, 2, 2, 5, 5 },
[SPX5_SD10G28_CMU_AUX1] = { 0, 0, 3, 3, 3,
3, 3, 3, 3, 3 },
[SPX5_SD10G28_CMU_AUX2] = { 1, 1, 1, 1, 4,
4, 4, 4, 4, 4 },
[SPX5_SD10G28_CMU_NONE] = { 1, 1, 1, 1, 4,
4, 4, 4, 4, 4 },
};
static int lan969x_serdes_cmu_get(enum sparx5_10g28cmu_mode mode, int sd_index)
{
return lan969x_serdes_cmu_map[mode][sd_index];
}
static void sparx5_serdes_cmu_power_off(struct sparx5_serdes_private *priv)
{
void __iomem *cmu_inst, *cmu_cfg_inst;
int i;
/* Power down each CMU */
for (i = 0; i < SPX5_CMU_MAX; i++) {
for (i = 0; i < priv->data->consts.cmu_max; i++) {
cmu_inst = sdx5_inst_get(priv, TARGET_SD_CMU, i);
cmu_cfg_inst = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, i);
@ -1650,7 +1678,7 @@ static int sparx5_sd10g28_apply_params(struct sparx5_serdes_macro *macro,
if (params->skip_cmu_cfg)
return 0;
cmu_idx = sparx5_serdes_cmu_get(params->cmu_sel, lane_index);
cmu_idx = priv->data->ops.serdes_cmu_get(params->cmu_sel, macro->sidx);
err = sparx5_cmu_cfg(priv, cmu_idx);
if (err)
return err;
@ -2183,6 +2211,10 @@ static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
{
struct sparx5_serdes_private *priv = macro->priv;
/* Clock is auto-detected in 100Base-FX mode on lan969x */
if (priv->data->type == SPX5_TARGET_LAN969X)
return 0;
if (macro->serdesmode == SPX5_SD_MODE_100FX) {
u32 freq = priv->coreclock == 250000000 ? 2 :
priv->coreclock == 500000000 ? 1 : 0;
@ -2297,10 +2329,12 @@ static int sparx5_serdes_set_speed(struct phy *phy, int speed)
{
struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
return -EINVAL;
if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
return -EINVAL;
if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
return -EINVAL;
if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
return -EINVAL;
}
if (speed != macro->speed) {
macro->speed = speed;
if (macro->serdesmode != SPX5_SD_MODE_NONE)
@ -2337,11 +2371,14 @@ static int sparx5_serdes_validate(struct phy *phy, enum phy_mode mode,
if (macro->speed == 0)
return -EINVAL;
if (macro->sidx < SPX5_SERDES_10G_START && macro->speed > SPEED_5000)
return -EINVAL;
if (macro->sidx < SPX5_SERDES_25G_START && macro->speed > SPEED_10000)
return -EINVAL;
if (macro->priv->data->type == SPX5_TARGET_SPARX5) {
if (macro->sidx < SPX5_SERDES_10G_START &&
macro->speed > SPEED_5000)
return -EINVAL;
if (macro->sidx < SPX5_SERDES_25G_START &&
macro->speed > SPEED_10000)
return -EINVAL;
}
switch (submode) {
case PHY_INTERFACE_MODE_1000BASEX:
if (macro->speed != SPEED_100 && /* This is for 100BASE-FX */
@ -2375,6 +2412,26 @@ static const struct phy_ops sparx5_serdes_ops = {
.owner = THIS_MODULE,
};
static void sparx5_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
{
if (sidx < SPX5_SERDES_10G_START) {
macro->serdestype = SPX5_SDT_6G;
macro->stpidx = macro->sidx;
} else if (sidx < SPX5_SERDES_25G_START) {
macro->serdestype = SPX5_SDT_10G;
macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
} else {
macro->serdestype = SPX5_SDT_25G;
macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
}
}
static void lan969x_serdes_type_set(struct sparx5_serdes_macro *macro, int sidx)
{
macro->serdestype = SPX5_SDT_10G;
macro->stpidx = macro->sidx;
}
static int sparx5_phy_create(struct sparx5_serdes_private *priv,
int idx, struct phy **phy)
{
@ -2391,16 +2448,8 @@ static int sparx5_phy_create(struct sparx5_serdes_private *priv,
macro->sidx = idx;
macro->priv = priv;
macro->speed = SPEED_UNKNOWN;
if (idx < SPX5_SERDES_10G_START) {
macro->serdestype = SPX5_SDT_6G;
macro->stpidx = macro->sidx;
} else if (idx < SPX5_SERDES_25G_START) {
macro->serdestype = SPX5_SDT_10G;
macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
} else {
macro->serdestype = SPX5_SDT_25G;
macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
}
priv->data->ops.serdes_type_set(macro, idx);
phy_set_drvdata(*phy, macro);
@ -2507,6 +2556,71 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] = {
{ TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
};
static const struct sparx5_serdes_io_resource lan969x_serdes_iomap[] = {
{ TARGET_SD_CMU, 0x0 }, /* 0xe3410000 */
{ TARGET_SD_CMU + 1, 0x8000 }, /* 0xe3418000 */
{ TARGET_SD_CMU + 2, 0x10000 }, /* 0xe3420000 */
{ TARGET_SD_CMU + 3, 0x18000 }, /* 0xe3428000 */
{ TARGET_SD_CMU + 4, 0x20000 }, /* 0xe3430000 */
{ TARGET_SD_CMU + 5, 0x28000 }, /* 0xe3438000 */
{ TARGET_SD_CMU_CFG, 0x30000 }, /* 0xe3440000 */
{ TARGET_SD_CMU_CFG + 1, 0x38000 }, /* 0xe3448000 */
{ TARGET_SD_CMU_CFG + 2, 0x40000 }, /* 0xe3450000 */
{ TARGET_SD_CMU_CFG + 3, 0x48000 }, /* 0xe3458000 */
{ TARGET_SD_CMU_CFG + 4, 0x50000 }, /* 0xe3460000 */
{ TARGET_SD_CMU_CFG + 5, 0x58000 }, /* 0xe3468000 */
{ TARGET_SD10G_LANE, 0x60000 }, /* 0xe3470000 */
{ TARGET_SD10G_LANE + 1, 0x68000 }, /* 0xe3478000 */
{ TARGET_SD10G_LANE + 2, 0x70000 }, /* 0xe3480000 */
{ TARGET_SD10G_LANE + 3, 0x78000 }, /* 0xe3488000 */
{ TARGET_SD10G_LANE + 4, 0x80000 }, /* 0xe3490000 */
{ TARGET_SD10G_LANE + 5, 0x88000 }, /* 0xe3498000 */
{ TARGET_SD10G_LANE + 6, 0x90000 }, /* 0xe34a0000 */
{ TARGET_SD10G_LANE + 7, 0x98000 }, /* 0xe34a8000 */
{ TARGET_SD10G_LANE + 8, 0xa0000 }, /* 0xe34b0000 */
{ TARGET_SD10G_LANE + 9, 0xa8000 }, /* 0xe34b8000 */
{ TARGET_SD_LANE, 0x100000 }, /* 0xe3510000 */
{ TARGET_SD_LANE + 1, 0x108000 }, /* 0xe3518000 */
{ TARGET_SD_LANE + 2, 0x110000 }, /* 0xe3520000 */
{ TARGET_SD_LANE + 3, 0x118000 }, /* 0xe3528000 */
{ TARGET_SD_LANE + 4, 0x120000 }, /* 0xe3530000 */
{ TARGET_SD_LANE + 5, 0x128000 }, /* 0xe3538000 */
{ TARGET_SD_LANE + 6, 0x130000 }, /* 0xe3540000 */
{ TARGET_SD_LANE + 7, 0x138000 }, /* 0xe3548000 */
{ TARGET_SD_LANE + 8, 0x140000 }, /* 0xe3550000 */
{ TARGET_SD_LANE + 9, 0x148000 }, /* 0xe3558000 */
};
static const struct sparx5_serdes_match_data sparx5_desc = {
.type = SPX5_TARGET_SPARX5,
.iomap = sparx5_serdes_iomap,
.iomap_size = ARRAY_SIZE(sparx5_serdes_iomap),
.tsize = sparx5_serdes_tsize,
.consts = {
.sd_max = 33,
.cmu_max = 14,
},
.ops = {
.serdes_type_set = &sparx5_serdes_type_set,
.serdes_cmu_get = &sparx5_serdes_cmu_get,
},
};
static const struct sparx5_serdes_match_data lan969x_desc = {
.type = SPX5_TARGET_LAN969X,
.iomap = lan969x_serdes_iomap,
.iomap_size = ARRAY_SIZE(lan969x_serdes_iomap),
.tsize = lan969x_serdes_tsize,
.consts = {
.sd_max = 10,
.cmu_max = 6,
},
.ops = {
.serdes_type_set = &lan969x_serdes_type_set,
.serdes_cmu_get = &lan969x_serdes_cmu_get,
}
};
/* Client lookup function, uses serdes index */
static struct phy *sparx5_serdes_xlate(struct device *dev,
const struct of_phandle_args *args)
@ -2521,7 +2635,7 @@ static struct phy *sparx5_serdes_xlate(struct device *dev,
sidx = args->args[0];
/* Check validity: ERR_PTR(-ENODEV) if not valid */
for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
struct sparx5_serdes_macro *macro =
phy_get_drvdata(priv->phys[idx]);
@ -2555,6 +2669,12 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
priv->dev = &pdev->dev;
priv->data = device_get_match_data(priv->dev);
if (!priv->data)
return -EINVAL;
tsize = priv->data->tsize;
/* Get coreclock */
clk = devm_clk_get(priv->dev, NULL);
if (IS_ERR(clk)) {
@ -2579,19 +2699,21 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
iores->name);
return -ENOMEM;
}
for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) {
struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
for (idx = 0; idx < priv->data->iomap_size; idx++) {
const struct sparx5_serdes_io_resource *iomap =
&priv->data->iomap[idx];
priv->regs[iomap->id] = iomem + iomap->offset;
}
for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
for (idx = 0; idx < priv->data->consts.sd_max; idx++) {
err = sparx5_phy_create(priv, idx, &priv->phys[idx]);
if (err)
return err;
}
/* Power down all CMUs by default */
sparx5_serdes_cmu_power_off(priv);
/* Power down all CMU's by default */
if (priv->data->type == SPX5_TARGET_SPARX5)
sparx5_serdes_cmu_power_off(priv);
provider = devm_of_phy_provider_register(priv->dev, sparx5_serdes_xlate);
@ -2599,7 +2721,8 @@ static int sparx5_serdes_probe(struct platform_device *pdev)
}
static const struct of_device_id sparx5_serdes_match[] = {
{ .compatible = "microchip,sparx5-serdes" },
{ .compatible = "microchip,sparx5-serdes", .data = &sparx5_desc },
{ .compatible = "microchip,lan9691-serdes", .data = &lan969x_desc },
{ }
};
MODULE_DEVICE_TABLE(of, sparx5_serdes_match);

View File

@ -26,11 +26,18 @@ enum sparx5_serdes_mode {
SPX5_SD_MODE_SFI,
};
struct sparx5_serdes_private {
struct device *dev;
void __iomem *regs[NUM_TARGETS];
struct phy *phys[SPX5_SERDES_MAX];
unsigned long coreclock;
enum sparx5_10g28cmu_mode {
SPX5_SD10G28_CMU_MAIN = 0,
SPX5_SD10G28_CMU_AUX1 = 1,
SPX5_SD10G28_CMU_AUX2 = 3,
SPX5_SD10G28_CMU_NONE = 4,
SPX5_SD10G28_CMU_MAX,
};
enum sparx5_target {
SPX5_TARGET_SPARX5,
SPX5_TARGET_LAN969X,
};
struct sparx5_serdes_macro {
@ -44,6 +51,33 @@ struct sparx5_serdes_macro {
enum phy_media media;
};
struct sparx5_serdes_consts {
int sd_max;
int cmu_max;
};
struct sparx5_serdes_ops {
void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
};
struct sparx5_serdes_match_data {
enum sparx5_target type;
const struct sparx5_serdes_consts consts;
const struct sparx5_serdes_ops ops;
const struct sparx5_serdes_io_resource *iomap;
int iomap_size;
const unsigned int *tsize;
};
struct sparx5_serdes_private {
struct device *dev;
void __iomem *regs[NUM_TARGETS];
struct phy *phys[SPX5_SERDES_MAX];
unsigned long coreclock;
const struct sparx5_serdes_match_data *data;
};
/* Read, Write and modify registers content.
* The register definition macros start at the id
*/

File diff suppressed because it is too large Load Diff

View File

@ -704,7 +704,7 @@ static void cpcap_usb_phy_remove(struct platform_device *pdev)
static struct platform_driver cpcap_usb_phy_driver = {
.probe = cpcap_usb_phy_probe,
.remove_new = cpcap_usb_phy_remove,
.remove = cpcap_usb_phy_remove,
.driver = {
.name = "cpcap-usb-phy",
.of_match_table = of_match_ptr(cpcap_usb_phy_id_table),

View File

@ -655,7 +655,7 @@ static void phy_mdm6600_remove(struct platform_device *pdev)
static struct platform_driver phy_mdm6600_driver = {
.probe = phy_mdm6600_probe,
.remove_new = phy_mdm6600_remove,
.remove = phy_mdm6600_remove,
.driver = {
.name = "phy-mapphone-mdm6600",
.pm = &phy_mdm6600_pm_ops,

View File

@ -197,9 +197,9 @@
#define CSR_2L_PXP_TX1_MULTLANE_EN BIT(0)
#define REG_CSR_2L_RX0_REV0 0x00fc
#define CSR_2L_PXP_VOS_PNINV GENMASK(3, 2)
#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE GENMASK(6, 4)
#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE GENMASK(10, 8)
#define CSR_2L_PXP_VOS_PNINV GENMASK(19, 18)
#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE GENMASK(22, 20)
#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE GENMASK(26, 24)
#define REG_CSR_2L_RX0_PHYCK_DIV 0x0100
#define CSR_2L_PXP_RX0_PHYCK_SEL GENMASK(9, 8)

View File

@ -459,7 +459,7 @@ static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy)
airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET,
CSR_2L_PXP_CLKTX1_SR);
airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0,
CSR_2L_PXP_PLL_RESERVE_MASK, 0xdd);
CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d);
}
static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy)
@ -471,9 +471,9 @@ static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy)
PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST |
PCIE_SW_RX_RST);
airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET,
PCIE_TX_TOP_RST | REG_PCIE_PMA_TX_RESET);
PCIE_TX_TOP_RST | PCIE_TX_CAL_RST);
airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET,
PCIE_TX_TOP_RST | REG_PCIE_PMA_TX_RESET);
PCIE_TX_TOP_RST | PCIE_TX_CAL_RST);
}
static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy)
@ -802,7 +802,7 @@ static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy)
airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM,
CSR_2L_PXP_JCPLL_SDM_IFM);
airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN,
REG_CSR_2L_JCPLL_SDM_HREN);
CSR_2L_PXP_JCPLL_SDM_HREN);
airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY,
CSR_2L_PXP_JCPLL_SDM_DI_EN);
airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC,

View File

@ -271,7 +271,7 @@ static struct platform_driver lgm_phy_driver = {
.of_match_table = intel_usb_phy_dt_ids,
},
.probe = phy_probe,
.remove_new = phy_remove,
.remove = phy_remove,
};
module_platform_driver(lgm_phy_driver);

View File

@ -0,0 +1,123 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2024, Linaro Limited
*/
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#define NUM_SUPPLIES 2
struct ptn3222 {
struct i2c_client *client;
struct phy *phy;
struct gpio_desc *reset_gpio;
struct regulator_bulk_data *supplies;
};
static int ptn3222_init(struct phy *phy)
{
struct ptn3222 *ptn3222 = phy_get_drvdata(phy);
int ret;
ret = regulator_bulk_enable(NUM_SUPPLIES, ptn3222->supplies);
if (ret)
return ret;
gpiod_set_value_cansleep(ptn3222->reset_gpio, 0);
return 0;
}
static int ptn3222_exit(struct phy *phy)
{
struct ptn3222 *ptn3222 = phy_get_drvdata(phy);
gpiod_set_value_cansleep(ptn3222->reset_gpio, 1);
return regulator_bulk_disable(NUM_SUPPLIES, ptn3222->supplies);
}
static const struct phy_ops ptn3222_ops = {
.init = ptn3222_init,
.exit = ptn3222_exit,
.owner = THIS_MODULE,
};
static const struct regulator_bulk_data ptn3222_supplies[NUM_SUPPLIES] = {
{
.supply = "vdd3v3",
.init_load_uA = 11000,
}, {
.supply = "vdd1v8",
.init_load_uA = 55000,
}
};
static int ptn3222_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct phy_provider *phy_provider;
struct ptn3222 *ptn3222;
int ret;
ptn3222 = devm_kzalloc(dev, sizeof(*ptn3222), GFP_KERNEL);
if (!ptn3222)
return -ENOMEM;
ptn3222->client = client;
ptn3222->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(ptn3222->reset_gpio))
return dev_err_probe(dev, PTR_ERR(ptn3222->reset_gpio),
"unable to acquire reset gpio\n");
ret = devm_regulator_bulk_get_const(dev, NUM_SUPPLIES, ptn3222_supplies,
&ptn3222->supplies);
if (ret)
return ret;
ptn3222->phy = devm_phy_create(dev, dev->of_node, &ptn3222_ops);
if (IS_ERR(ptn3222->phy)) {
dev_err(dev, "failed to create PHY: %d\n", ret);
return PTR_ERR(ptn3222->phy);
}
phy_set_drvdata(ptn3222->phy, ptn3222);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct i2c_device_id ptn3222_table[] = {
{ "ptn3222" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ptn3222_table);
static const struct of_device_id ptn3222_of_table[] = {
{ .compatible = "nxp,ptn3222" },
{ }
};
MODULE_DEVICE_TABLE(of, ptn3222_of_table);
static struct i2c_driver ptn3222_driver = {
.driver = {
.name = "ptn3222",
.of_match_table = ptn3222_of_table,
},
.probe = ptn3222_probe,
.id_table = ptn3222_table,
};
module_i2c_driver(ptn3222_driver);
MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver");
MODULE_LICENSE("GPL");

View File

@ -257,12 +257,12 @@ static const struct of_device_id qcom_apq8064_sata_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, qcom_apq8064_sata_phy_of_match);
static struct platform_driver qcom_apq8064_sata_phy_driver = {
.probe = qcom_apq8064_sata_phy_probe,
.remove_new = qcom_apq8064_sata_phy_remove,
.probe = qcom_apq8064_sata_phy_probe,
.remove = qcom_apq8064_sata_phy_remove,
.driver = {
.name = "qcom-apq8064-sata-phy",
.of_match_table = qcom_apq8064_sata_phy_of_match,
}
.name = "qcom-apq8064-sata-phy",
.of_match_table = qcom_apq8064_sata_phy_of_match,
},
};
module_platform_driver(qcom_apq8064_sata_phy_driver);

View File

@ -32,16 +32,8 @@
#define DP_PHY_PD_CTL 0x001c
#define DP_PHY_MODE 0x0020
#define DP_PHY_AUX_CFG0 0x0024
#define DP_PHY_AUX_CFG1 0x0028
#define DP_PHY_AUX_CFG2 0x002C
#define DP_PHY_AUX_CFG3 0x0030
#define DP_PHY_AUX_CFG4 0x0034
#define DP_PHY_AUX_CFG5 0x0038
#define DP_PHY_AUX_CFG6 0x003C
#define DP_PHY_AUX_CFG7 0x0040
#define DP_PHY_AUX_CFG8 0x0044
#define DP_PHY_AUX_CFG9 0x0048
#define DP_AUX_CFG_SIZE 10
#define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n)))
#define DP_PHY_AUX_INTERRUPT_MASK 0x0058
@ -90,6 +82,7 @@ struct phy_ver_ops {
struct qcom_edp_phy_cfg {
bool is_edp;
const u8 *aux_cfg;
const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
const struct phy_ver_ops *ver_ops;
};
@ -186,11 +179,40 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
};
static const u8 edp_phy_aux_cfg_v4[10] = {
0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
};
static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
{ 0x05, 0x11, 0x17, 0x1d },
{ 0x05, 0x11, 0x18, 0xff },
{ 0x06, 0x11, 0xff, 0xff },
{ 0x00, 0xff, 0xff, 0xff }
};
static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
{ 0x0c, 0x15, 0x19, 0x1e },
{ 0x0b, 0x15, 0x19, 0xff },
{ 0x0e, 0x14, 0xff, 0xff },
{ 0x0d, 0xff, 0xff, 0xff }
};
static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
.swing_hbr_rbr = &edp_swing_hbr_rbr,
.swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
.pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
};
static const u8 edp_phy_aux_cfg_v5[10] = {
0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
};
static int qcom_edp_phy_init(struct phy *phy)
{
struct qcom_edp *edp = phy_get_drvdata(phy);
u8 aux_cfg[DP_AUX_CFG_SIZE];
int ret;
u8 cfg8;
ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
if (ret)
@ -200,6 +222,8 @@ static int qcom_edp_phy_init(struct phy *phy)
if (ret)
goto out_disable_supplies;
memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
edp->edp + DP_PHY_PD_CTL);
@ -222,22 +246,12 @@ static int qcom_edp_phy_init(struct phy *phy)
* even needed.
*/
if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
cfg8 = 0xb7;
else
cfg8 = 0x37;
aux_cfg[8] = 0xb7;
writel(0xfc, edp->edp + DP_PHY_MODE);
writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
writel(cfg8, edp->edp + DP_PHY_AUX_CFG8);
writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
for (int i = 0; i < DP_AUX_CFG_SIZE; i++)
writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i));
writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
@ -518,17 +532,27 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
.com_configure_ssc = qcom_edp_com_configure_ssc_v4,
};
static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
.is_edp = false,
.aux_cfg = edp_phy_aux_cfg_v5,
.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
.ver_ops = &qcom_edp_phy_ops_v4,
};
static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.ver_ops = &qcom_edp_phy_ops_v4,
};
static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
.is_edp = true,
.aux_cfg = edp_phy_aux_cfg_v4,
.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
@ -707,6 +731,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
};
static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v6,
};
@ -1108,6 +1133,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_edp_phy_match_table[] = {
{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
{ .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, },

View File

@ -294,7 +294,7 @@ MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table);
static struct platform_driver eusb2_repeater_driver = {
.probe = eusb2_repeater_probe,
.remove_new = eusb2_repeater_remove,
.remove = eusb2_repeater_remove,
.driver = {
.name = "qcom-eusb2-repeater",
.of_match_table = eusb2_repeater_of_match_table,

View File

@ -184,11 +184,11 @@ static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
static struct platform_driver qcom_ipq806x_sata_phy_driver = {
.probe = qcom_ipq806x_sata_phy_probe,
.remove_new = qcom_ipq806x_sata_phy_remove,
.probe = qcom_ipq806x_sata_phy_probe,
.remove = qcom_ipq806x_sata_phy_remove,
.driver = {
.name = "qcom-ipq806x-sata-phy",
.of_match_table = qcom_ipq806x_sata_phy_of_match,
.name = "qcom-ipq806x-sata-phy",
.of_match_table = qcom_ipq806x_sata_phy_of_match,
}
};
module_platform_driver(qcom_ipq806x_sata_phy_driver);

View File

@ -3483,7 +3483,7 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
}
#endif
static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_node *np)
static int qmp_combo_parse_dt_legacy_dp(struct qmp_combo *qmp, struct device_node *np)
{
struct device *dev = qmp->dev;
@ -3510,7 +3510,7 @@ static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_nod
return 0;
}
static int qmp_combo_parse_dt_lecacy_usb(struct qmp_combo *qmp, struct device_node *np)
static int qmp_combo_parse_dt_legacy_usb(struct qmp_combo *qmp, struct device_node *np)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
struct device *dev = qmp->dev;
@ -3576,11 +3576,11 @@ static int qmp_combo_parse_dt_legacy(struct qmp_combo *qmp, struct device_node *
if (IS_ERR(qmp->dp_serdes))
return PTR_ERR(qmp->dp_serdes);
ret = qmp_combo_parse_dt_lecacy_usb(qmp, usb_np);
ret = qmp_combo_parse_dt_legacy_usb(qmp, usb_np);
if (ret)
return ret;
ret = qmp_combo_parse_dt_lecacy_dp(qmp, dp_np);
ret = qmp_combo_parse_dt_legacy_dp(qmp, dp_np);
if (ret)
return ret;

View File

@ -34,6 +34,8 @@
#include "phy-qcom-qmp-pcs-pcie-v5_20.h"
#include "phy-qcom-qmp-pcs-pcie-v6.h"
#include "phy-qcom-qmp-pcs-pcie-v6_20.h"
#include "phy-qcom-qmp-pcs-pcie-v6_30.h"
#include "phy-qcom-qmp-pcs-v6_30.h"
#include "phy-qcom-qmp-pcie-qhp.h"
#define PHY_INIT_COMPLETE_TIMEOUT 10000
@ -1344,6 +1346,154 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x26),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x03),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x12),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x40),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x46),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MISC_1, 0x88),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0x12),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B3, 0x9a),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B4, 0x38),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B5, 0xb6),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B6, 0x64),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE210, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH1_RATE3, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE210, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH2_RATE3, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE210, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH3_RATE3, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_txz_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_RES_CODE_LANE_OFFSET_RX, 0x05),
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_2, 0x10),
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_LANE_MODE_3, 0x51),
QMP_PHY_INIT_CFG(QSERDES_V6_20_TX_TRAN_DRVR_EMP_EN, 0x34),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rxz_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_2, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_GAIN_RATE_2, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_FO_GAIN_RATE_3, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_PI_CONTROLS, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_UCDR_SO_ACC_DEFAULT_VAL_RATE3, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_CAL_CTRL2, 0x80),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_IVCM_POSTCAL_OFFSET, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_BKUP_CTRL1, 0x15),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0xd4),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0x23),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B2, 0x58),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B3, 0x9a),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B4, 0x38),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B5, 0xb6),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B6, 0xee),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B0, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B1, 0xe4),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B2, 0x60),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B3, 0xdf),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x69),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_rx_tbl[] = {
QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x3a, BIT(0)),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2, 0x00),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_G3S2_PRE_GAIN, 0x2e),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_RX_SIGDET_LVL, 0x99),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7, 0x00),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG4, 0x00),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_EQ_CONFIG5, 0x22),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG, 0x04),
QMP_PHY_INIT_CFG(QPHY_V6_30_PCS_TX_RX_CONFIG2, 0x02),
};
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS, 0x00),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_EQ_CONFIG1, 0x16),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5, 0x02),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN, 0x2e),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1, 0x03),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3, 0x28),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5, 0x18),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5, 0x7a),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5, 0x8a),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME, 0x27),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME, 0x27),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG, 0xc0),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2, 0x1d),
};
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@ -2582,6 +2732,8 @@ struct qmp_pcie_offsets {
u16 rx;
u16 tx2;
u16 rx2;
u16 txz;
u16 rxz;
u16 ln_shrd;
};
@ -2592,6 +2744,10 @@ struct qmp_phy_cfg_tbls {
int tx_num;
const struct qmp_phy_init_tbl *rx;
int rx_num;
const struct qmp_phy_init_tbl *txz;
int txz_num;
const struct qmp_phy_init_tbl *rxz;
int rxz_num;
const struct qmp_phy_init_tbl *pcs;
int pcs_num;
const struct qmp_phy_init_tbl *pcs_misc;
@ -2659,6 +2815,8 @@ struct qmp_pcie {
void __iomem *rx;
void __iomem *tx2;
void __iomem *rx2;
void __iomem *txz;
void __iomem *rxz;
void __iomem *ln_shrd;
void __iomem *port_b;
@ -2826,6 +2984,17 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
.ln_shrd = 0x0e00,
};
static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
.serdes = 0x8800,
.pcs = 0x9000,
.pcs_misc = 0x9800,
.tx = 0x0000,
.rx = 0x0200,
.txz = 0xe000,
.rxz = 0xe200,
.ln_shrd = 0x8000,
};
static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.lanes = 1,
@ -3704,6 +3873,38 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
.has_nocsr_reset = true,
};
static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
.lanes = 8,
.offsets = &qmp_pcie_offsets_v6_30,
.tbls = {
.serdes = x1e80100_qmp_gen4x8_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_serdes_tbl),
.rx = x1e80100_qmp_gen4x8_pcie_rx_tbl,
.rx_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rx_tbl),
.txz = x1e80100_qmp_gen4x8_pcie_txz_tbl,
.txz_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_txz_tbl),
.rxz = x1e80100_qmp_gen4x8_pcie_rxz_tbl,
.rxz_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_rxz_tbl),
.pcs = x1e80100_qmp_gen4x8_pcie_pcs_tbl,
.pcs_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_tbl),
.pcs_misc = x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_pcs_misc_tbl),
.ln_shrd = x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl,
.ln_shrd_num = ARRAY_SIZE(x1e80100_qmp_gen4x8_pcie_ln_shrd_tbl),
},
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = sm8550_qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
.regs = pciephy_v6_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS_4_20,
.has_nocsr_reset = true,
};
static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@ -3751,6 +3952,13 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
/*
* Tx/Rx registers that require different settings than
* txz/rxz must be programmed after txz/rxz.
*/
qmp_configure(qmp->dev, qmp->txz, tbls->txz, tbls->txz_num);
qmp_configure(qmp->dev, qmp->rxz, tbls->rxz, tbls->rxz_num);
qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
@ -4293,6 +4501,9 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
return PTR_ERR(qmp->port_b);
}
qmp->txz = base + offs->txz;
qmp->rxz = base + offs->rxz;
if (cfg->tbls.ln_shrd)
qmp->ln_shrd = base + offs->ln_shrd;
@ -4478,6 +4689,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,x1e80100-qmp-gen4x4-pcie-phy",
.data = &x1e80100_qmp_gen4x4_pciephy_cfg,
}, {
.compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy",
.data = &x1e80100_qmp_gen4x8_pciephy_cfg,
},
{ },
};

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
*/
#ifndef QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
#define QCOM_PHY_QMP_PCS_PCIE_V6_30_H_
/* Only for QMP V6_30 PHY - PCIE have different offsets than V6 */
#define QPHY_PCIE_V6_30_PCS_POWER_STATE_CONFIG2 0x014
#define QPHY_PCIE_V6_30_PCS_TX_RX_CONFIG 0x020
#define QPHY_PCIE_V6_30_PCS_ENDPOINT_REFCLK_DRIVE 0x024
#define QPHY_PCIE_V6_30_PCS_OSC_DTCT_ACTIONS 0x098
#define QPHY_PCIE_V6_30_PCS_EQ_CONFIG1 0x0a8
#define QPHY_PCIE_V6_30_PCS_G3_RXEQEVAL_TIME 0x0f8
#define QPHY_PCIE_V6_30_PCS_G4_RXEQEVAL_TIME 0x0fc
#define QPHY_PCIE_V6_30_PCS_G4_EQ_CONFIG5 0x110
#define QPHY_PCIE_V6_30_PCS_G4_PRE_GAIN 0x164
#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG1 0x184
#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG3 0x18c
#define QPHY_PCIE_V6_30_PCS_RX_MARGINING_CONFIG5 0x194
#define QPHY_PCIE_V6_30_PCS_G3_FOM_EQ_CONFIG5 0x1b4
#define QPHY_PCIE_V6_30_PCS_G4_FOM_EQ_CONFIG5 0x1c8
#endif

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Qualcomm Innovation Center. All rights reserved.
*/
#ifndef QCOM_PHY_QMP_PCS_V6_30_H_
#define QCOM_PHY_QMP_PCS_V6_30_H_
/* Only for QMP V6_30 PHY - PCIe PCS registers */
#define QPHY_V6_30_PCS_LOCK_DETECT_CONFIG2 0x0cc
#define QPHY_V6_30_PCS_G3S2_PRE_GAIN 0x17c
#define QPHY_V6_30_PCS_RX_SIGDET_LVL 0x194
#define QPHY_V6_30_PCS_ALIGN_DETECT_CONFIG7 0x1dc
#define QPHY_V6_30_PCS_TX_RX_CONFIG 0x1e0
#define QPHY_V6_30_PCS_TX_RX_CONFIG2 0x1e4
#define QPHY_V6_30_PCS_EQ_CONFIG4 0x1fc
#define QPHY_V6_30_PCS_EQ_CONFIG5 0x200
#endif

View File

@ -871,6 +871,16 @@ static const struct qmp_phy_init_tbl sdx75_usb3_uniphy_pcs_usb_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
};
static const struct qmp_phy_init_tbl qcs8300_usb3_uniphy_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0xf2),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x21),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x10),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
};
static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xa5),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_2, 0x82),
@ -989,6 +999,40 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
};
static const struct qmp_phy_init_tbl qcs8300_usb3_uniphy_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xec),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x3f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x3f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa9),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x7b),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xe4),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0x24),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0x64),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0x99),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x09),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x19),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_ENABLES, 0x00),
};
static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xdc),
QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0xbd),
@ -1462,6 +1506,24 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = {
.regs = qmp_v5_usb3phy_regs_layout,
};
static const struct qmp_phy_cfg qcs8300_usb3_uniphy_cfg = {
.offsets = &qmp_usb_offsets_v5,
.serdes_tbl = sc8280xp_usb3_uniphy_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_serdes_tbl),
.tx_tbl = qcs8300_usb3_uniphy_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(qcs8300_usb3_uniphy_tx_tbl),
.rx_tbl = qcs8300_usb3_uniphy_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(qcs8300_usb3_uniphy_rx_tbl),
.pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl),
.pcs_usb_tbl = sa8775p_usb3_uniphy_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_usb_tbl),
.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 sc8280xp_usb3_uniphy_cfg = {
.offsets = &qmp_usb_offsets_v5,
@ -2247,6 +2309,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, {
.compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg,
}, {
.compatible = "qcom,qcs8300-qmp-usb3-uni-phy",
.data = &qcs8300_usb3_uniphy_cfg,
}, {
.compatible = "qcom,qdu1000-qmp-usb3-uni-phy",
.data = &qdu1000_usb3_uniphy_cfg,

View File

@ -1298,7 +1298,7 @@ MODULE_DEVICE_TABLE(of, usbphy_rtk_dt_match);
static struct platform_driver rtk_usb2phy_driver = {
.probe = rtk_usb2phy_probe,
.remove_new = rtk_usb2phy_remove,
.remove = rtk_usb2phy_remove,
.driver = {
.name = "rtk-usb2phy",
.of_match_table = usbphy_rtk_dt_match,

View File

@ -734,7 +734,7 @@ MODULE_DEVICE_TABLE(of, usbphy_rtk_dt_match);
static struct platform_driver rtk_usb3phy_driver = {
.probe = rtk_usb3phy_probe,
.remove_new = rtk_usb3phy_remove,
.remove = rtk_usb3phy_remove,
.driver = {
.name = "rtk-usb3phy",
.of_match_table = usbphy_rtk_dt_match,

View File

@ -132,11 +132,11 @@ static void rcar_gen3_phy_pcie_remove(struct platform_device *pdev)
static struct platform_driver rcar_gen3_phy_driver = {
.driver = {
.name = "phy_rcar_gen3_pcie",
.of_match_table = rcar_gen3_phy_pcie_match_table,
.name = "phy_rcar_gen3_pcie",
.of_match_table = rcar_gen3_phy_pcie_match_table,
},
.probe = rcar_gen3_phy_pcie_probe,
.remove_new = rcar_gen3_phy_pcie_remove,
.probe = rcar_gen3_phy_pcie_probe,
.remove = rcar_gen3_phy_pcie_remove,
};
module_platform_driver(rcar_gen3_phy_driver);

View File

@ -825,7 +825,7 @@ static struct platform_driver rcar_gen3_phy_usb2_driver = {
.of_match_table = rcar_gen3_phy_usb2_match_table,
},
.probe = rcar_gen3_phy_usb2_probe,
.remove_new = rcar_gen3_phy_usb2_remove,
.remove = rcar_gen3_phy_usb2_remove,
};
module_platform_driver(rcar_gen3_phy_usb2_driver);

View File

@ -206,11 +206,11 @@ static void rcar_gen3_phy_usb3_remove(struct platform_device *pdev)
static struct platform_driver rcar_gen3_phy_usb3_driver = {
.driver = {
.name = "phy_rcar_gen3_usb3",
.of_match_table = rcar_gen3_phy_usb3_match_table,
.name = "phy_rcar_gen3_usb3",
.of_match_table = rcar_gen3_phy_usb3_match_table,
},
.probe = rcar_gen3_phy_usb3_probe,
.remove_new = rcar_gen3_phy_usb3_remove,
.probe = rcar_gen3_phy_usb3_probe,
.remove = rcar_gen3_phy_usb3_remove,
};
module_platform_driver(rcar_gen3_phy_usb3_driver);

View File

@ -404,7 +404,7 @@ static void r8a779f0_eth_serdes_remove(struct platform_device *pdev)
static struct platform_driver r8a779f0_eth_serdes_driver_platform = {
.probe = r8a779f0_eth_serdes_probe,
.remove_new = r8a779f0_eth_serdes_remove,
.remove = r8a779f0_eth_serdes_remove,
.driver = {
.name = "r8a779f0_eth_serdes",
.of_match_table = r8a779f0_eth_serdes_of_table,

View File

@ -472,7 +472,7 @@ static struct platform_driver rockchip_inno_csidphy_driver = {
.of_match_table = rockchip_inno_csidphy_match_id,
},
.probe = rockchip_inno_csidphy_probe,
.remove_new = rockchip_inno_csidphy_remove,
.remove = rockchip_inno_csidphy_remove,
};
module_platform_driver(rockchip_inno_csidphy_driver);

View File

@ -784,7 +784,7 @@ static struct platform_driver inno_dsidphy_driver = {
.of_match_table = of_match_ptr(inno_dsidphy_of_match),
},
.probe = inno_dsidphy_probe,
.remove_new = inno_dsidphy_remove,
.remove = inno_dsidphy_remove,
};
module_platform_driver(inno_dsidphy_driver);

View File

@ -1424,8 +1424,8 @@ static const struct of_device_id inno_hdmi_phy_of_match[] = {
MODULE_DEVICE_TABLE(of, inno_hdmi_phy_of_match);
static struct platform_driver inno_hdmi_phy_driver = {
.probe = inno_hdmi_phy_probe,
.remove_new = inno_hdmi_phy_remove,
.probe = inno_hdmi_phy_probe,
.remove = inno_hdmi_phy_remove,
.driver = {
.name = "inno-hdmi-phy",
.of_match_table = inno_hdmi_phy_of_match,

View File

@ -229,9 +229,10 @@ struct rockchip_usb2phy_port {
* @dev: pointer to device.
* @grf: General Register Files regmap.
* @usbgrf: USB General Register Files regmap.
* @clk: clock struct of phy input clk.
* @clks: array of phy input clocks.
* @clk480m: clock struct of phy output clk.
* @clk480m_hw: clock struct of phy output clk management.
* @num_clks: number of phy input clocks.
* @phy_reset: phy reset control.
* @chg_state: states involved in USB charger detection.
* @chg_type: USB charger types.
@ -246,9 +247,10 @@ struct rockchip_usb2phy {
struct device *dev;
struct regmap *grf;
struct regmap *usbgrf;
struct clk *clk;
struct clk_bulk_data *clks;
struct clk *clk480m;
struct clk_hw clk480m_hw;
int num_clks;
struct reset_control *phy_reset;
enum usb_chg_state chg_state;
enum power_supply_type chg_type;
@ -310,6 +312,13 @@ static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
return 0;
}
static void rockchip_usb2phy_clk_bulk_disable(void *data)
{
struct rockchip_usb2phy *rphy = data;
clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
}
static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
@ -376,7 +385,9 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
{
struct device_node *node = rphy->dev->of_node;
struct clk_init_data init;
struct clk *refclk = NULL;
const char *clk_name;
int i;
int ret = 0;
init.flags = 0;
@ -386,8 +397,15 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
/* optional override of the clockname */
of_property_read_string(node, "clock-output-names", &init.name);
if (rphy->clk) {
clk_name = __clk_get_name(rphy->clk);
for (i = 0; i < rphy->num_clks; i++) {
if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
refclk = rphy->clks[i].clk;
break;
}
}
if (!IS_ERR(refclk)) {
clk_name = __clk_get_name(refclk);
init.parent_names = &clk_name;
init.num_parents = 1;
} else {
@ -418,30 +436,28 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
{
int ret;
struct device_node *node = rphy->dev->of_node;
struct extcon_dev *edev;
int ret;
if (of_property_read_bool(node, "extcon")) {
edev = extcon_get_edev_by_phandle(rphy->dev, 0);
if (IS_ERR(edev)) {
if (PTR_ERR(edev) != -EPROBE_DEFER)
dev_err(rphy->dev, "Invalid or missing extcon\n");
return PTR_ERR(edev);
}
if (IS_ERR(edev))
return dev_err_probe(rphy->dev, PTR_ERR(edev),
"invalid or missing extcon\n");
} else {
/* Initialize extcon device */
edev = devm_extcon_dev_allocate(rphy->dev,
rockchip_usb2phy_extcon_cable);
if (IS_ERR(edev))
return -ENOMEM;
return dev_err_probe(rphy->dev, PTR_ERR(edev),
"failed to allocate extcon device\n");
ret = devm_extcon_dev_register(rphy->dev, edev);
if (ret) {
dev_err(rphy->dev, "failed to register extcon device\n");
return ret;
}
if (ret)
return dev_err_probe(rphy->dev, ret,
"failed to register extcon device\n");
}
rphy->edev = edev;
@ -1327,7 +1343,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
struct rockchip_usb2phy *rphy;
const struct rockchip_usb2phy_cfg *phy_cfgs;
unsigned int reg;
int index, ret;
int index = 0, ret;
rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
if (!rphy)
@ -1339,9 +1355,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
dev_err(dev, "failed to locate usbgrf\n");
return PTR_ERR(rphy->grf);
}
}
else {
} else {
rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(rphy->grf))
return PTR_ERR(rphy->grf);
@ -1358,16 +1372,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
}
if (of_property_read_u32_index(np, "reg", 0, &reg)) {
dev_err(dev, "the reg property is not assigned in %pOFn node\n",
np);
dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
return -EINVAL;
}
/* support address_cells=2 */
if (of_property_count_u32_elems(np, "reg") > 2 && reg == 0) {
if (of_property_read_u32_index(np, "reg", 1, &reg)) {
dev_err(dev, "the reg property is not assigned in %pOFn node\n",
np);
dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
return -EINVAL;
}
}
@ -1386,8 +1398,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
if (ret)
return ret;
/* find out a proper config which can be matched with dt. */
index = 0;
/* find a proper config that can be matched with the DT */
do {
if (phy_cfgs[index].reg == reg) {
rphy->phy_cfg = &phy_cfgs[index];
@ -1406,17 +1417,25 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
if (IS_ERR(rphy->phy_reset))
return PTR_ERR(rphy->phy_reset);
rphy->clk = devm_clk_get_optional_enabled(dev, "phyclk");
if (IS_ERR(rphy->clk)) {
return dev_err_probe(&pdev->dev, PTR_ERR(rphy->clk),
"failed to get phyclk\n");
}
ret = devm_clk_bulk_get_all(dev, &rphy->clks);
if (ret == -EPROBE_DEFER)
return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
"failed to get phy clock\n");
/* Clocks are optional */
rphy->num_clks = ret < 0 ? 0 : ret;
ret = rockchip_usb2phy_clk480m_register(rphy);
if (ret) {
dev_err(dev, "failed to register 480m output clock\n");
if (ret)
return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
if (ret)
return dev_err_probe(dev, ret, "failed to enable phy clock\n");
ret = devm_add_action_or_reset(dev, rockchip_usb2phy_clk_bulk_disable, rphy);
if (ret)
return ret;
}
if (rphy->phy_cfg->phy_tuning) {
ret = rphy->phy_cfg->phy_tuning(rphy);
@ -1436,8 +1455,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
if (IS_ERR(phy)) {
dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
ret = PTR_ERR(phy);
ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
goto put_child;
}
@ -1446,13 +1464,11 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
/* initialize otg/host port separately */
if (of_node_name_eq(child_np, "host-port")) {
ret = rockchip_usb2phy_host_port_init(rphy, rport,
child_np);
ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np);
if (ret)
goto put_child;
} else {
ret = rockchip_usb2phy_otg_port_init(rphy, rport,
child_np);
ret = rockchip_usb2phy_otg_port_init(rphy, rport, child_np);
if (ret)
goto put_child;
}
@ -1474,8 +1490,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
"rockchip_usb2phy",
rphy);
if (ret) {
dev_err(rphy->dev,
"failed to request usb2phy irq handle\n");
dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
goto put_child;
}
}
@ -1495,6 +1510,30 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
BIT(2) << BIT_WRITEABLE_SHIFT | 0);
}
static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
{
int ret;
u32 reg = rphy->phy_cfg->reg;
/* Deassert SIDDQ to power on analog block */
ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
if (ret)
return ret;
/* Do reset after exit IDDQ mode */
ret = rockchip_usb2phy_reset(rphy);
if (ret)
return ret;
/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
return ret;
}
static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
{
int ret;
@ -1923,6 +1962,84 @@ static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
{ /* sentinel */ }
};
static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
{
.reg = 0x0,
.num_ports = 1,
.phy_tuning = rk3576_usb2phy_tuning,
.clkout_ctl = { 0x0008, 0, 0, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x0000, 8, 0, 0, 0x1d1 },
.bvalid_det_en = { 0x00c0, 1, 1, 0, 1 },
.bvalid_det_st = { 0x00c4, 1, 1, 0, 1 },
.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
.ls_det_en = { 0x00c0, 0, 0, 0, 1 },
.ls_det_st = { 0x00c4, 0, 0, 0, 1 },
.ls_det_clr = { 0x00c8, 0, 0, 0, 1 },
.disfall_en = { 0x00c0, 6, 6, 0, 1 },
.disfall_st = { 0x00c4, 6, 6, 0, 1 },
.disfall_clr = { 0x00c8, 6, 6, 0, 1 },
.disrise_en = { 0x00c0, 5, 5, 0, 1 },
.disrise_st = { 0x00c4, 5, 5, 0, 1 },
.disrise_clr = { 0x00c8, 5, 5, 0, 1 },
.utmi_avalid = { 0x0080, 1, 1, 0, 1 },
.utmi_bvalid = { 0x0080, 0, 0, 0, 1 },
.utmi_ls = { 0x0080, 5, 4, 0, 1 },
}
},
.chg_det = {
.cp_det = { 0x0080, 8, 8, 0, 1 },
.dcp_det = { 0x0080, 8, 8, 0, 1 },
.dp_det = { 0x0080, 9, 9, 1, 0 },
.idm_sink_en = { 0x0010, 5, 5, 1, 0 },
.idp_sink_en = { 0x0010, 5, 5, 0, 1 },
.idp_src_en = { 0x0010, 14, 14, 0, 1 },
.rdm_pdwn_en = { 0x0010, 14, 14, 0, 1 },
.vdm_src_en = { 0x0010, 7, 6, 0, 3 },
.vdp_src_en = { 0x0010, 7, 6, 0, 3 },
},
},
{
.reg = 0x2000,
.num_ports = 1,
.phy_tuning = rk3576_usb2phy_tuning,
.clkout_ctl = { 0x2008, 0, 0, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x2000, 8, 0, 0, 0x1d1 },
.bvalid_det_en = { 0x20c0, 1, 1, 0, 1 },
.bvalid_det_st = { 0x20c4, 1, 1, 0, 1 },
.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
.ls_det_en = { 0x20c0, 0, 0, 0, 1 },
.ls_det_st = { 0x20c4, 0, 0, 0, 1 },
.ls_det_clr = { 0x20c8, 0, 0, 0, 1 },
.disfall_en = { 0x20c0, 6, 6, 0, 1 },
.disfall_st = { 0x20c4, 6, 6, 0, 1 },
.disfall_clr = { 0x20c8, 6, 6, 0, 1 },
.disrise_en = { 0x20c0, 5, 5, 0, 1 },
.disrise_st = { 0x20c4, 5, 5, 0, 1 },
.disrise_clr = { 0x20c8, 5, 5, 0, 1 },
.utmi_avalid = { 0x2080, 1, 1, 0, 1 },
.utmi_bvalid = { 0x2080, 0, 0, 0, 1 },
.utmi_ls = { 0x2080, 5, 4, 0, 1 },
}
},
.chg_det = {
.cp_det = { 0x2080, 8, 8, 0, 1 },
.dcp_det = { 0x2080, 8, 8, 0, 1 },
.dp_det = { 0x2080, 9, 9, 1, 0 },
.idm_sink_en = { 0x2010, 5, 5, 1, 0 },
.idp_sink_en = { 0x2010, 5, 5, 0, 1 },
.idp_src_en = { 0x2010, 14, 14, 0, 1 },
.rdm_pdwn_en = { 0x2010, 14, 14, 0, 1 },
.vdm_src_en = { 0x2010, 7, 6, 0, 3 },
.vdp_src_en = { 0x2010, 7, 6, 0, 3 },
},
},
{ /* sentinel */ }
};
static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
{
.reg = 0x0000,
@ -2094,6 +2211,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
{}

View File

@ -256,13 +256,10 @@ struct ropll_config {
};
enum rk_hdptx_reset {
RST_PHY = 0,
RST_APB,
RST_APB = 0,
RST_INIT,
RST_CMN,
RST_LANE,
RST_ROPLL,
RST_LCPLL,
RST_MAX
};
@ -665,11 +662,6 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
{
u32 val;
/* reset phy and apb, or phy locked flag may keep 1 */
reset_control_assert(hdptx->rsts[RST_PHY].rstc);
usleep_range(20, 30);
reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
reset_control_assert(hdptx->rsts[RST_APB].rstc);
usleep_range(20, 30);
reset_control_deassert(hdptx->rsts[RST_APB].rstc);
@ -792,10 +784,6 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
rk_hdptx_pre_power_up(hdptx);
reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
usleep_range(20, 30);
reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
@ -1098,13 +1086,10 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
"Failed to init regmap\n");
hdptx->rsts[RST_PHY].id = "phy";
hdptx->rsts[RST_APB].id = "apb";
hdptx->rsts[RST_INIT].id = "init";
hdptx->rsts[RST_CMN].id = "cmn";
hdptx->rsts[RST_LANE].id = "lane";
hdptx->rsts[RST_ROPLL].id = "ropll";
hdptx->rsts[RST_LCPLL].id = "lcpll";
ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
if (ret)

View File

@ -1210,7 +1210,7 @@ MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids);
static struct platform_driver rockchip_typec_phy_driver = {
.probe = rockchip_typec_phy_probe,
.remove_new = rockchip_typec_phy_remove,
.remove = rockchip_typec_phy_remove,
.driver = {
.name = "rockchip-typec-phy",
.of_match_table = rockchip_typec_phy_dt_ids,

View File

@ -1538,6 +1538,43 @@ static const char * const rk_udphy_rst_list[] = {
"init", "cmn", "lane", "pcs_apb", "pma_apb"
};
static const struct rk_udphy_cfg rk3576_udphy_cfgs = {
.num_phys = 1,
.phy_ids = { 0x2b010000 },
.num_rsts = ARRAY_SIZE(rk_udphy_rst_list),
.rst_list = rk_udphy_rst_list,
.grfcfg = {
/* u2phy-grf */
.bvalid_phy_con = RK_UDPHY_GEN_GRF_REG(0x0010, 1, 0, 0x2, 0x3),
.bvalid_grf_con = RK_UDPHY_GEN_GRF_REG(0x0000, 15, 14, 0x1, 0x3),
/* usb-grf */
.usb3otg0_cfg = RK_UDPHY_GEN_GRF_REG(0x0030, 15, 0, 0x1100, 0x0188),
/* usbdpphy-grf */
.low_pwrn = RK_UDPHY_GEN_GRF_REG(0x0004, 13, 13, 0, 1),
.rx_lfps = RK_UDPHY_GEN_GRF_REG(0x0004, 14, 14, 0, 1),
},
.vogrfcfg = {
{
.hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0000, 11, 10, 1, 3),
.dp_lane_reg = 0x0000,
},
},
.dp_tx_ctrl_cfg = {
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_hbr2,
rk3588_dp_tx_drv_ctrl_hbr3,
},
.dp_tx_ctrl_cfg_typec = {
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_hbr2,
rk3588_dp_tx_drv_ctrl_hbr3,
},
};
static const struct rk_udphy_cfg rk3588_udphy_cfgs = {
.num_phys = 2,
.phy_ids = {
@ -1584,6 +1621,10 @@ static const struct rk_udphy_cfg rk3588_udphy_cfgs = {
};
static const struct of_device_id rk_udphy_dt_match[] = {
{
.compatible = "rockchip,rk3576-usbdp-phy",
.data = &rk3576_udphy_cfgs
},
{
.compatible = "rockchip,rk3588-usbdp-phy",
.data = &rk3588_udphy_cfgs

View File

@ -33,6 +33,17 @@ config PHY_STIH407_USB
Enable this support to enable the picoPHY device used by USB2
and USB3 controllers on STMicroelectronics STiH407 SoC families.
config PHY_STM32_COMBOPHY
tristate "STMicroelectronics COMBOPHY driver for STM32MP25"
depends on ARCH_STM32 || COMPILE_TEST
select GENERIC_PHY
help
Enable this to support the COMBOPHY device used by USB3 or PCIe
controllers on STMicroelectronics STM32MP25 SoC.
This driver controls the COMBOPHY block to generate the PCIe 100Mhz
reference clock from either the external clock generator or HSE
internal SoC clock source.
config PHY_STM32_USBPHYC
tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
depends on ARCH_STM32 || COMPILE_TEST

View File

@ -3,4 +3,5 @@ obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
obj-$(CONFIG_PHY_STM32_COMBOPHY) += phy-stm32-combophy.o
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o

View File

@ -0,0 +1,598 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* STMicroelectronics COMBOPHY STM32MP25 Controller driver.
*
* Copyright (C) 2024 STMicroelectronics
* Author: Christian Bruel <christian.bruel@foss.st.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <dt-bindings/phy/phy.h>
#define SYSCFG_COMBOPHY_CR1 0x4c00
#define SYSCFG_COMBOPHY_CR2 0x4c04
#define SYSCFG_COMBOPHY_CR4 0x4c0c
#define SYSCFG_COMBOPHY_CR5 0x4c10
#define SYSCFG_COMBOPHY_SR 0x4c14
#define SYSCFG_PCIEPRGCR 0x6080
/* SYSCFG PCIEPRGCR */
#define STM32MP25_PCIEPRGCR_EN BIT(0)
#define STM32MP25_PCIEPRG_IMPCTRL_OHM GENMASK(3, 1)
#define STM32MP25_PCIEPRG_IMPCTRL_VSWING GENMASK(5, 4)
/* SYSCFG SYSCFG_COMBOPHY_SR */
#define STM32MP25_PIPE0_PHYSTATUS BIT(1)
/* SYSCFG CR1 */
#define SYSCFG_COMBOPHY_CR1_REFUSEPAD BIT(0)
#define SYSCFG_COMBOPHY_CR1_MPLLMULT GENMASK(7, 1)
#define SYSCFG_COMBOPHY_CR1_REFCLKSEL GENMASK(16, 8)
#define SYSCFG_COMBOPHY_CR1_REFCLKDIV2 BIT(17)
#define SYSCFG_COMBOPHY_CR1_REFSSPEN BIT(18)
#define SYSCFG_COMBOPHY_CR1_SSCEN BIT(19)
/* SYSCFG CR4 */
#define SYSCFG_COMBOPHY_CR4_RX0_EQ GENMASK(2, 0)
#define MPLLMULT_19_2 (0x02u << 1)
#define MPLLMULT_20 (0x7du << 1)
#define MPLLMULT_24 (0x68u << 1)
#define MPLLMULT_25 (0x64u << 1)
#define MPLLMULT_26 (0x60u << 1)
#define MPLLMULT_38_4 (0x41u << 1)
#define MPLLMULT_48 (0x6cu << 1)
#define MPLLMULT_50 (0x32u << 1)
#define MPLLMULT_52 (0x30u << 1)
#define MPLLMULT_100 (0x19u << 1)
#define REFCLKSEL_0 0
#define REFCLKSEL_1 (0x108u << 8)
#define REFCLDIV_0 0
/* SYSCFG CR2 */
#define SYSCFG_COMBOPHY_CR2_MODESEL GENMASK(1, 0)
#define SYSCFG_COMBOPHY_CR2_ISO_DIS BIT(15)
#define COMBOPHY_MODESEL_PCIE 0
#define COMBOPHY_MODESEL_USB 3
/* SYSCFG CR5 */
#define SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS BIT(12)
#define COMBOPHY_SUP_ANA_MPLL_LOOP_CTL 0xc0
#define COMBOPHY_PROP_CNTRL GENMASK(7, 4)
/* Required apb/ker clocks first, optional pad last. */
static const char * const combophy_clks[] = {"apb", "ker", "pad"};
#define APB_CLK 0
#define KER_CLK 1
#define PAD_CLK 2
struct stm32_combophy {
struct phy *phy;
struct regmap *regmap;
struct device *dev;
void __iomem *base;
struct reset_control *phy_reset;
struct clk_bulk_data clks[ARRAY_SIZE(combophy_clks)];
int num_clks;
bool have_pad_clk;
unsigned int type;
bool is_init;
int irq_wakeup;
};
struct clk_impedance {
u32 microohm;
u32 vswing[4];
};
/*
* lookup table to hold the settings needed for a ref clock frequency
* impedance, the offset is used to set the IMP_CTL and DE_EMP bit of the
* PRG_IMP_CTRL register. Use ordered discrete values in the table
*/
static const struct clk_impedance imp_lookup[] = {
{ 6090000, { 442000, 564000, 684000, 802000 } },
{ 5662000, { 528000, 621000, 712000, 803000 } },
{ 5292000, { 491000, 596000, 700000, 802000 } },
{ 4968000, { 558000, 640000, 722000, 803000 } },
{ 4684000, { 468000, 581000, 692000, 802000 } },
{ 4429000, { 554000, 613000, 717000, 803000 } },
{ 4204000, { 511000, 609000, 706000, 802000 } },
{ 3999000, { 571000, 648000, 726000, 803000 } }
};
static int stm32_impedance_tune(struct stm32_combophy *combophy)
{
u8 imp_size = ARRAY_SIZE(imp_lookup);
u8 vswing_size = ARRAY_SIZE(imp_lookup[0].vswing);
u8 imp_of, vswing_of;
u32 max_imp = imp_lookup[0].microohm;
u32 min_imp = imp_lookup[imp_size - 1].microohm;
u32 max_vswing = imp_lookup[imp_size - 1].vswing[vswing_size - 1];
u32 min_vswing = imp_lookup[0].vswing[0];
u32 val;
if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) {
if (val < min_imp || val > max_imp) {
dev_err(combophy->dev, "Invalid value %u for output ohm\n", val);
return -EINVAL;
}
for (imp_of = 0; imp_of < ARRAY_SIZE(imp_lookup); imp_of++)
if (imp_lookup[imp_of].microohm <= val)
break;
dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n",
imp_lookup[imp_of].microohm);
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
STM32MP25_PCIEPRG_IMPCTRL_OHM,
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_OHM, imp_of));
} else {
regmap_read(combophy->regmap, SYSCFG_PCIEPRGCR, &val);
imp_of = FIELD_GET(STM32MP25_PCIEPRG_IMPCTRL_OHM, val);
}
if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) {
if (val < min_vswing || val > max_vswing) {
dev_err(combophy->dev, "Invalid value %u for output vswing\n", val);
return -EINVAL;
}
for (vswing_of = 0; vswing_of < ARRAY_SIZE(imp_lookup[imp_of].vswing); vswing_of++)
if (imp_lookup[imp_of].vswing[vswing_of] >= val)
break;
dev_dbg(combophy->dev, "Set %u microvolt swing\n",
imp_lookup[imp_of].vswing[vswing_of]);
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
STM32MP25_PCIEPRG_IMPCTRL_VSWING,
FIELD_PREP(STM32MP25_PCIEPRG_IMPCTRL_VSWING, vswing_of));
}
return 0;
}
static int stm32_combophy_pll_init(struct stm32_combophy *combophy)
{
int ret;
u32 refclksel, pllmult, propcntrl, val;
u32 clk_rate;
struct clk *clk;
u32 cr1_val = 0, cr1_mask = 0;
if (combophy->have_pad_clk)
clk = combophy->clks[PAD_CLK].clk;
else
clk = combophy->clks[KER_CLK].clk;
clk_rate = clk_get_rate(clk);
dev_dbg(combophy->dev, "%s pll init rate %d\n",
combophy->have_pad_clk ? "External" : "Ker", clk_rate);
if (combophy->type != PHY_TYPE_PCIE) {
cr1_mask |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
cr1_val |= SYSCFG_COMBOPHY_CR1_REFSSPEN;
}
if (of_property_present(combophy->dev->of_node, "st,ssc-on")) {
dev_dbg(combophy->dev, "Enabling clock with SSC\n");
cr1_mask |= SYSCFG_COMBOPHY_CR1_SSCEN;
cr1_val |= SYSCFG_COMBOPHY_CR1_SSCEN;
}
switch (clk_rate) {
case 100000000:
pllmult = MPLLMULT_100;
refclksel = REFCLKSEL_0;
propcntrl = 0x8u << 4;
break;
case 19200000:
pllmult = MPLLMULT_19_2;
refclksel = REFCLKSEL_1;
propcntrl = 0x8u << 4;
break;
case 25000000:
pllmult = MPLLMULT_25;
refclksel = REFCLKSEL_0;
propcntrl = 0xeu << 4;
break;
case 24000000:
pllmult = MPLLMULT_24;
refclksel = REFCLKSEL_1;
propcntrl = 0xeu << 4;
break;
case 20000000:
pllmult = MPLLMULT_20;
refclksel = REFCLKSEL_0;
propcntrl = 0xeu << 4;
break;
default:
dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate);
return -EINVAL;
}
cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKDIV2;
cr1_val |= REFCLDIV_0;
cr1_mask |= SYSCFG_COMBOPHY_CR1_REFCLKSEL;
cr1_val |= refclksel;
cr1_mask |= SYSCFG_COMBOPHY_CR1_MPLLMULT;
cr1_val |= pllmult;
/*
* vddcombophy is interconnected with vddcore. Isolation bit should be unset
* before using the ComboPHY.
*/
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
SYSCFG_COMBOPHY_CR2_ISO_DIS, SYSCFG_COMBOPHY_CR2_ISO_DIS);
reset_control_assert(combophy->phy_reset);
if (combophy->type == PHY_TYPE_PCIE) {
ret = stm32_impedance_tune(combophy);
if (ret)
goto out_iso;
cr1_mask |= SYSCFG_COMBOPHY_CR1_REFUSEPAD;
cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0;
}
if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) {
dev_dbg(combophy->dev, "Set RX equalizer %u\n", val);
if (val > SYSCFG_COMBOPHY_CR4_RX0_EQ) {
dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val);
ret = -EINVAL;
goto out_iso;
}
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4,
SYSCFG_COMBOPHY_CR4_RX0_EQ, val);
}
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val);
/*
* Force elasticity buffer to be tuned for the reference clock as
* the separated clock model is not supported
*/
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5,
SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS, SYSCFG_COMBOPHY_CR5_COMMON_CLOCKS);
reset_control_deassert(combophy->phy_reset);
ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val,
!(val & STM32MP25_PIPE0_PHYSTATUS),
10, 1000);
if (ret) {
dev_err(combophy->dev, "timeout, cannot lock PLL\n");
if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
STM32MP25_PCIEPRGCR_EN, 0);
if (combophy->type != PHY_TYPE_PCIE)
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
goto out;
}
if (combophy->type == PHY_TYPE_PCIE) {
if (!combophy->have_pad_clk)
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
STM32MP25_PCIEPRGCR_EN, STM32MP25_PCIEPRGCR_EN);
val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
val &= ~COMBOPHY_PROP_CNTRL;
val |= propcntrl;
writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL);
}
return 0;
out_iso:
reset_control_deassert(combophy->phy_reset);
out:
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
return ret;
}
static struct phy *stm32_combophy_xlate(struct device *dev,
const struct of_phandle_args *args)
{
struct stm32_combophy *combophy = dev_get_drvdata(dev);
unsigned int type;
if (args->args_count != 1) {
dev_err(dev, "invalid number of cells in 'phy' property\n");
return ERR_PTR(-EINVAL);
}
type = args->args[0];
if (type != PHY_TYPE_USB3 && type != PHY_TYPE_PCIE) {
dev_err(dev, "unsupported device type: %d\n", type);
return ERR_PTR(-EINVAL);
}
if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) {
dev_err(dev, "Invalid use of clk_pad for USB3 mode\n");
return ERR_PTR(-EINVAL);
}
combophy->type = type;
return combophy->phy;
}
static int stm32_combophy_set_mode(struct stm32_combophy *combophy)
{
int type = combophy->type;
u32 val;
switch (type) {
case PHY_TYPE_PCIE:
dev_dbg(combophy->dev, "setting PCIe ComboPHY\n");
val = COMBOPHY_MODESEL_PCIE;
break;
case PHY_TYPE_USB3:
dev_dbg(combophy->dev, "setting USB3 ComboPHY\n");
val = COMBOPHY_MODESEL_USB;
break;
default:
dev_err(combophy->dev, "Invalid PHY mode %d\n", type);
return -EINVAL;
}
return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
SYSCFG_COMBOPHY_CR2_MODESEL, val);
}
static int stm32_combophy_suspend_noirq(struct device *dev)
{
struct stm32_combophy *combophy = dev_get_drvdata(dev);
/*
* Clocks should be turned off since it is not needed for
* wakeup capability. In case usb-remote wakeup is not enabled,
* combo-phy is already turned off by HCD driver using exit callback
*/
if (combophy->is_init) {
clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
/* since wakeup is enabled for ctrl */
enable_irq_wake(combophy->irq_wakeup);
}
return 0;
}
static int stm32_combophy_resume_noirq(struct device *dev)
{
struct stm32_combophy *combophy = dev_get_drvdata(dev);
int ret;
/*
* If clocks was turned off by suspend call for wakeup then needs
* to be turned back ON in resume. In case usb-remote wakeup is not
* enabled, clocks already turned ON by HCD driver using init callback
*/
if (combophy->is_init) {
/* since wakeup was enabled for ctrl */
disable_irq_wake(combophy->irq_wakeup);
ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
if (ret) {
dev_err(dev, "can't enable clocks (%d)\n", ret);
return ret;
}
}
return 0;
}
static int stm32_combophy_exit(struct phy *phy)
{
struct stm32_combophy *combophy = phy_get_drvdata(phy);
struct device *dev = combophy->dev;
combophy->is_init = false;
if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk)
regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR,
STM32MP25_PCIEPRGCR_EN, 0);
if (combophy->type != PHY_TYPE_PCIE)
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1,
SYSCFG_COMBOPHY_CR1_REFSSPEN, 0);
regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2,
SYSCFG_COMBOPHY_CR2_ISO_DIS, 0);
clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
pm_runtime_put_noidle(dev);
return 0;
}
static int stm32_combophy_init(struct phy *phy)
{
struct stm32_combophy *combophy = phy_get_drvdata(phy);
struct device *dev = combophy->dev;
int ret;
pm_runtime_get_noresume(dev);
ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks);
if (ret) {
dev_err(dev, "can't enable clocks (%d)\n", ret);
pm_runtime_put_noidle(dev);
return ret;
}
ret = stm32_combophy_set_mode(combophy);
if (ret) {
dev_err(dev, "combophy mode not set\n");
clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
pm_runtime_put_noidle(dev);
return ret;
}
ret = stm32_combophy_pll_init(combophy);
if (ret) {
clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks);
pm_runtime_put_noidle(dev);
return ret;
}
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
combophy->is_init = true;
return ret;
}
static const struct phy_ops stm32_combophy_phy_data = {
.init = stm32_combophy_init,
.exit = stm32_combophy_exit,
.owner = THIS_MODULE
};
static irqreturn_t stm32_combophy_irq_wakeup_handler(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
static int stm32_combophy_get_clocks(struct stm32_combophy *combophy)
{
int i, ret;
for (i = 0; i < ARRAY_SIZE(combophy_clks); i++)
combophy->clks[i].id = combophy_clks[i];
combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1;
ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks);
if (ret)
return ret;
ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks);
if (ret)
return ret;
if (combophy->clks[combophy->num_clks].clk != NULL) {
combophy->have_pad_clk = true;
combophy->num_clks++;
}
return 0;
}
static int stm32_combophy_probe(struct platform_device *pdev)
{
struct stm32_combophy *combophy;
struct device *dev = &pdev->dev;
struct phy_provider *phy_provider;
int ret, irq;
combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL);
if (!combophy)
return -ENOMEM;
combophy->dev = dev;
dev_set_drvdata(dev, combophy);
combophy->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(combophy->base))
return PTR_ERR(combophy->base);
ret = stm32_combophy_get_clocks(combophy);
if (ret)
return ret;
combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
if (IS_ERR(combophy->phy_reset))
return dev_err_probe(dev, PTR_ERR(combophy->phy_reset),
"Failed to get PHY reset\n");
combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
if (IS_ERR(combophy->regmap))
return dev_err_probe(dev, PTR_ERR(combophy->regmap),
"No syscfg specified\n");
combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data);
if (IS_ERR(combophy->phy))
return dev_err_probe(dev, PTR_ERR(combophy->phy),
"failed to create PCIe/USB3 ComboPHY\n");
if (device_property_read_bool(dev, "wakeup-source")) {
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return dev_err_probe(dev, irq, "failed to get IRQ\n");
combophy->irq_wakeup = irq;
ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL,
stm32_combophy_irq_wakeup_handler, IRQF_ONESHOT,
NULL, NULL);
if (ret)
return dev_err_probe(dev, ret, "unable to request wake IRQ %d\n",
combophy->irq_wakeup);
}
ret = devm_pm_runtime_enable(dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");
phy_set_drvdata(combophy->phy, combophy);
phy_provider = devm_of_phy_provider_register(dev, stm32_combophy_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct dev_pm_ops stm32_combophy_pm_ops = {
NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_combophy_suspend_noirq,
stm32_combophy_resume_noirq)
};
static const struct of_device_id stm32_combophy_of_match[] = {
{ .compatible = "st,stm32mp25-combophy", },
{ },
};
MODULE_DEVICE_TABLE(of, stm32_combophy_of_match);
static struct platform_driver stm32_combophy_driver = {
.probe = stm32_combophy_probe,
.driver = {
.name = "stm32-combophy",
.of_match_table = stm32_combophy_of_match,
.pm = pm_sleep_ptr(&stm32_combophy_pm_ops)
}
};
module_platform_driver(stm32_combophy_driver);
MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>");
MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");
MODULE_LICENSE("GPL");

View File

@ -812,7 +812,7 @@ MODULE_DEVICE_TABLE(of, stm32_usbphyc_of_match);
static struct platform_driver stm32_usbphyc_driver = {
.probe = stm32_usbphyc_probe,
.remove_new = stm32_usbphyc_remove,
.remove = stm32_usbphyc_remove,
.driver = {
.of_match_table = stm32_usbphyc_of_match,
.name = "stm32-usbphyc",

View File

@ -1327,7 +1327,7 @@ static struct platform_driver tegra_xusb_padctl_driver = {
.pm = &tegra_xusb_padctl_pm_ops,
},
.probe = tegra_xusb_padctl_probe,
.remove_new = tegra_xusb_padctl_remove,
.remove = tegra_xusb_padctl_remove,
};
module_platform_driver(tegra_xusb_padctl_driver);

View File

@ -837,7 +837,7 @@ static void serdes_am654_remove(struct platform_device *pdev)
static struct platform_driver serdes_am654_driver = {
.probe = serdes_am654_probe,
.remove_new = serdes_am654_remove,
.remove = serdes_am654_remove,
.driver = {
.name = "phy-am654",
.of_match_table = serdes_am654_id_table,

View File

@ -277,11 +277,11 @@ MODULE_DEVICE_TABLE(of, da8xx_usb_phy_ids);
static struct platform_driver da8xx_usb_phy_driver = {
.probe = da8xx_usb_phy_probe,
.remove_new = da8xx_usb_phy_remove,
.remove = da8xx_usb_phy_remove,
.driver = {
.name = "da8xx-usb-phy",
.pm = &da8xx_usb_phy_pm_ops,
.of_match_table = da8xx_usb_phy_ids,
.of_match_table = da8xx_usb_phy_ids,
},
};

View File

@ -259,7 +259,7 @@ static void dm816x_usb_phy_remove(struct platform_device *pdev)
static struct platform_driver dm816x_usb_phy_driver = {
.probe = dm816x_usb_phy_probe,
.remove_new = dm816x_usb_phy_remove,
.remove = dm816x_usb_phy_remove,
.driver = {
.name = "dm816x-usb-phy",
.pm = &dm816x_usb_phy_pm_ops,

View File

@ -230,7 +230,8 @@ static const
struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
.use_of_data = true,
.regfields = phy_gmii_sel_fields_am654,
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
BIT(PHY_INTERFACE_MODE_USXGMII),
.num_ports = 4,
.num_qsgmii_main_ports = 1,
};

View File

@ -1685,7 +1685,7 @@ static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq);
static struct platform_driver wiz_driver = {
.probe = wiz_probe,
.remove_new = wiz_remove,
.remove = wiz_remove,
.driver = {
.name = "wiz",
.of_match_table = wiz_id_table,

View File

@ -511,7 +511,7 @@ static void omap_usb2_remove(struct platform_device *pdev)
static struct platform_driver omap_usb2_driver = {
.probe = omap_usb2_probe,
.remove_new = omap_usb2_remove,
.remove = omap_usb2_remove,
.driver = {
.name = "omap-usb2",
.of_match_table = omap_usb2_id_table,

View File

@ -920,7 +920,7 @@ MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
static struct platform_driver ti_pipe3_driver = {
.probe = ti_pipe3_probe,
.remove_new = ti_pipe3_remove,
.remove = ti_pipe3_remove,
.driver = {
.name = "ti-pipe3",
.of_match_table = ti_pipe3_id_table,

View File

@ -834,7 +834,7 @@ MODULE_DEVICE_TABLE(of, twl4030_usb_id_table);
static struct platform_driver twl4030_usb_driver = {
.probe = twl4030_usb_probe,
.remove_new = twl4030_usb_remove,
.remove = twl4030_usb_remove,
.driver = {
.name = "twl4030_usb",
.pm = &twl4030_usb_pm_ops,

View File

@ -1071,7 +1071,7 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match);
static struct platform_driver xpsgtr_driver = {
.probe = xpsgtr_probe,
.remove_new = xpsgtr_remove,
.remove = xpsgtr_remove,
.driver = {
.name = "xilinx-psgtr",
.of_match_table = xpsgtr_of_match,

View File

@ -11,7 +11,7 @@
/**
* sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
* @phy: reference to a sun4i usb phy
* @enabled: wether to enable or disable squelch detect
* @enabled: whether to enable or disable squelch detect
*/
void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled);