mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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:
		
						commit
						0ce9a5ffca
					
				
					 81 changed files with 3056 additions and 1069 deletions
				
			
		| 
						 | 
				
			
			@ -18,16 +18,8 @@ properties:
 | 
			
		|||
    const: brcm,ns-usb2-phy
 | 
			
		||||
 | 
			
		||||
  reg:
 | 
			
		||||
    anyOf:
 | 
			
		||||
      - maxItems: 1
 | 
			
		||||
    maxItems: 1
 | 
			
		||||
    description: PHY control register
 | 
			
		||||
      - maxItems: 1
 | 
			
		||||
        description: iomem address range of DMU (Device Management Unit)
 | 
			
		||||
        deprecated: true
 | 
			
		||||
 | 
			
		||||
  reg-names:
 | 
			
		||||
    items:
 | 
			
		||||
      - const: dmu
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
additionalProperties: false
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ properties:
 | 
			
		|||
          - enum:
 | 
			
		||||
              - fsl,imx8dxl-usbphy
 | 
			
		||||
              - fsl,imx8qm-usbphy
 | 
			
		||||
              - fsl,imx8qxp-usbphy
 | 
			
		||||
              - fsl,imx8ulp-usbphy
 | 
			
		||||
          - const: fsl,imx7ulp-usbphy
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]+$":
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										55
									
								
								Documentation/devicetree/bindings/phy/nxp,ptn3222.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Documentation/devicetree/bindings/phy/nxp,ptn3222.yaml
									
									
									
									
									
										Normal 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>;
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
...
 | 
			
		||||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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";
 | 
			
		||||
		...
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ maintainers:
 | 
			
		|||
properties:
 | 
			
		||||
  compatible:
 | 
			
		||||
    enum:
 | 
			
		||||
      - rockchip,rk3576-usbdp-phy
 | 
			
		||||
      - rockchip,rk3588-usbdp-phy
 | 
			
		||||
 | 
			
		||||
  reg:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ description:
 | 
			
		|||
properties:
 | 
			
		||||
  compatible:
 | 
			
		||||
    enum:
 | 
			
		||||
      - qcom,sa8775p-edp-phy
 | 
			
		||||
      - qcom,sc7280-edp-phy
 | 
			
		||||
      - qcom,sc8180x-edp-phy
 | 
			
		||||
      - qcom,sc8280xp-dp-phy
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,16 @@ description:
 | 
			
		|||
 | 
			
		||||
properties:
 | 
			
		||||
  compatible:
 | 
			
		||||
    enum:
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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";
 | 
			
		||||
    };
 | 
			
		||||
							
								
								
									
										119
									
								
								Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								Documentation/devicetree/bindings/phy/st,stm32mp25-combophy.yaml
									
									
									
									
									
										Normal 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>;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -14,10 +14,15 @@ properties:
 | 
			
		|||
    pattern: "^can-phy"
 | 
			
		||||
 | 
			
		||||
  compatible:
 | 
			
		||||
    enum:
 | 
			
		||||
      - nxp,tjr1443
 | 
			
		||||
    oneOf:
 | 
			
		||||
      - items:
 | 
			
		||||
          - enum:
 | 
			
		||||
              - microchip,ata6561
 | 
			
		||||
          - const: ti,tcan1042
 | 
			
		||||
      - enum:
 | 
			
		||||
          - ti,tcan1042
 | 
			
		||||
          - ti,tcan1043
 | 
			
		||||
          - nxp,tjr1443
 | 
			
		||||
 | 
			
		||||
  '#phy-cells':
 | 
			
		||||
    const: 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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/	\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1050,9 +1050,9 @@ 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,
 | 
			
		||||
	.remove = sun4i_usb_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.of_match_table	= sun4i_usb_phy_of_match,
 | 
			
		||||
		.of_match_table= sun4i_usb_phy_of_match,
 | 
			
		||||
		.name = "sun4i-usb-phy",
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	/* 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);
 | 
			
		||||
 | 
			
		||||
	/* Lock DMU PLL settings */
 | 
			
		||||
	if (usb2->clkset)
 | 
			
		||||
	regmap_write(usb2->clkset, 0, 0x00000000);
 | 
			
		||||
	else
 | 
			
		||||
		writel(0x00000000, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
 | 
			
		||||
 | 
			
		||||
err_clk_off:
 | 
			
		||||
	clk_disable_unprepare(usb2->ref_clk);
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +93,6 @@ 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");
 | 
			
		||||
| 
						 | 
				
			
			@ -120,15 +105,6 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev)
 | 
			
		|||
		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->ref_clk = devm_clk_get(dev, "phy-ref-clk");
 | 
			
		||||
	if (IS_ERR(usb2->ref_clk)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_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,
 | 
			
		||||
		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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
 | 
			
		||||
		[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK,
 | 
			
		||||
		[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
 | 
			
		||||
			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 */
 | 
			
		||||
	},
 | 
			
		||||
	/* 7250b0 */
 | 
			
		||||
	[BRCM_FAMILY_7250B0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		0, /* 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_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
 | 
			
		||||
			USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
 | 
			
		||||
		0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
 | 
			
		||||
		[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[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_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,
 | 
			
		||||
		0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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,
 | 
			
		||||
		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_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,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
 | 
			
		||||
	},
 | 
			
		||||
	/* 7364a0 */
 | 
			
		||||
	[BRCM_FAMILY_7364A0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		0, /* 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_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
 | 
			
		||||
			USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK,
 | 
			
		||||
		0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */
 | 
			
		||||
		[USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
 | 
			
		||||
	},
 | 
			
		||||
	/* 7366c0 */
 | 
			
		||||
	[BRCM_FAMILY_7366C0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		0, /* 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,
 | 
			
		||||
		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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK,
 | 
			
		||||
		[USB_CTRL_USB_PM_USB_PWRDN_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
 | 
			
		||||
	},
 | 
			
		||||
	/* 74371A0 */
 | 
			
		||||
	[BRCM_FAMILY_74371A0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		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_SELECTOR] =
 | 
			
		||||
			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_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,
 | 
			
		||||
		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_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
 | 
			
		||||
	},
 | 
			
		||||
	/* 7439B0 */
 | 
			
		||||
	[BRCM_FAMILY_7439B0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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,
 | 
			
		||||
		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_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[USB_CTRL_SETUP_ENDIAN_SELECTOR] = ENDIAN_SETTINGS,
 | 
			
		||||
	},
 | 
			
		||||
	/* 7445d0 */
 | 
			
		||||
	[BRCM_FAMILY_7445D0] = {
 | 
			
		||||
		[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,
 | 
			
		||||
		0, /* 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_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[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_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,
 | 
			
		||||
		0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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,
 | 
			
		||||
		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_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,
 | 
			
		||||
		ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */
 | 
			
		||||
		[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_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,
 | 
			
		||||
		0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_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,
 | 
			
		||||
		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_SELECTOR] =
 | 
			
		||||
			USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK,
 | 
			
		||||
		[USB_CTRL_USB_PM_SOFT_RESET_SELECTOR] =
 | 
			
		||||
			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 */
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5440,7 +5440,7 @@ 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,
 | 
			
		||||
	.remove	= cdns_torrent_phy_remove,
 | 
			
		||||
	.driver	= {
 | 
			
		||||
		.name	= "cdns-torrent-phy",
 | 
			
		||||
		.of_match_table	= cdns_torrent_phy_of_match,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -434,7 +434,7 @@ 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,
 | 
			
		||||
	.remove = mixel_lvds_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.pm = &mixel_lvds_phy_pm_ops,
 | 
			
		||||
		.name = "mixel-lvds-phy",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -632,7 +632,7 @@ 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,
 | 
			
		||||
	.remove = lynx_28g_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.name = "lynx-28g",
 | 
			
		||||
		.of_match_table = lynx_28g_of_match_table,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 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 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
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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 PHY_REG_33		0x84
 | 
			
		||||
#define REG33_MODE_SET_DONE	BIT(7)
 | 
			
		||||
#define REG33_FIX_DA		BIT(1)
 | 
			
		||||
 | 
			
		||||
#define PHY_REG_34		0x88
 | 
			
		||||
#define REG34_PHY_READY	BIT(7)
 | 
			
		||||
#define REG34_PLL_LOCK		BIT(6)
 | 
			
		||||
#define REG34_PHY_CLK_READY	BIT(5)
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
#ifndef MHZ
 | 
			
		||||
#define MHZ	(1000UL * 1000UL)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#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 &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 = {
 | 
			
		||||
| 
						 | 
				
			
			@ -704,7 +750,7 @@ 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,
 | 
			
		||||
	.remove = fsl_samsung_hdmi_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.name = "fsl-samsung-hdmi-phy",
 | 
			
		||||
		.of_match_table = fsl_samsung_hdmi_phy_of_match,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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->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)
 | 
			
		||||
	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)
 | 
			
		||||
		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,18 +2699,20 @@ 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 */
 | 
			
		||||
	/* 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
											
										
									
								
							| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										123
									
								
								drivers/phy/phy-nxp-ptn3222.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								drivers/phy/phy-nxp-ptn3222.c
									
									
									
									
									
										Normal 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");
 | 
			
		||||
| 
						 | 
				
			
			@ -258,11 +258,11 @@ 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,
 | 
			
		||||
	.remove = qcom_apq8064_sata_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.name = "qcom-apq8064-sata-phy",
 | 
			
		||||
		.of_match_table = qcom_apq8064_sata_phy_of_match,
 | 
			
		||||
	}
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
module_platform_driver(qcom_apq8064_sata_phy_driver);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -185,7 +185,7 @@ 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,
 | 
			
		||||
	.remove = qcom_ipq806x_sata_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.name = "qcom-ipq806x-sata-phy",
 | 
			
		||||
		.of_match_table = qcom_ipq806x_sata_phy_of_match,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
	},
 | 
			
		||||
	{ },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6_30.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
							
								
								
									
										19
									
								
								drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6_30.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ static struct platform_driver rcar_gen3_phy_driver = {
 | 
			
		|||
		.of_match_table = rcar_gen3_phy_pcie_match_table,
 | 
			
		||||
	},
 | 
			
		||||
	.probe = rcar_gen3_phy_pcie_probe,
 | 
			
		||||
	.remove_new = rcar_gen3_phy_pcie_remove,
 | 
			
		||||
	.remove = rcar_gen3_phy_pcie_remove,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module_platform_driver(rcar_gen3_phy_driver);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ static struct platform_driver rcar_gen3_phy_usb3_driver = {
 | 
			
		|||
		.of_match_table = rcar_gen3_phy_usb3_match_table,
 | 
			
		||||
	},
 | 
			
		||||
	.probe = rcar_gen3_phy_usb3_probe,
 | 
			
		||||
	.remove_new = rcar_gen3_phy_usb3_remove,
 | 
			
		||||
	.remove = rcar_gen3_phy_usb3_remove,
 | 
			
		||||
};
 | 
			
		||||
module_platform_driver(rcar_gen3_phy_usb3_driver);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1425,7 +1425,7 @@ 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,
 | 
			
		||||
	.remove = inno_hdmi_phy_remove,
 | 
			
		||||
	.driver = {
 | 
			
		||||
		.name = "inno-hdmi-phy",
 | 
			
		||||
		.of_match_table = inno_hdmi_phy_of_match,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, ®)) {
 | 
			
		||||
		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, ®)) {
 | 
			
		||||
			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 },
 | 
			
		||||
	{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										598
									
								
								drivers/phy/st/phy-stm32-combophy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										598
									
								
								drivers/phy/st/phy-stm32-combophy.c
									
									
									
									
									
										Normal 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");
 | 
			
		||||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,7 +277,7 @@ 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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue