mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00: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
@ -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,7 +1050,7 @@ 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,
|
||||
.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 New Issue
Block a user