mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 12:14:10 +08:00
phy-for-6.11
- New Support - Samsung Exynos gs101 drd combo phy - Qualcomm SC8180x USB uniphy, IPQ9574 QMP PCIe phy - Airoha EN7581 PCIe phy - Freescale i.MX8Q HSIO SerDes phy - Starfive jh7110 dphy tx - Updates - Resume support for j721e-wiz driver - Updates to Exynos usbdrd driver - Support for optional power domains in g12a usb2-phy driver - Debugfs support and updates to zynqmp driver -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmagrXcACgkQfBQHDyUj g0d70Q//WxsWO59+bXIbqRk1YyXOZBlV9vAF+4hrHohwH8CBkJsSLhmWPvM8oUID 5OI9zFYqNUH9PnBtL4CkGkyvsdJAks98qIAIDxL5W500WWEbhjj874rb+BJR6/pm 6LsojpgKnYL/Aq9wOtONZbztdHBK9xkoFTh3+g/EcA505O7j1ZdhW2JDkvFA6xdw 9xQvf18IfOysz/ZnOzvdVzxsS1X19fm/v+4aWOzqQSNQeOppU3ZqInXsSAy2moUY UJ1b9b1WIslrsM0ZFVXhPOVEJp86ZuFC3PW5bJHWcTvbDrnUWz3PPWH3XwFca8fi EdP+8dAzvEvJsKtqZu034z5l9tAOiqOwMCs2loxEauHKihzklMko/dUkUs0IANA+ UULLLEtLH9mGjNWKADJvIbzFFd+Tsv9H6GjoXTKWx7P+BrkBTuIKzDmDqM/kkjgU pYyj65eJJr7R5eLfoDKdIDDiWO7HfZfF8ujsvych5Pft/Kbxd/rTBSADbDz/6ljZ lgvC0XE4T6tMWkwwX+SHUHzJlcQFYBZ09txLgpGdHBmgywPZsJoK4/52BNADEes/ LSe1jgegkc7LMVpfqhqIlHXLmaR+qXY+j5Y5jvYv5bVHx5syHrk7emrQT7YCtkpi 0eJ9IUyFrteeheL1SuNw+BqUuDMBTaOomfzJWyGX4r36Nspg23c= =KWse -----END PGP SIGNATURE----- Merge tag 'phy-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy Pull phy updates from Vinod Koul: "New Support - Samsung Exynos gs101 drd combo phy - Qualcomm SC8180x USB uniphy, IPQ9574 QMP PCIe phy - Airoha EN7581 PCIe phy - Freescale i.MX8Q HSIO SerDes phy - Starfive jh7110 dphy tx Updates: - Resume support for j721e-wiz driver - Updates to Exynos usbdrd driver - Support for optional power domains in g12a usb2-phy driver - Debugfs support and updates to zynqmp driver" * tag 'phy-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (56 commits) phy: airoha: Add dtime and Rx AEQ IO registers dt-bindings: phy: airoha: Add dtime and Rx AEQ IO registers dt-bindings: phy: rockchip-emmc-phy: Convert to dtschema dt-bindings: phy: qcom,qmp-usb: fix spelling error phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS) phy: exynos5-usbdrd: convert Vbus supplies to regulator_bulk phy: exynos5-usbdrd: convert (phy) register access clock to clk_bulk phy: exynos5-usbdrd: convert core clocks to clk_bulk phy: exynos5-usbdrd: support isolating HS and SS ports independently dt-bindings: phy: samsung,usb3-drd-phy: add gs101 compatible phy: core: Fix documentation of of_phy_get phy: starfive: Correct the dphy configure process phy: zynqmp: Add debugfs support phy: zynqmp: Take the phy mutex in xlate phy: zynqmp: Only wait for PLL lock "primary" instances phy: zynqmp: Store instance instead of type phy: zynqmp: Enable reference clock correctly phy: cadence-torrent: Check return value on register read phy: Fix the cacography in phy-exynos5250-usb2.c phy: phy-rockchip-samsung-hdptx: Select CONFIG_MFD_SYSCON ...
This commit is contained in:
commit
c33ffdb70c
@ -0,0 +1,69 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/airoha,en7581-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Airoha EN7581 PCI-Express PHY
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
description:
|
||||
The PCIe PHY supports physical layer functionality for PCIe Gen2/Gen3 port.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: airoha,en7581-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PCIE analog base address
|
||||
- description: PCIE lane0 base address
|
||||
- description: PCIE lane1 base address
|
||||
- description: PCIE lane0 detection time base address
|
||||
- description: PCIE lane1 detection time base address
|
||||
- description: PCIE Rx AEQ base address
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: csr-2l
|
||||
- const: pma0
|
||||
- const: pma1
|
||||
- const: p0-xr-dtime
|
||||
- const: p1-xr-dtime
|
||||
- const: rx-aeq
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
phy@11e80000 {
|
||||
compatible = "airoha,en7581-pcie-phy";
|
||||
#phy-cells = <0>;
|
||||
reg = <0x0 0x1fa5a000 0x0 0xfff>,
|
||||
<0x0 0x1fa5b000 0x0 0xfff>,
|
||||
<0x0 0x1fa5c000 0x0 0xfff>,
|
||||
<0x0 0x1fc10044 0x0 0x4>,
|
||||
<0x0 0x1fc30044 0x0 0x4>,
|
||||
<0x0 0x1fc15030 0x0 0x104>;
|
||||
reg-names = "csr-2l", "pma0", "pma1",
|
||||
"p0-xr-dtime", "p1-xr-dtime",
|
||||
"rx-aeq";
|
||||
};
|
||||
};
|
@ -41,6 +41,9 @@ properties:
|
||||
Phandle to a regulator that provides power to the PHY. This
|
||||
regulator will be managed during the PHY power on/off sequence.
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
164
Documentation/devicetree/bindings/phy/fsl,imx8qm-hsio.yaml
Normal file
164
Documentation/devicetree/bindings/phy/fsl,imx8qm-hsio.yaml
Normal file
@ -0,0 +1,164 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/fsl,imx8qm-hsio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8QM SoC series High Speed IO(HSIO) SERDES PHY
|
||||
|
||||
maintainers:
|
||||
- Richard Zhu <hongxing.zhu@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qm-hsio
|
||||
- fsl,imx8qxp-hsio
|
||||
reg:
|
||||
items:
|
||||
- description: Base address and length of the PHY block
|
||||
- description: HSIO control and status registers(CSR) of the PHY
|
||||
- description: HSIO CSR of the controller bound to the PHY
|
||||
- description: HSIO CSR for MISC
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: reg
|
||||
- const: phy
|
||||
- const: ctrl
|
||||
- const: misc
|
||||
|
||||
"#phy-cells":
|
||||
const: 3
|
||||
description:
|
||||
The first defines lane index.
|
||||
The second defines the type of the PHY refer to the include phy.h.
|
||||
The third defines the controller index, indicated which controller
|
||||
is bound to the lane.
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 14
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 14
|
||||
|
||||
fsl,hsio-cfg:
|
||||
description: |
|
||||
Specifies the use case of the HSIO module in the hardware design.
|
||||
Regarding the design of i.MX8QM HSIO subsystem, HSIO module can be
|
||||
confiured as following three use cases.
|
||||
+---------------------------------------+
|
||||
| | i.MX8QM |
|
||||
|------------------|--------------------|
|
||||
| | Lane0| Lane1| Lane2|
|
||||
|------------------|------|------|------|
|
||||
| pciea-x2-sata | PCIEA| PCIEA| SATA |
|
||||
|------------------|------|------|------|
|
||||
| pciea-x2-pcieb | PCIEA| PCIEA| PCIEB|
|
||||
|------------------|------|------|------|
|
||||
| pciea-pcieb-sata | PCIEA| PCIEB| SATA |
|
||||
+---------------------------------------+
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [ pciea-x2-sata, pciea-x2-pcieb, pciea-pcieb-sata]
|
||||
default: pciea-pcieb-sata
|
||||
|
||||
fsl,refclk-pad-mode:
|
||||
description:
|
||||
Specifies the mode of the refclk pad used. INPUT(PHY refclock is
|
||||
provided externally via the refclk pad) or OUTPUT(PHY refclock is
|
||||
derived from SoC internal source and provided on the refclk pad).
|
||||
This property not exists means unused(PHY refclock is derived from
|
||||
SoC internal source).
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [ input, output, unused ]
|
||||
default: unused
|
||||
|
||||
power-domains:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- fsl,hsio-cfg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8qxp-hsio
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk0
|
||||
- const: apb_pclk0
|
||||
- const: phy0_crr
|
||||
- const: ctl0_crr
|
||||
- const: misc_crr
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8qm-hsio
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk0
|
||||
- const: pclk1
|
||||
- const: apb_pclk0
|
||||
- const: apb_pclk1
|
||||
- const: pclk2
|
||||
- const: epcs_tx
|
||||
- const: epcs_rx
|
||||
- const: apb_pclk2
|
||||
- const: phy0_crr
|
||||
- const: phy1_crr
|
||||
- const: ctl0_crr
|
||||
- const: ctl1_crr
|
||||
- const: ctl2_crr
|
||||
- const: misc_crr
|
||||
power-domains:
|
||||
minItems: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx8-clock.h>
|
||||
#include <dt-bindings/clock/imx8-lpcg.h>
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <dt-bindings/phy/phy-imx8-pcie.h>
|
||||
|
||||
phy@5f1a0000 {
|
||||
compatible = "fsl,imx8qxp-hsio";
|
||||
reg = <0x5f1a0000 0x10000>,
|
||||
<0x5f120000 0x10000>,
|
||||
<0x5f140000 0x10000>,
|
||||
<0x5f160000 0x10000>;
|
||||
reg-names = "reg", "phy", "ctrl", "misc";
|
||||
clocks = <&phyx1_lpcg IMX_LPCG_CLK_0>,
|
||||
<&phyx1_lpcg IMX_LPCG_CLK_4>,
|
||||
<&phyx1_crr1_lpcg IMX_LPCG_CLK_4>,
|
||||
<&pcieb_crr3_lpcg IMX_LPCG_CLK_4>,
|
||||
<&misc_crr5_lpcg IMX_LPCG_CLK_4>;
|
||||
clock-names = "pclk0", "apb_pclk0", "phy0_crr", "ctl0_crr", "misc_crr";
|
||||
power-domains = <&pd IMX_SC_R_SERDES_1>;
|
||||
#phy-cells = <3>;
|
||||
fsl,hsio-cfg = "pciea-pcieb-sata";
|
||||
fsl,refclk-pad-mode = "input";
|
||||
};
|
||||
...
|
@ -41,6 +41,12 @@ properties:
|
||||
Phandle to the system controller node
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
swap-dx-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
Specifies the ports which will swap the differential-pair (D+/D-),
|
||||
default is not-swapped.
|
||||
|
||||
# Required child nodes:
|
||||
|
||||
patternProperties:
|
||||
|
@ -19,6 +19,8 @@ properties:
|
||||
- qcom,ipq6018-qmp-pcie-phy
|
||||
- qcom,ipq8074-qmp-gen3-pcie-phy
|
||||
- qcom,ipq8074-qmp-pcie-phy
|
||||
- qcom,ipq9574-qmp-gen3x1-pcie-phy
|
||||
- qcom,ipq9574-qmp-gen3x2-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -91,8 +91,7 @@ properties:
|
||||
"#clock-cells": true
|
||||
|
||||
clock-output-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
@ -222,14 +221,10 @@ allOf:
|
||||
- qcom,sm8650-qmp-gen4x2-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clock-output-names:
|
||||
minItems: 2
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
else:
|
||||
properties:
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
|
@ -20,8 +20,9 @@ properties:
|
||||
- qcom,ipq8074-qmp-usb3-phy
|
||||
- qcom,ipq9574-qmp-usb3-phy
|
||||
- qcom,msm8996-qmp-usb3-phy
|
||||
- com,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sdm845-qmp-usb3-uni-phy
|
||||
- qcom,sdx55-qmp-usb3-uni-phy
|
||||
@ -112,6 +113,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sm8150-qmp-usb3-uni-phy
|
||||
- qcom,sm8250-qmp-usb3-uni-phy
|
||||
@ -152,6 +154,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,x1e80100-qmp-usb3-uni-phy
|
||||
then:
|
||||
|
@ -15,6 +15,7 @@ if:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,usb-hs-phy-apq8064
|
||||
- qcom,usb-hs-phy-msm8660
|
||||
- qcom,usb-hs-phy-msm8960
|
||||
then:
|
||||
properties:
|
||||
@ -41,6 +42,7 @@ properties:
|
||||
- enum:
|
||||
- qcom,usb-hs-phy-apq8064
|
||||
- qcom,usb-hs-phy-msm8226
|
||||
- qcom,usb-hs-phy-msm8660
|
||||
- qcom,usb-hs-phy-msm8916
|
||||
- qcom,usb-hs-phy-msm8960
|
||||
- qcom,usb-hs-phy-msm8974
|
||||
|
@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/rockchip,rk3399-emmc-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip EMMC PHY
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rockchip,rk3399-emmc-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: emmcclk
|
||||
|
||||
drive-impedance-ohm:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Specifies the drive impedance in Ohm.
|
||||
enum: [33, 40, 50, 66, 100]
|
||||
default: 50
|
||||
|
||||
rockchip,enable-strobe-pulldown:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable internal pull-down for the strobe
|
||||
line. If not set, pull-down is not used.
|
||||
|
||||
rockchip,output-tapdelay-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Specifies the phyctrl_otapdlysec register.
|
||||
default: 0x4
|
||||
maximum: 0xf
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
Rockchip EMMC PHY
|
||||
-----------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: rockchip,rk3399-emmc-phy
|
||||
- #phy-cells: must be 0
|
||||
- reg: PHY register address offset and length in "general
|
||||
register files"
|
||||
|
||||
Optional properties:
|
||||
- clock-names: Should contain "emmcclk". Although this is listed as optional
|
||||
(because most boards can get basic functionality without having
|
||||
access to it), it is strongly suggested.
|
||||
See ../clock/clock-bindings.txt for details.
|
||||
- clocks: Should have a phandle to the card clock exported by the SDHCI driver.
|
||||
- drive-impedance-ohm: Specifies the drive impedance in Ohm.
|
||||
Possible values are 33, 40, 50, 66 and 100.
|
||||
If not set, the default value of 50 will be applied.
|
||||
- rockchip,enable-strobe-pulldown: Enable internal pull-down for the strobe
|
||||
line. If not set, pull-down is not used.
|
||||
- rockchip,output-tapdelay-select: Specifies the phyctrl_otapdlysec register.
|
||||
If not set, the register defaults to 0x4.
|
||||
Maximum value 0xf.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
grf: syscon@ff770000 {
|
||||
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
...
|
||||
|
||||
emmcphy: phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
@ -25,6 +25,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- google,gs101-usb31drd-phy
|
||||
- samsung,exynos5250-usbdrd-phy
|
||||
- samsung,exynos5420-usbdrd-phy
|
||||
- samsung,exynos5433-usbdrd-phy
|
||||
@ -57,7 +58,15 @@ properties:
|
||||
the OF graph bindings specified.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: phy
|
||||
- const: pcs
|
||||
- const: pma
|
||||
|
||||
samsung,pmu-syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
@ -72,6 +81,19 @@ properties:
|
||||
description:
|
||||
VBUS Boost 5V power source.
|
||||
|
||||
pll-supply:
|
||||
description: Power supply for the USB PLL.
|
||||
dvdd-usb20-supply:
|
||||
description: DVDD power supply for the USB 2.0 phy.
|
||||
vddh-usb20-supply:
|
||||
description: VDDh power supply for the USB 2.0 phy.
|
||||
vdd33-usb20-supply:
|
||||
description: 3.3V power supply for the USB 2.0 phy.
|
||||
vdda-usbdp-supply:
|
||||
description: VDDa power supply for the USB DP phy.
|
||||
vddh-usbdp-supply:
|
||||
description: VDDh power supply for the USB DP phy.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
@ -81,6 +103,40 @@ required:
|
||||
- samsung,pmu-syscon
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: google,gs101-usb31drd-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Gate of main PHY clock
|
||||
- description: Gate of PHY reference clock
|
||||
- description: Gate of control interface AXI clock
|
||||
- description: Gate of control interface APB clock
|
||||
- description: Gate of SCL APB clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: ref
|
||||
- const: ctrl_aclk
|
||||
- const: ctrl_pclk
|
||||
- const: scl_pclk
|
||||
reg:
|
||||
minItems: 3
|
||||
reg-names:
|
||||
minItems: 3
|
||||
required:
|
||||
- reg-names
|
||||
- pll-supply
|
||||
- dvdd-usb20-supply
|
||||
- vddh-usb20-supply
|
||||
- vdd33-usb20-supply
|
||||
- vdda-usbdp-supply
|
||||
- vddh-usbdp-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -100,7 +156,20 @@ allOf:
|
||||
- const: phy_utmi
|
||||
- const: phy_pipe
|
||||
- const: itp
|
||||
else:
|
||||
reg:
|
||||
maxItems: 1
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynos5250-usbdrd-phy
|
||||
- samsung,exynos5420-usbdrd-phy
|
||||
- samsung,exynos850-usbdrd-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
@ -109,6 +178,10 @@ allOf:
|
||||
items:
|
||||
- const: phy
|
||||
- const: ref
|
||||
reg:
|
||||
maxItems: 1
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/starfive,jh7110-dphy-tx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Starfive SoC MIPI D-PHY Tx Controller
|
||||
|
||||
maintainers:
|
||||
- Keith Zhao <keith.zhao@starfivetech.com>
|
||||
- Shengyang Chen <shengyang.chen@starfivetech.com>
|
||||
|
||||
description:
|
||||
The Starfive SoC uses the MIPI DSI D-PHY based on M31 IP to transfer
|
||||
DSI data.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: starfive,jh7110-dphy-tx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: txesc
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MIPITX_DPHY_SYS reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: sys
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@295e0000 {
|
||||
compatible = "starfive,jh7110-dphy-tx";
|
||||
reg = <0x295e0000 0x10000>;
|
||||
clocks = <&voutcrg 14>;
|
||||
clock-names = "txesc";
|
||||
resets = <&syscrg 10>;
|
||||
reset-names = "sys";
|
||||
power-domains = <&aon_syscon 0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -176,9 +176,10 @@ allOf:
|
||||
Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt
|
||||
|
||||
patternProperties:
|
||||
"phy@[0-9a-f]+$":
|
||||
description:
|
||||
Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/phy/rockchip,rk3399-emmc-phy.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@ -292,6 +293,15 @@ examples:
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
u2phy0: usb2phy@e450 {
|
||||
compatible = "rockchip,rk3399-usb2phy";
|
||||
reg = <0xe450 0x10>;
|
||||
|
15
MAINTAINERS
15
MAINTAINERS
@ -702,6 +702,14 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
|
||||
F: drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
|
||||
AIROHA PCIE PHY DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml
|
||||
F: drivers/phy/phy-airoha-pcie-regs.h
|
||||
F: drivers/phy/phy-airoha-pcie.c
|
||||
|
||||
AIROHA SPI SNFI DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
M: Ray Liu <ray.liu@airoha.com>
|
||||
@ -21682,6 +21690,13 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
|
||||
F: drivers/phy/starfive/phy-jh7110-dphy-rx.c
|
||||
|
||||
STARFIVE JH7110 DPHY TX DRIVER
|
||||
M: Keith Zhao <keith.zhao@starfivetech.com>
|
||||
M: Shengyang Chen <shengyang.chen@starfivetech.com>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-tx.yaml
|
||||
F: drivers/phy/starfive/phy-jh7110-dphy-tx.c
|
||||
|
||||
STARFIVE JH7110 MMC/SD/SDIO DRIVER
|
||||
M: William Qiu <william.qiu@starfivetech.com>
|
||||
S: Supported
|
||||
|
@ -72,6 +72,16 @@ config PHY_CAN_TRANSCEIVER
|
||||
functional modes using gpios and sets the attribute max link
|
||||
rate, for CAN drivers.
|
||||
|
||||
config PHY_AIROHA_PCIE
|
||||
tristate "Airoha PCIe-PHY Driver"
|
||||
depends on ARCH_AIROHA || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Say Y here to add support for Airoha PCIe PHY driver.
|
||||
This driver create the basic PHY instance and provides initialize
|
||||
callback for PCIe GEN3 port.
|
||||
|
||||
source "drivers/phy/allwinner/Kconfig"
|
||||
source "drivers/phy/amlogic/Kconfig"
|
||||
source "drivers/phy/broadcom/Kconfig"
|
||||
|
@ -10,6 +10,7 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
|
||||
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-y += allwinner/ \
|
||||
amlogic/ \
|
||||
broadcom/ \
|
||||
|
@ -162,4 +162,5 @@ static struct platform_driver bcm_ns_usb2_driver = {
|
||||
};
|
||||
module_platform_driver(bcm_ns_usb2_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom Northstar USB 2.0 PHY Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -240,5 +240,6 @@ static struct mdio_driver bcm_ns_usb3_mdio_driver = {
|
||||
|
||||
mdio_module_driver(bcm_ns_usb3_mdio_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom Northstar USB 3.0 PHY Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
|
||||
|
@ -360,6 +360,7 @@ struct cdns_torrent_phy {
|
||||
enum cdns_torrent_ref_clk ref_clk1_rate;
|
||||
struct cdns_torrent_inst phys[MAX_NUM_LANES];
|
||||
int nsubnodes;
|
||||
int already_configured;
|
||||
const struct cdns_torrent_data *init_data;
|
||||
struct regmap *regmap_common_cdb;
|
||||
struct regmap *regmap_phy_pcs_common_cdb;
|
||||
@ -1156,6 +1157,9 @@ static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
|
||||
ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK,
|
||||
read_val, (read_val & mask) == value, 0,
|
||||
POLL_TIMEOUT_US);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000);
|
||||
ndelay(100);
|
||||
|
||||
@ -1594,6 +1598,9 @@ static int cdns_torrent_dp_configure(struct phy *phy,
|
||||
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
|
||||
int ret;
|
||||
|
||||
if (cdns_phy->already_configured)
|
||||
return 0;
|
||||
|
||||
ret = cdns_torrent_dp_verify_config(inst, &opts->dp);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "invalid params for phy configure\n");
|
||||
@ -1629,6 +1636,12 @@ static int cdns_torrent_phy_on(struct phy *phy)
|
||||
u32 read_val;
|
||||
int ret;
|
||||
|
||||
if (cdns_phy->already_configured) {
|
||||
/* Give 5ms to 10ms delay for the PIPE clock to be stable */
|
||||
usleep_range(5000, 10000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cdns_phy->nsubnodes == 1) {
|
||||
/* Take the PHY lane group out of reset */
|
||||
reset_control_deassert(inst->lnk_rst);
|
||||
@ -2307,6 +2320,9 @@ static int cdns_torrent_phy_init(struct phy *phy)
|
||||
u32 num_regs;
|
||||
int i, j;
|
||||
|
||||
if (cdns_phy->already_configured)
|
||||
return 0;
|
||||
|
||||
if (cdns_phy->nsubnodes > 1) {
|
||||
if (phy_type == TYPE_DP)
|
||||
return cdns_torrent_dp_multilink_init(cdns_phy, inst, phy);
|
||||
@ -2444,19 +2460,6 @@ static const struct phy_ops cdns_torrent_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int cdns_torrent_noop_phy_on(struct phy *phy)
|
||||
{
|
||||
/* Give 5ms to 10ms delay for the PIPE clock to be stable */
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops noop_ops = {
|
||||
.power_on = cdns_torrent_noop_phy_on,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static
|
||||
int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
@ -2678,7 +2681,7 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
|
||||
static int cdns_torrent_of_get_reset(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
struct device *dev = cdns_phy->dev;
|
||||
|
||||
@ -2699,20 +2702,29 @@ static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdns_torrent_of_get_clk(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
/* refclk: Input reference clock for PLL0 */
|
||||
cdns_phy->clk = devm_clk_get(cdns_phy->dev, "refclk");
|
||||
if (IS_ERR(cdns_phy->clk))
|
||||
return dev_err_probe(cdns_phy->dev, PTR_ERR(cdns_phy->clk),
|
||||
"phy ref clock not found\n");
|
||||
|
||||
/* refclk1: Input reference clock for PLL1 */
|
||||
cdns_phy->clk1 = devm_clk_get_optional(cdns_phy->dev, "pll1_refclk");
|
||||
if (IS_ERR(cdns_phy->clk1))
|
||||
return dev_err_probe(cdns_phy->dev, PTR_ERR(cdns_phy->clk1),
|
||||
"phy PLL1 ref clock not found\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
struct device *dev = cdns_phy->dev;
|
||||
unsigned long ref_clk1_rate;
|
||||
unsigned long ref_clk_rate;
|
||||
int ret;
|
||||
|
||||
/* refclk: Input reference clock for PLL0 */
|
||||
cdns_phy->clk = devm_clk_get(dev, "refclk");
|
||||
if (IS_ERR(cdns_phy->clk)) {
|
||||
dev_err(dev, "phy ref clock not found\n");
|
||||
return PTR_ERR(cdns_phy->clk);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(cdns_phy->clk);
|
||||
if (ret) {
|
||||
dev_err(cdns_phy->dev, "Failed to prepare ref clock: %d\n", ret);
|
||||
@ -2745,14 +2757,6 @@ static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
/* refclk1: Input reference clock for PLL1 */
|
||||
cdns_phy->clk1 = devm_clk_get_optional(dev, "pll1_refclk");
|
||||
if (IS_ERR(cdns_phy->clk1)) {
|
||||
dev_err(dev, "phy PLL1 ref clock not found\n");
|
||||
ret = PTR_ERR(cdns_phy->clk1);
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
if (cdns_phy->clk1) {
|
||||
ret = clk_prepare_enable(cdns_phy->clk1);
|
||||
if (ret) {
|
||||
@ -2807,7 +2811,6 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
||||
struct device_node *child;
|
||||
int ret, subnodes, node = 0, i;
|
||||
u32 total_num_lanes = 0;
|
||||
int already_configured;
|
||||
u8 init_dp_regmap = 0;
|
||||
u32 phy_type;
|
||||
|
||||
@ -2846,13 +2849,17 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &already_configured);
|
||||
ret = cdns_torrent_of_get_reset(cdns_phy);
|
||||
if (ret)
|
||||
goto clk_cleanup;
|
||||
|
||||
if (!already_configured) {
|
||||
ret = cdns_torrent_reset(cdns_phy);
|
||||
if (ret)
|
||||
goto clk_cleanup;
|
||||
ret = cdns_torrent_of_get_clk(cdns_phy);
|
||||
if (ret)
|
||||
goto clk_cleanup;
|
||||
|
||||
regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &cdns_phy->already_configured);
|
||||
|
||||
if (!cdns_phy->already_configured) {
|
||||
ret = cdns_torrent_clk(cdns_phy);
|
||||
if (ret)
|
||||
goto clk_cleanup;
|
||||
@ -2932,10 +2939,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
||||
of_property_read_u32(child, "cdns,ssc-mode",
|
||||
&cdns_phy->phys[node].ssc_mode);
|
||||
|
||||
if (!already_configured)
|
||||
gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
|
||||
else
|
||||
gphy = devm_phy_create(dev, child, &noop_ops);
|
||||
gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
|
||||
if (IS_ERR(gphy)) {
|
||||
ret = PTR_ERR(gphy);
|
||||
goto put_child;
|
||||
@ -3018,7 +3022,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
||||
goto put_lnk_rst;
|
||||
}
|
||||
|
||||
if (cdns_phy->nsubnodes > 1 && !already_configured) {
|
||||
if (cdns_phy->nsubnodes > 1 && !cdns_phy->already_configured) {
|
||||
ret = cdns_torrent_phy_configure_multilink(cdns_phy);
|
||||
if (ret)
|
||||
goto put_lnk_rst;
|
||||
@ -3074,6 +3078,82 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
|
||||
cdns_torrent_clk_cleanup(cdns_phy);
|
||||
}
|
||||
|
||||
/* SGMII and QSGMII link configuration */
|
||||
static struct cdns_reg_pairs sgmii_qsgmii_link_cmn_regs[] = {
|
||||
{0x0002, PHY_PLL_CFG}
|
||||
};
|
||||
|
||||
static struct cdns_reg_pairs sgmii_qsgmii_xcvr_diag_ln_regs[] = {
|
||||
{0x0003, XCVR_DIAG_HSCLK_DIV},
|
||||
{0x0113, XCVR_DIAG_PLLDRC_CTRL}
|
||||
};
|
||||
|
||||
static struct cdns_torrent_vals sgmii_qsgmii_link_cmn_vals = {
|
||||
.reg_pairs = sgmii_qsgmii_link_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_qsgmii_link_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_torrent_vals sgmii_qsgmii_xcvr_diag_ln_vals = {
|
||||
.reg_pairs = sgmii_qsgmii_xcvr_diag_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs),
|
||||
};
|
||||
|
||||
static int cdns_torrent_phy_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
reset_control_assert(cdns_phy->phy_rst);
|
||||
reset_control_assert(cdns_phy->apb_rst);
|
||||
for (i = 0; i < cdns_phy->nsubnodes; i++)
|
||||
reset_control_assert(cdns_phy->phys[i].lnk_rst);
|
||||
|
||||
if (cdns_phy->already_configured)
|
||||
cdns_phy->already_configured = 0;
|
||||
else {
|
||||
clk_disable_unprepare(cdns_phy->clk1);
|
||||
clk_disable_unprepare(cdns_phy->clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdns_torrent_phy_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
|
||||
int node = cdns_phy->nsubnodes;
|
||||
int ret, i;
|
||||
|
||||
ret = cdns_torrent_clk(cdns_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable APB */
|
||||
reset_control_deassert(cdns_phy->apb_rst);
|
||||
|
||||
if (cdns_phy->nsubnodes > 1) {
|
||||
ret = cdns_torrent_phy_configure_multilink(cdns_phy);
|
||||
if (ret)
|
||||
goto put_lnk_rst;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
put_lnk_rst:
|
||||
for (i = 0; i < node; i++)
|
||||
reset_control_assert(cdns_phy->phys[i].lnk_rst);
|
||||
reset_control_assert(cdns_phy->apb_rst);
|
||||
|
||||
clk_disable_unprepare(cdns_phy->clk1);
|
||||
clk_disable_unprepare(cdns_phy->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_NOIRQ_DEV_PM_OPS(cdns_torrent_phy_pm_ops,
|
||||
cdns_torrent_phy_suspend_noirq,
|
||||
cdns_torrent_phy_resume_noirq);
|
||||
|
||||
/* USB and DP link configuration */
|
||||
static struct cdns_reg_pairs usb_dp_link_cmn_regs[] = {
|
||||
{0x0002, PHY_PLL_CFG},
|
||||
@ -4043,7 +4123,8 @@ static struct cdns_reg_pairs sgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x04A2, TX_PSC_A2},
|
||||
{0x04A2, TX_PSC_A3},
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00},
|
||||
{0x00B3, DRV_DIAG_TX_DRV}
|
||||
{0x00B3, DRV_DIAG_TX_DRV},
|
||||
{0x0002, XCVR_DIAG_PSC_OVRD}
|
||||
};
|
||||
|
||||
static struct cdns_reg_pairs ti_sgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
@ -4052,7 +4133,8 @@ static struct cdns_reg_pairs ti_sgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x04A2, TX_PSC_A3},
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00},
|
||||
{0x00B3, DRV_DIAG_TX_DRV},
|
||||
{0x4000, XCVR_DIAG_RXCLK_CTRL},
|
||||
{0x0002, XCVR_DIAG_PSC_OVRD},
|
||||
{0x4000, XCVR_DIAG_RXCLK_CTRL}
|
||||
};
|
||||
|
||||
static struct cdns_reg_pairs sgmii_100_no_ssc_rx_ln_regs[] = {
|
||||
@ -4219,7 +4301,8 @@ static struct cdns_reg_pairs qsgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x04A2, TX_PSC_A3},
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00},
|
||||
{0x0011, TX_TXCC_MGNFS_MULT_100},
|
||||
{0x0003, DRV_DIAG_TX_DRV}
|
||||
{0x0003, DRV_DIAG_TX_DRV},
|
||||
{0x0002, XCVR_DIAG_PSC_OVRD}
|
||||
};
|
||||
|
||||
static struct cdns_reg_pairs ti_qsgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
@ -4229,7 +4312,8 @@ static struct cdns_reg_pairs ti_qsgmii_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00},
|
||||
{0x0011, TX_TXCC_MGNFS_MULT_100},
|
||||
{0x0003, DRV_DIAG_TX_DRV},
|
||||
{0x4000, XCVR_DIAG_RXCLK_CTRL},
|
||||
{0x0002, XCVR_DIAG_PSC_OVRD},
|
||||
{0x4000, XCVR_DIAG_RXCLK_CTRL}
|
||||
};
|
||||
|
||||
static struct cdns_reg_pairs qsgmii_100_no_ssc_rx_ln_regs[] = {
|
||||
@ -4541,11 +4625,13 @@ static struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_QSGMII), &sgmii_qsgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &usb_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &pcie_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_SGMII), &sgmii_qsgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &usb_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &usxgmii_sgmii_link_cmn_vals},
|
||||
|
||||
@ -4575,11 +4661,13 @@ static struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_QSGMII), &sgmii_qsgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_SGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_NONE), &sl_sgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_PCIE), &sgmii_pcie_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_SGMII), &sgmii_qsgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USB), &sgmii_usb_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_QSGMII, TYPE_USXGMII), &sgmii_usxgmii_xcvr_diag_ln_vals},
|
||||
|
||||
@ -4635,6 +4723,8 @@ static struct cdns_torrent_vals_entry cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_int_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
@ -4645,6 +4735,8 @@ static struct cdns_torrent_vals_entry cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_int_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &sl_qsgmii_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
@ -4713,6 +4805,8 @@ static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -4723,6 +4817,8 @@ static struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -4791,6 +4887,8 @@ static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
@ -4801,6 +4899,8 @@ static struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
@ -4905,6 +5005,8 @@ static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -4915,6 +5017,8 @@ static struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -5017,6 +5121,8 @@ static struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_int_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &sl_sgmii_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_cmn_vals},
|
||||
@ -5027,6 +5133,8 @@ static struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_int_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &sl_qsgmii_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_cmn_vals},
|
||||
@ -5095,6 +5203,8 @@ static struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &ti_sgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -5105,6 +5215,8 @@ static struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &ti_qsgmii_100_no_ssc_tx_ln_vals},
|
||||
@ -5173,6 +5285,8 @@ static struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_PCIE, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_QSGMII, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, NO_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, EXTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_SGMII, TYPE_USB, INTERNAL_SSC), &sgmii_100_no_ssc_rx_ln_vals},
|
||||
@ -5183,6 +5297,8 @@ static struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_PCIE, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_SGMII, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, NO_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, EXTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_QSGMII, TYPE_USB, INTERNAL_SSC), &qsgmii_100_no_ssc_rx_ln_vals},
|
||||
@ -5275,6 +5391,7 @@ static struct platform_driver cdns_torrent_phy_driver = {
|
||||
.driver = {
|
||||
.name = "cdns-torrent-phy",
|
||||
.of_match_table = cdns_torrent_phy_of_match,
|
||||
.pm = pm_sleep_ptr(&cdns_torrent_phy_pm_ops),
|
||||
}
|
||||
};
|
||||
module_platform_driver(cdns_torrent_phy_driver);
|
||||
|
@ -35,12 +35,19 @@ config PHY_FSL_IMX8M_PCIE
|
||||
Enable this to add support for the PCIE PHY as found on
|
||||
i.MX8M family of SOCs.
|
||||
|
||||
config PHY_FSL_IMX8QM_HSIO
|
||||
tristate "Freescale i.MX8QM HSIO PHY"
|
||||
depends on OF && HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to add support for the HSIO PHY as found on
|
||||
i.MX8QM family of SOCs.
|
||||
|
||||
config PHY_FSL_SAMSUNG_HDMI_PHY
|
||||
tristate "Samsung HDMI PHY support"
|
||||
depends on OF && HAS_IOMEM && COMMON_CLK
|
||||
help
|
||||
Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
|
||||
|
||||
endif
|
||||
|
||||
config PHY_FSL_LYNX_28G
|
||||
|
@ -3,5 +3,6 @@ obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o
|
||||
obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o
|
||||
obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o
|
||||
obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o
|
||||
obj-$(CONFIG_PHY_FSL_IMX8QM_HSIO) += phy-fsl-imx8qm-hsio.o
|
||||
obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o
|
||||
obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY) += phy-fsl-samsung-hdmi.o
|
||||
|
611
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
Normal file
611
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
Normal file
@ -0,0 +1,611 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2024 NXP
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pci_regs.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/phy/pcie.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/phy/phy-imx8-pcie.h>
|
||||
|
||||
#define MAX_NUM_LANE 3
|
||||
#define LANE_NUM_CLKS 5
|
||||
|
||||
/* Parameters for the waiting for PCIe PHY PLL to lock */
|
||||
#define PHY_INIT_WAIT_USLEEP_MAX 10
|
||||
#define PHY_INIT_WAIT_TIMEOUT (1000 * PHY_INIT_WAIT_USLEEP_MAX)
|
||||
|
||||
/* i.MX8Q HSIO registers */
|
||||
#define HSIO_CTRL0 0x0
|
||||
#define HSIO_APB_RSTN_0 BIT(0)
|
||||
#define HSIO_APB_RSTN_1 BIT(1)
|
||||
#define HSIO_PIPE_RSTN_0_MASK GENMASK(25, 24)
|
||||
#define HSIO_PIPE_RSTN_1_MASK GENMASK(27, 26)
|
||||
#define HSIO_MODE_MASK GENMASK(20, 17)
|
||||
#define HSIO_MODE_PCIE 0x0
|
||||
#define HSIO_MODE_SATA 0x4
|
||||
#define HSIO_DEVICE_TYPE_MASK GENMASK(27, 24)
|
||||
#define HSIO_EPCS_TXDEEMP BIT(5)
|
||||
#define HSIO_EPCS_TXDEEMP_SEL BIT(6)
|
||||
#define HSIO_EPCS_PHYRESET_N BIT(7)
|
||||
#define HSIO_RESET_N BIT(12)
|
||||
|
||||
#define HSIO_IOB_RXENA BIT(0)
|
||||
#define HSIO_IOB_TXENA BIT(1)
|
||||
#define HSIO_IOB_A_0_TXOE BIT(2)
|
||||
#define HSIO_IOB_A_0_M1M0_2 BIT(4)
|
||||
#define HSIO_IOB_A_0_M1M0_MASK GENMASK(4, 3)
|
||||
#define HSIO_PHYX1_EPCS_SEL BIT(12)
|
||||
#define HSIO_PCIE_AB_SELECT BIT(13)
|
||||
|
||||
#define HSIO_PHY_STS0 0x4
|
||||
#define HSIO_LANE0_TX_PLL_LOCK BIT(4)
|
||||
#define HSIO_LANE1_TX_PLL_LOCK BIT(12)
|
||||
|
||||
#define HSIO_CTRL2 0x8
|
||||
#define HSIO_LTSSM_ENABLE BIT(4)
|
||||
#define HSIO_BUTTON_RST_N BIT(21)
|
||||
#define HSIO_PERST_N BIT(22)
|
||||
#define HSIO_POWER_UP_RST_N BIT(23)
|
||||
|
||||
#define HSIO_PCIE_STS0 0xc
|
||||
#define HSIO_PM_REQ_CORE_RST BIT(19)
|
||||
|
||||
#define HSIO_REG48_PMA_STATUS 0x30
|
||||
#define HSIO_REG48_PMA_RDY BIT(7)
|
||||
|
||||
struct imx_hsio_drvdata {
|
||||
int lane_num;
|
||||
};
|
||||
|
||||
struct imx_hsio_lane {
|
||||
u32 ctrl_index;
|
||||
u32 ctrl_off;
|
||||
u32 idx;
|
||||
u32 phy_off;
|
||||
u32 phy_type;
|
||||
const char * const *clk_names;
|
||||
struct clk_bulk_data clks[LANE_NUM_CLKS];
|
||||
struct imx_hsio_priv *priv;
|
||||
struct phy *phy;
|
||||
enum phy_mode phy_mode;
|
||||
};
|
||||
|
||||
struct imx_hsio_priv {
|
||||
void __iomem *base;
|
||||
struct device *dev;
|
||||
struct mutex lock;
|
||||
const char *hsio_cfg;
|
||||
const char *refclk_pad;
|
||||
u32 open_cnt;
|
||||
struct regmap *phy;
|
||||
struct regmap *ctrl;
|
||||
struct regmap *misc;
|
||||
const struct imx_hsio_drvdata *drvdata;
|
||||
struct imx_hsio_lane lane[MAX_NUM_LANE];
|
||||
};
|
||||
|
||||
static const char * const lan0_pcie_clks[] = {"apb_pclk0", "pclk0", "ctl0_crr",
|
||||
"phy0_crr", "misc_crr"};
|
||||
static const char * const lan1_pciea_clks[] = {"apb_pclk1", "pclk1", "ctl0_crr",
|
||||
"phy0_crr", "misc_crr"};
|
||||
static const char * const lan1_pcieb_clks[] = {"apb_pclk1", "pclk1", "ctl1_crr",
|
||||
"phy0_crr", "misc_crr"};
|
||||
static const char * const lan2_pcieb_clks[] = {"apb_pclk2", "pclk2", "ctl1_crr",
|
||||
"phy1_crr", "misc_crr"};
|
||||
static const char * const lan2_sata_clks[] = {"pclk2", "epcs_tx", "epcs_rx",
|
||||
"phy1_crr", "misc_crr"};
|
||||
|
||||
static const struct regmap_config regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static int imx_hsio_init(struct phy *phy)
|
||||
{
|
||||
int ret, i;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
struct device *dev = priv->dev;
|
||||
|
||||
/* Assign clocks refer to different modes */
|
||||
switch (lane->phy_type) {
|
||||
case PHY_TYPE_PCIE:
|
||||
lane->phy_mode = PHY_MODE_PCIE;
|
||||
if (lane->ctrl_index == 0) { /* PCIEA */
|
||||
lane->ctrl_off = 0;
|
||||
lane->phy_off = 0;
|
||||
|
||||
for (i = 0; i < LANE_NUM_CLKS; i++) {
|
||||
if (lane->idx == 0)
|
||||
lane->clks[i].id = lan0_pcie_clks[i];
|
||||
else
|
||||
lane->clks[i].id = lan1_pciea_clks[i];
|
||||
}
|
||||
} else { /* PCIEB */
|
||||
if (lane->idx == 0) { /* i.MX8QXP */
|
||||
lane->ctrl_off = 0;
|
||||
lane->phy_off = 0;
|
||||
} else {
|
||||
/*
|
||||
* On i.MX8QM, only second or third lane can be
|
||||
* bound to PCIEB.
|
||||
*/
|
||||
lane->ctrl_off = SZ_64K;
|
||||
if (lane->idx == 1)
|
||||
lane->phy_off = 0;
|
||||
else /* the third lane is bound to PCIEB */
|
||||
lane->phy_off = SZ_64K;
|
||||
}
|
||||
|
||||
for (i = 0; i < LANE_NUM_CLKS; i++) {
|
||||
if (lane->idx == 1)
|
||||
lane->clks[i].id = lan1_pcieb_clks[i];
|
||||
else if (lane->idx == 2)
|
||||
lane->clks[i].id = lan2_pcieb_clks[i];
|
||||
else /* i.MX8QXP only has PCIEB, idx is 0 */
|
||||
lane->clks[i].id = lan0_pcie_clks[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PHY_TYPE_SATA:
|
||||
/* On i.MX8QM, only the third lane can be bound to SATA */
|
||||
lane->phy_mode = PHY_MODE_SATA;
|
||||
lane->ctrl_off = SZ_128K;
|
||||
lane->phy_off = SZ_64K;
|
||||
|
||||
for (i = 0; i < LANE_NUM_CLKS; i++)
|
||||
lane->clks[i].id = lan2_sata_clks[i];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Fetch clocks and enable them */
|
||||
ret = devm_clk_bulk_get(dev, LANE_NUM_CLKS, lane->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = clk_bulk_prepare_enable(LANE_NUM_CLKS, lane->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* allow the clocks to stabilize */
|
||||
usleep_range(200, 500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_hsio_exit(struct phy *phy)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
|
||||
clk_bulk_disable_unprepare(LANE_NUM_CLKS, lane->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_hsio_pcie_phy_resets(struct phy *phy)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_BUTTON_RST_N);
|
||||
regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_PERST_N);
|
||||
regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_POWER_UP_RST_N);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_BUTTON_RST_N);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_PERST_N);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_POWER_UP_RST_N);
|
||||
|
||||
if (lane->idx == 1) {
|
||||
regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_APB_RSTN_1);
|
||||
regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_PIPE_RSTN_1_MASK);
|
||||
} else {
|
||||
regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_APB_RSTN_0);
|
||||
regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_PIPE_RSTN_0_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_hsio_sata_phy_resets(struct phy *phy)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
/* clear PHY RST, then set it */
|
||||
regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_PHYRESET_N);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_PHYRESET_N);
|
||||
|
||||
/* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N);
|
||||
udelay(1);
|
||||
regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_RESET_N);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N);
|
||||
}
|
||||
|
||||
static void imx_hsio_configure_clk_pad(struct phy *phy)
|
||||
{
|
||||
bool pll = false;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
if (strncmp(priv->refclk_pad, "output", 6) == 0) {
|
||||
pll = true;
|
||||
regmap_update_bits(priv->misc, HSIO_CTRL0,
|
||||
HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,
|
||||
HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_2);
|
||||
} else {
|
||||
regmap_update_bits(priv->misc, HSIO_CTRL0,
|
||||
HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,
|
||||
0);
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_RXENA,
|
||||
pll ? 0 : HSIO_IOB_RXENA);
|
||||
regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_TXENA,
|
||||
pll ? HSIO_IOB_TXENA : 0);
|
||||
}
|
||||
|
||||
static void imx_hsio_pre_set(struct phy *phy)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
if (strncmp(priv->hsio_cfg, "pciea-x2-pcieb", 14) == 0) {
|
||||
regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT);
|
||||
} else if (strncmp(priv->hsio_cfg, "pciea-x2-sata", 13) == 0) {
|
||||
regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL);
|
||||
} else if (strncmp(priv->hsio_cfg, "pciea-pcieb-sata", 16) == 0) {
|
||||
regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT);
|
||||
regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL);
|
||||
}
|
||||
|
||||
imx_hsio_configure_clk_pad(phy);
|
||||
}
|
||||
|
||||
static int imx_hsio_pcie_power_on(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
u32 val, addr, cond;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
imx_hsio_pcie_phy_resets(phy);
|
||||
|
||||
/* Toggle apb_pclk to make sure PM_REQ_CORE_RST is cleared. */
|
||||
clk_disable_unprepare(lane->clks[0].clk);
|
||||
mdelay(1);
|
||||
ret = clk_prepare_enable(lane->clks[0].clk);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "unable to enable phy apb_pclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
addr = lane->ctrl_off + HSIO_PCIE_STS0;
|
||||
cond = HSIO_PM_REQ_CORE_RST;
|
||||
ret = regmap_read_poll_timeout(priv->ctrl, addr, val,
|
||||
(val & cond) == 0,
|
||||
PHY_INIT_WAIT_USLEEP_MAX,
|
||||
PHY_INIT_WAIT_TIMEOUT);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "HSIO_PM_REQ_CORE_RST is set\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx_hsio_sata_power_on(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
u32 val, cond;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, HSIO_APB_RSTN_0);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_TXDEEMP);
|
||||
regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_TXDEEMP_SEL);
|
||||
|
||||
imx_hsio_sata_phy_resets(phy);
|
||||
|
||||
cond = HSIO_REG48_PMA_RDY;
|
||||
ret = read_poll_timeout(readb, val, ((val & cond) == cond),
|
||||
PHY_INIT_WAIT_USLEEP_MAX,
|
||||
PHY_INIT_WAIT_TIMEOUT, false,
|
||||
priv->base + HSIO_REG48_PMA_STATUS);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "PHY calibration is timeout\n");
|
||||
else
|
||||
dev_dbg(priv->dev, "PHY calibration is done\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx_hsio_power_on(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
u32 val, cond;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
scoped_guard(mutex, &priv->lock) {
|
||||
if (!priv->open_cnt)
|
||||
imx_hsio_pre_set(phy);
|
||||
priv->open_cnt++;
|
||||
}
|
||||
|
||||
if (lane->phy_mode == PHY_MODE_PCIE)
|
||||
ret = imx_hsio_pcie_power_on(phy);
|
||||
else /* SATA */
|
||||
ret = imx_hsio_sata_power_on(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Polling to check the PHY is ready or not. */
|
||||
if (lane->idx == 1)
|
||||
cond = HSIO_LANE1_TX_PLL_LOCK;
|
||||
else
|
||||
/*
|
||||
* Except the phy_off, the bit-offset of lane2 is same to lane0.
|
||||
* Merge the lane0 and lane2 bit-operations together.
|
||||
*/
|
||||
cond = HSIO_LANE0_TX_PLL_LOCK;
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->phy, lane->phy_off + HSIO_PHY_STS0,
|
||||
val, ((val & cond) == cond),
|
||||
PHY_INIT_WAIT_USLEEP_MAX,
|
||||
PHY_INIT_WAIT_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "IMX8Q PHY%d PLL lock timeout\n", lane->idx);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(priv->dev, "IMX8Q PHY%d PLL is locked\n", lane->idx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx_hsio_power_off(struct phy *phy)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
scoped_guard(mutex, &priv->lock) {
|
||||
priv->open_cnt--;
|
||||
if (priv->open_cnt == 0) {
|
||||
regmap_clear_bits(priv->misc, HSIO_CTRL0,
|
||||
HSIO_PCIE_AB_SELECT);
|
||||
regmap_clear_bits(priv->misc, HSIO_CTRL0,
|
||||
HSIO_PHYX1_EPCS_SEL);
|
||||
|
||||
if (lane->phy_mode == PHY_MODE_PCIE) {
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_BUTTON_RST_N);
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_PERST_N);
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_POWER_UP_RST_N);
|
||||
} else {
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_TXDEEMP);
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_EPCS_TXDEEMP_SEL);
|
||||
regmap_clear_bits(priv->ctrl,
|
||||
lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_RESET_N);
|
||||
}
|
||||
|
||||
if (lane->idx == 1) {
|
||||
regmap_clear_bits(priv->phy,
|
||||
lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_APB_RSTN_1);
|
||||
regmap_clear_bits(priv->phy,
|
||||
lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_PIPE_RSTN_1_MASK);
|
||||
} else {
|
||||
/*
|
||||
* Except the phy_off, the bit-offset of lane2 is same
|
||||
* to lane0. Merge the lane0 and lane2 bit-operations
|
||||
* together.
|
||||
*/
|
||||
regmap_clear_bits(priv->phy,
|
||||
lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_APB_RSTN_0);
|
||||
regmap_clear_bits(priv->phy,
|
||||
lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_PIPE_RSTN_0_MASK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_hsio_set_mode(struct phy *phy, enum phy_mode mode,
|
||||
int submode)
|
||||
{
|
||||
u32 val;
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
if (lane->phy_mode != mode)
|
||||
return -EINVAL;
|
||||
|
||||
val = (mode == PHY_MODE_PCIE) ? HSIO_MODE_PCIE : HSIO_MODE_SATA;
|
||||
val = FIELD_PREP(HSIO_MODE_MASK, val);
|
||||
regmap_update_bits(priv->phy, lane->phy_off + HSIO_CTRL0,
|
||||
HSIO_MODE_MASK, val);
|
||||
|
||||
switch (submode) {
|
||||
case PHY_MODE_PCIE_RC:
|
||||
val = FIELD_PREP(HSIO_DEVICE_TYPE_MASK, PCI_EXP_TYPE_ROOT_PORT);
|
||||
break;
|
||||
case PHY_MODE_PCIE_EP:
|
||||
val = FIELD_PREP(HSIO_DEVICE_TYPE_MASK, PCI_EXP_TYPE_ENDPOINT);
|
||||
break;
|
||||
default: /* Support only PCIe EP and RC now. */
|
||||
return 0;
|
||||
}
|
||||
if (submode)
|
||||
regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0,
|
||||
HSIO_DEVICE_TYPE_MASK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_hsio_set_speed(struct phy *phy, int speed)
|
||||
{
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2,
|
||||
HSIO_LTSSM_ENABLE,
|
||||
speed ? HSIO_LTSSM_ENABLE : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops imx_hsio_ops = {
|
||||
.init = imx_hsio_init,
|
||||
.exit = imx_hsio_exit,
|
||||
.power_on = imx_hsio_power_on,
|
||||
.power_off = imx_hsio_power_off,
|
||||
.set_mode = imx_hsio_set_mode,
|
||||
.set_speed = imx_hsio_set_speed,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct imx_hsio_drvdata imx8qxp_hsio_drvdata = {
|
||||
.lane_num = 0x1,
|
||||
};
|
||||
|
||||
static const struct imx_hsio_drvdata imx8qm_hsio_drvdata = {
|
||||
.lane_num = 0x3,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx_hsio_of_match[] = {
|
||||
{.compatible = "fsl,imx8qm-hsio", .data = &imx8qm_hsio_drvdata},
|
||||
{.compatible = "fsl,imx8qxp-hsio", .data = &imx8qxp_hsio_drvdata},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_hsio_of_match);
|
||||
|
||||
static struct phy *imx_hsio_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
{
|
||||
struct imx_hsio_priv *priv = dev_get_drvdata(dev);
|
||||
int idx = args->args[0];
|
||||
int phy_type = args->args[1];
|
||||
int ctrl_index = args->args[2];
|
||||
|
||||
if (idx < 0 || idx >= priv->drvdata->lane_num)
|
||||
return ERR_PTR(-EINVAL);
|
||||
priv->lane[idx].idx = idx;
|
||||
priv->lane[idx].phy_type = phy_type;
|
||||
priv->lane[idx].ctrl_index = ctrl_index;
|
||||
|
||||
return priv->lane[idx].phy;
|
||||
}
|
||||
|
||||
static int imx_hsio_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
void __iomem *off;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct imx_hsio_priv *priv;
|
||||
struct phy_provider *provider;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
priv->dev = &pdev->dev;
|
||||
priv->drvdata = of_device_get_match_data(dev);
|
||||
|
||||
/* Get HSIO configuration mode */
|
||||
if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg))
|
||||
priv->hsio_cfg = "pciea-pcieb-sata";
|
||||
/* Get PHY refclk pad mode */
|
||||
if (of_property_read_string(np, "fsl,refclk-pad-mode",
|
||||
&priv->refclk_pad))
|
||||
priv->refclk_pad = NULL;
|
||||
|
||||
priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
off = devm_platform_ioremap_resource_byname(pdev, "phy");
|
||||
priv->phy = devm_regmap_init_mmio(dev, off, ®map_config);
|
||||
if (IS_ERR(priv->phy))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->phy),
|
||||
"unable to find phy csr registers\n");
|
||||
|
||||
off = devm_platform_ioremap_resource_byname(pdev, "ctrl");
|
||||
priv->ctrl = devm_regmap_init_mmio(dev, off, ®map_config);
|
||||
if (IS_ERR(priv->ctrl))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->ctrl),
|
||||
"unable to find ctrl csr registers\n");
|
||||
|
||||
off = devm_platform_ioremap_resource_byname(pdev, "misc");
|
||||
priv->misc = devm_regmap_init_mmio(dev, off, ®map_config);
|
||||
if (IS_ERR(priv->misc))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->misc),
|
||||
"unable to find misc csr registers\n");
|
||||
|
||||
for (i = 0; i < priv->drvdata->lane_num; i++) {
|
||||
struct imx_hsio_lane *lane = &priv->lane[i];
|
||||
struct phy *phy;
|
||||
|
||||
phy = devm_phy_create(&pdev->dev, NULL, &imx_hsio_ops);
|
||||
if (IS_ERR(phy))
|
||||
return PTR_ERR(phy);
|
||||
|
||||
lane->priv = priv;
|
||||
lane->phy = phy;
|
||||
lane->idx = i;
|
||||
phy_set_drvdata(phy, lane);
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, priv);
|
||||
dev_set_drvdata(&pdev->dev, priv);
|
||||
|
||||
provider = devm_of_phy_provider_register(&pdev->dev, imx_hsio_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(provider);
|
||||
}
|
||||
|
||||
static struct platform_driver imx_hsio_driver = {
|
||||
.probe = imx_hsio_probe,
|
||||
.driver = {
|
||||
.name = "imx8qm-hsio-phy",
|
||||
.of_match_table = imx_hsio_of_match,
|
||||
}
|
||||
};
|
||||
module_platform_driver(imx_hsio_driver);
|
||||
|
||||
MODULE_DESCRIPTION("FSL IMX8QM HSIO SERDES PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
494
drivers/phy/phy-airoha-pcie-regs.h
Normal file
494
drivers/phy/phy-airoha-pcie-regs.h
Normal file
@ -0,0 +1,494 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2024 AIROHA Inc
|
||||
* Author: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
*/
|
||||
|
||||
#ifndef _PHY_AIROHA_PCIE_H
|
||||
#define _PHY_AIROHA_PCIE_H
|
||||
|
||||
/* CSR_2L */
|
||||
#define REG_CSR_2L_CMN 0x0000
|
||||
#define CSR_2L_PXP_CMN_LANE_EN BIT(0)
|
||||
#define CSR_2L_PXP_CMN_TRIM_MASK GENMASK(28, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_IB_EXT 0x0004
|
||||
#define REG_CSR_2L_JCPLL_LPF_SHCK_EN BIT(8)
|
||||
#define CSR_2L_PXP_JCPLL_CHP_IBIAS GENMASK(21, 16)
|
||||
#define CSR_2L_PXP_JCPLL_CHP_IOFST GENMASK(29, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_LPF_BR 0x0008
|
||||
#define CSR_2L_PXP_JCPLL_LPF_BR GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_JCPLL_LPF_BC GENMASK(12, 8)
|
||||
#define CSR_2L_PXP_JCPLL_LPF_BP GENMASK(20, 16)
|
||||
#define CSR_2L_PXP_JCPLL_LPF_BWR GENMASK(28, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_LPF_BWC 0x000c
|
||||
#define CSR_2L_PXP_JCPLL_LPF_BWC GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_JCPLL_KBAND_CODE GENMASK(23, 16)
|
||||
#define CSR_2L_PXP_JCPLL_KBAND_DIV GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_KBAND_KFC 0x0010
|
||||
#define CSR_2L_PXP_JCPLL_KBAND_KFC GENMASK(1, 0)
|
||||
#define CSR_2L_PXP_JCPLL_KBAND_KF GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_JCPLL_KBAND_KS GENMASK(17, 16)
|
||||
#define CSR_2L_PXP_JCPLL_POSTDIV_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_MMD_PREDIV_MODE 0x0014
|
||||
#define CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0)
|
||||
#define CSR_2L_PXP_JCPLL_POSTDIV_D2 BIT(16)
|
||||
#define CSR_2L_PXP_JCPLL_POSTDIV_D5 BIT(24)
|
||||
|
||||
#define CSR_2L_PXP_JCPLL_MONCK 0x0018
|
||||
#define CSR_2L_PXP_JCPLL_REFIN_DIV GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_RST_DLY 0x001c
|
||||
#define CSR_2L_PXP_JCPLL_RST_DLY GENMASK(2, 0)
|
||||
#define CSR_2L_PXP_JCPLL_RST BIT(8)
|
||||
#define CSR_2L_PXP_JCPLL_SDM_DI_EN BIT(16)
|
||||
#define CSR_2L_PXP_JCPLL_SDM_DI_LS GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_SDM_IFM 0x0020
|
||||
#define CSR_2L_PXP_JCPLL_SDM_IFM BIT(0)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_SDM_HREN 0x0024
|
||||
#define CSR_2L_PXP_JCPLL_SDM_HREN BIT(0)
|
||||
#define CSR_2L_PXP_JCPLL_TCL_AMP_EN BIT(8)
|
||||
#define CSR_2L_PXP_JCPLL_TCL_AMP_GAIN GENMASK(18, 16)
|
||||
#define CSR_2L_PXP_JCPLL_TCL_AMP_VREF GENMASK(28, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_TCL_CMP 0x0028
|
||||
#define CSR_2L_PXP_JCPLL_TCL_LPF_EN BIT(16)
|
||||
#define CSR_2L_PXP_JCPLL_TCL_LPF_BW GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_VCODIV 0x002c
|
||||
#define CSR_2L_PXP_JCPLL_VCO_CFIX GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN BIT(16)
|
||||
#define CSR_2L_PXP_JCPLL_VCO_SCAPWR GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_VCO_TCLVAR 0x0030
|
||||
#define CSR_2L_PXP_JCPLL_VCO_TCLVAR GENMASK(2, 0)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_SSC 0x0038
|
||||
#define CSR_2L_PXP_JCPLL_SSC_EN BIT(0)
|
||||
#define CSR_2L_PXP_JCPLL_SSC_PHASE_INI BIT(8)
|
||||
#define CSR_2L_PXP_JCPLL_SSC_TRI_EN BIT(16)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_SSC_DELTA1 0x003c
|
||||
#define CSR_2L_PXP_JCPLL_SSC_DELTA1 GENMASK(15, 0)
|
||||
#define CSR_2L_PXP_JCPLL_SSC_DELTA GENMASK(31, 16)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_SSC_PERIOD 0x0040
|
||||
#define CSR_2L_PXP_JCPLL_SSC_PERIOD GENMASK(15, 0)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_TCL_VTP_EN 0x004c
|
||||
#define CSR_2L_PXP_JCPLL_SPARE_LOW GENMASK(31, 24)
|
||||
|
||||
#define REG_CSR_2L_JCPLL_TCL_KBAND_VREF 0x0050
|
||||
#define CSR_2L_PXP_JCPLL_TCL_KBAND_VREF GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_750M_SYS_CK 0x0054
|
||||
#define CSR_2L_PXP_TXPLL_LPF_SHCK_EN BIT(16)
|
||||
#define CSR_2L_PXP_TXPLL_CHP_IBIAS GENMASK(29, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_CHP_IOFST 0x0058
|
||||
#define CSR_2L_PXP_TXPLL_CHP_IOFST GENMASK(5, 0)
|
||||
#define CSR_2L_PXP_TXPLL_LPF_BR GENMASK(12, 8)
|
||||
#define CSR_2L_PXP_TXPLL_LPF_BC GENMASK(20, 16)
|
||||
#define CSR_2L_PXP_TXPLL_LPF_BP GENMASK(28, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_LPF_BWR 0x005c
|
||||
#define CSR_2L_PXP_TXPLL_LPF_BWR GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_TXPLL_LPF_BWC GENMASK(12, 8)
|
||||
#define CSR_2L_PXP_TXPLL_KBAND_CODE GENMASK(31, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_KBAND_DIV 0x0060
|
||||
#define CSR_2L_PXP_TXPLL_KBAND_DIV GENMASK(2, 0)
|
||||
#define CSR_2L_PXP_TXPLL_KBAND_KFC GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_TXPLL_KBAND_KF GENMASK(17, 16)
|
||||
#define CSR_2L_PXP_txpll_KBAND_KS GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_POSTDIV 0x0064
|
||||
#define CSR_2L_PXP_TXPLL_POSTDIV_EN BIT(0)
|
||||
#define CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_TXPLL_PHY_CK1_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_PHY_CK2 0x0068
|
||||
#define CSR_2L_PXP_TXPLL_REFIN_INTERNAL BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_REFIN_DIV 0x006c
|
||||
#define CSR_2L_PXP_TXPLL_REFIN_DIV GENMASK(1, 0)
|
||||
#define CSR_2L_PXP_TXPLL_RST_DLY GENMASK(10, 8)
|
||||
#define CSR_2L_PXP_TXPLL_PLL_RSTB BIT(16)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_SDM_DI_LS 0x0070
|
||||
#define CSR_2L_PXP_TXPLL_SDM_DI_LS GENMASK(1, 0)
|
||||
#define CSR_2L_PXP_TXPLL_SDM_IFM BIT(8)
|
||||
#define CSR_2L_PXP_TXPLL_SDM_ORD GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_SDM_OUT 0x0074
|
||||
#define CSR_2L_PXP_TXPLL_TCL_AMP_EN BIT(16)
|
||||
#define CSR_2L_PXP_TXPLL_TCL_AMP_GAIN GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_TCL_AMP_VREF 0x0078
|
||||
#define CSR_2L_PXP_TXPLL_TCL_AMP_VREF GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_TXPLL_TCL_LPF_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_TCL_LPF_BW 0x007c
|
||||
#define CSR_2L_PXP_TXPLL_TCL_LPF_BW GENMASK(2, 0)
|
||||
#define CSR_2L_PXP_TXPLL_VCO_CFIX GENMASK(17, 16)
|
||||
#define CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_VCO_SCAPWR 0x0080
|
||||
#define CSR_2L_PXP_TXPLL_VCO_SCAPWR GENMASK(2, 0)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_SSC 0x0084
|
||||
#define CSR_2L_PXP_TXPLL_SSC_EN BIT(0)
|
||||
#define CSR_2L_PXP_TXPLL_SSC_PHASE_INI BIT(8)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_SSC_DELTA1 0x0088
|
||||
#define CSR_2L_PXP_TXPLL_SSC_DELTA1 GENMASK(15, 0)
|
||||
#define CSR_2L_PXP_TXPLL_SSC_DELTA GENMASK(31, 16)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_SSC_PERIOD 0x008c
|
||||
#define CSR_2L_PXP_txpll_SSC_PERIOD GENMASK(15, 0)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_VTP 0x0090
|
||||
#define CSR_2L_PXP_TXPLL_VTP_EN BIT(0)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_TCL_VTP 0x0098
|
||||
#define CSR_2L_PXP_TXPLL_SPARE_L GENMASK(31, 24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_TCL_KBAND_VREF 0x009c
|
||||
#define CSR_2L_PXP_TXPLL_TCL_KBAND_VREF GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TXPLL_POSTDIV_D256 0x00a0
|
||||
#define CSR_2L_PXP_CLKTX0_AMP GENMASK(10, 8)
|
||||
#define CSR_2L_PXP_CLKTX0_OFFSET GENMASK(17, 16)
|
||||
#define CSR_2L_PXP_CLKTX0_SR GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_CLKTX0_FORCE_OUT1 0x00a4
|
||||
#define CSR_2L_PXP_CLKTX0_HZ BIT(8)
|
||||
#define CSR_2L_PXP_CLKTX0_IMP_SEL GENMASK(20, 16)
|
||||
#define CSR_2L_PXP_CLKTX1_AMP GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_CLKTX1_OFFSET 0x00a8
|
||||
#define CSR_2L_PXP_CLKTX1_OFFSET GENMASK(1, 0)
|
||||
#define CSR_2L_PXP_CLKTX1_SR GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_CLKTX1_HZ BIT(24)
|
||||
|
||||
#define REG_CSR_2L_CLKTX1_IMP_SEL 0x00ac
|
||||
#define CSR_2L_PXP_CLKTX1_IMP_SEL GENMASK(4, 0)
|
||||
|
||||
#define REG_CSR_2L_PLL_CMN_RESERVE0 0x00b0
|
||||
#define CSR_2L_PXP_PLL_RESERVE_MASK GENMASK(15, 0)
|
||||
|
||||
#define REG_CSR_2L_TX0_CKLDO 0x00cc
|
||||
#define CSR_2L_PXP_TX0_CKLDO_EN BIT(0)
|
||||
#define CSR_2L_PXP_TX0_DMEDGEGEN_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TX1_CKLDO 0x00e8
|
||||
#define CSR_2L_PXP_TX1_CKLDO_EN BIT(0)
|
||||
#define CSR_2L_PXP_TX1_DMEDGEGEN_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_TX1_MULTLANE 0x00ec
|
||||
#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 REG_CSR_2L_RX0_PHYCK_DIV 0x0100
|
||||
#define CSR_2L_PXP_RX0_PHYCK_SEL GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_RX0_PHYCK_RSTB BIT(16)
|
||||
#define CSR_2L_PXP_RX0_TDC_CK_SEL BIT(24)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV 0x0104
|
||||
#define CSR_2L_PXP_CDR0_PD_EDGE_DISABLE BIT(8)
|
||||
|
||||
#define REG_CSR_2L_CDR0_LPF_RATIO 0x0110
|
||||
#define CSR_2L_PXP_CDR0_LPF_TOP_LIM GENMASK(26, 8)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_INJ_MODE 0x011c
|
||||
#define CSR_2L_PXP_CDR0_INJ_FORCE_OFF BIT(24)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_BETA_DAC 0x0120
|
||||
#define CSR_2L_PXP_CDR0_PR_BETA_SEL GENMASK(19, 16)
|
||||
#define CSR_2L_PXP_CDR0_PR_KBAND_DIV GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_VREG_IBAND 0x0124
|
||||
#define CSR_2L_PXP_CDR0_PR_VREG_IBAND GENMASK(2, 0)
|
||||
#define CSR_2L_PXP_CDR0_PR_VREG_CKBUF GENMASK(10, 8)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_CKREF_DIV 0x0128
|
||||
#define CSR_2L_PXP_CDR0_PR_CKREF_DIV GENMASK(1, 0)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_MONCK 0x012c
|
||||
#define CSR_2L_PXP_CDR0_PR_MONCK_ENABLE BIT(0)
|
||||
#define CSR_2L_PXP_CDR0_PR_RESERVE0 GENMASK(19, 16)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_COR_HBW 0x0130
|
||||
#define CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON BIT(8)
|
||||
#define CSR_2L_PXP_CDR0_PR_CKREF_DIV1 GENMASK(17, 16)
|
||||
|
||||
#define REG_CSR_2L_CDR0_PR_MONPI 0x0134
|
||||
#define CSR_2L_PXP_CDR0_PR_XFICK_EN BIT(8)
|
||||
|
||||
#define REG_CSR_2L_RX0_SIGDET_DCTEST 0x0140
|
||||
#define CSR_2L_PXP_RX0_SIGDET_LPF_CTRL GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_RX0_SIGDET_PEAK GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_RX0_SIGDET_VTH_SEL 0x0144
|
||||
#define CSR_2L_PXP_RX0_SIGDET_VTH_SEL GENMASK(4, 0)
|
||||
#define CSR_2L_PXP_RX0_FE_VB_EQ1_EN BIT(24)
|
||||
|
||||
#define REG_CSR_2L_PXP_RX0_FE_VB_EQ2 0x0148
|
||||
#define CSR_2L_PXP_RX0_FE_VB_EQ2_EN BIT(0)
|
||||
#define CSR_2L_PXP_RX0_FE_VB_EQ3_EN BIT(8)
|
||||
#define CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB BIT(16)
|
||||
|
||||
#define REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS 0x0158
|
||||
#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS GENMASK(29, 24)
|
||||
|
||||
#define REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS 0x015c
|
||||
#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS GENMASK(5, 0)
|
||||
#define CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS GENMASK(13, 8)
|
||||
|
||||
#define REG_CSR_2L_RX1_REV0 0x01b4
|
||||
|
||||
#define REG_CSR_2L_RX1_PHYCK_DIV 0x01b8
|
||||
#define CSR_2L_PXP_RX1_PHYCK_SEL GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_RX1_PHYCK_RSTB BIT(16)
|
||||
#define CSR_2L_PXP_RX1_TDC_CK_SEL BIT(24)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV 0x01bc
|
||||
#define CSR_2L_PXP_CDR1_PD_EDGE_DISABLE BIT(8)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_BETA_DAC 0x01d8
|
||||
#define CSR_2L_PXP_CDR1_PR_BETA_SEL GENMASK(19, 16)
|
||||
#define CSR_2L_PXP_CDR1_PR_KBAND_DIV GENMASK(26, 24)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_MONCK 0x01e4
|
||||
#define CSR_2L_PXP_CDR1_PR_MONCK_ENABLE BIT(0)
|
||||
#define CSR_2L_PXP_CDR1_PR_RESERVE0 GENMASK(19, 16)
|
||||
|
||||
#define REG_CSR_2L_CDR1_LPF_RATIO 0x01c8
|
||||
#define CSR_2L_PXP_CDR1_LPF_TOP_LIM GENMASK(26, 8)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_INJ_MODE 0x01d4
|
||||
#define CSR_2L_PXP_CDR1_INJ_FORCE_OFF BIT(24)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL 0x01dc
|
||||
#define CSR_2L_PXP_CDR1_PR_VREG_IBAND GENMASK(2, 0)
|
||||
#define CSR_2L_PXP_CDR1_PR_VREG_CKBUF GENMASK(10, 8)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_CKREF_DIV 0x01e0
|
||||
#define CSR_2L_PXP_CDR1_PR_CKREF_DIV GENMASK(1, 0)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_COR_HBW 0x01e8
|
||||
#define CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON BIT(8)
|
||||
#define CSR_2L_PXP_CDR1_PR_CKREF_DIV1 GENMASK(17, 16)
|
||||
|
||||
#define REG_CSR_2L_CDR1_PR_MONPI 0x01ec
|
||||
#define CSR_2L_PXP_CDR1_PR_XFICK_EN BIT(8)
|
||||
|
||||
#define REG_CSR_2L_RX1_DAC_RANGE_EYE 0x01f4
|
||||
#define CSR_2L_PXP_RX1_SIGDET_LPF_CTRL GENMASK(25, 24)
|
||||
|
||||
#define REG_CSR_2L_RX1_SIGDET_NOVTH 0x01f8
|
||||
#define CSR_2L_PXP_RX1_SIGDET_PEAK GENMASK(9, 8)
|
||||
#define CSR_2L_PXP_RX1_SIGDET_VTH_SEL GENMASK(20, 16)
|
||||
|
||||
#define REG_CSR_2L_RX1_FE_VB_EQ1 0x0200
|
||||
#define CSR_2L_PXP_RX1_FE_VB_EQ1_EN BIT(0)
|
||||
#define CSR_2L_PXP_RX1_FE_VB_EQ2_EN BIT(8)
|
||||
#define CSR_2L_PXP_RX1_FE_VB_EQ3_EN BIT(16)
|
||||
#define CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB BIT(24)
|
||||
|
||||
#define REG_CSR_2L_RX1_OSCAL_VGA1IOS 0x0214
|
||||
#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS GENMASK(5, 0)
|
||||
#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS GENMASK(13, 8)
|
||||
#define CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS GENMASK(21, 16)
|
||||
|
||||
/* PMA */
|
||||
#define REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1 0x0004
|
||||
#define PCIE_LCPLL_MAN_PWDB BIT(0)
|
||||
|
||||
#define REG_PCIE_PMA_SEQUENCE_DISB_CTRL1 0x010c
|
||||
#define PCIE_DISB_RX_SDCAL_EN BIT(0)
|
||||
|
||||
#define REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1 0x0114
|
||||
#define PCIE_FORCE_RX_SDCAL_EN BIT(0)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_FREQ_DET1 0x014c
|
||||
#define PCIE_PLL_FT_LOCK_CYCLECNT GENMASK(15, 0)
|
||||
#define PCIE_PLL_FT_UNLOCK_CYCLECNT GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_FREQ_DET2 0x0150
|
||||
#define PCIE_LOCK_TARGET_BEG GENMASK(15, 0)
|
||||
#define PCIE_LOCK_TARGET_END GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_FREQ_DET3 0x0154
|
||||
#define PCIE_UNLOCK_TARGET_BEG GENMASK(15, 0)
|
||||
#define PCIE_UNLOCK_TARGET_END GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_FREQ_DET4 0x0158
|
||||
#define PCIE_FREQLOCK_DET_EN GENMASK(2, 0)
|
||||
#define PCIE_LOCK_LOCKTH GENMASK(11, 8)
|
||||
#define PCIE_UNLOCK_LOCKTH GENMASK(15, 12)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_CAL1 0x0160
|
||||
#define REG_PCIE_PMA_SS_RX_CAL2 0x0164
|
||||
#define PCIE_CAL_OUT_OS GENMASK(11, 8)
|
||||
|
||||
#define REG_PCIE_PMA_SS_RX_SIGDET0 0x0168
|
||||
#define PCIE_SIGDET_WIN_NONVLD_TIMES GENMASK(28, 24)
|
||||
|
||||
#define REG_PCIE_PMA_TX_RESET 0x0260
|
||||
#define PCIE_TX_TOP_RST BIT(0)
|
||||
#define PCIE_TX_CAL_RST BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_RX_FORCE_MODE0 0x0294
|
||||
#define PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0)
|
||||
|
||||
#define REG_PCIE_PMA_SS_DA_XPON_PWDB0 0x034c
|
||||
#define PCIE_DA_XPON_CDR_PR_PWDB BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_SW_RESET 0x0460
|
||||
#define PCIE_SW_RX_FIFO_RST BIT(0)
|
||||
#define PCIE_SW_RX_RST BIT(1)
|
||||
#define PCIE_SW_TX_RST BIT(2)
|
||||
#define PCIE_SW_PMA_RST BIT(3)
|
||||
#define PCIE_SW_ALLPCS_RST BIT(4)
|
||||
#define PCIE_SW_REF_RST BIT(5)
|
||||
#define PCIE_SW_TX_FIFO_RST BIT(6)
|
||||
#define PCIE_SW_XFI_TXPCS_RST BIT(7)
|
||||
#define PCIE_SW_XFI_RXPCS_RST BIT(8)
|
||||
#define PCIE_SW_XFI_RXPCS_BIST_RST BIT(9)
|
||||
#define PCIE_SW_HSG_TXPCS_RST BIT(10)
|
||||
#define PCIE_SW_HSG_RXPCS_RST BIT(11)
|
||||
#define PCIE_PMA_SW_RST (PCIE_SW_RX_FIFO_RST | \
|
||||
PCIE_SW_RX_RST | \
|
||||
PCIE_SW_TX_RST | \
|
||||
PCIE_SW_PMA_RST | \
|
||||
PCIE_SW_ALLPCS_RST | \
|
||||
PCIE_SW_REF_RST | \
|
||||
PCIE_SW_TX_FIFO_RST | \
|
||||
PCIE_SW_XFI_TXPCS_RST | \
|
||||
PCIE_SW_XFI_RXPCS_RST | \
|
||||
PCIE_SW_XFI_RXPCS_BIST_RST | \
|
||||
PCIE_SW_HSG_TXPCS_RST | \
|
||||
PCIE_SW_HSG_RXPCS_RST)
|
||||
|
||||
#define REG_PCIE_PMA_RO_RX_FREQDET 0x0530
|
||||
#define PCIE_RO_FBCK_LOCK BIT(0)
|
||||
#define PCIE_RO_FL_OUT GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC 0x0794
|
||||
#define PCIE_FORCE_DA_PXP_CDR_PR_IDAC GENMASK(10, 0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW 0x0798
|
||||
#define PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW GENMASK(30, 0)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS 0x079c
|
||||
#define PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW BIT(16)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW 0x0800
|
||||
#define PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW GENMASK(30, 0)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB 0x081c
|
||||
#define PCIE_FORCE_DA_PXP_CDR_PD_PWDB BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C 0x0820
|
||||
#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN BIT(8)
|
||||
#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB 0x0824
|
||||
#define PCIE_FORCE_DA_PXP_CDR_PR_PWDB BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT 0x0828
|
||||
#define PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN BIT(8)
|
||||
#define PCIE_FORCE_DA_PXP_JCPLL_EN BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_JCPLL_EN BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST 0x0084c
|
||||
#define PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT 0x0854
|
||||
#define PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN BIT(8)
|
||||
#define PCIE_FORCE_DA_PXP_TXPLL_EN BIT(16)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_TXPLL_EN BIT(24)
|
||||
|
||||
#define REG_PCIE_PMA_SCAN_MODE 0x0884
|
||||
#define PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_13 0x08bc
|
||||
#define PCIE_FLL_IDAC_PCIEG1 GENMASK(10, 0)
|
||||
#define PCIE_FLL_IDAC_PCIEG2 GENMASK(26, 16)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_14 0x08c0
|
||||
#define PCIE_FLL_IDAC_PCIEG3 GENMASK(10, 0)
|
||||
#define PCIE_FLL_LOAD_EN BIT(16)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL 0x088c
|
||||
#define PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL GENMASK(1, 0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_RX_FE_GAIN_CTRL BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB 0x0894
|
||||
#define PCIE_FORCE_DA_PXP_RX_FE_PWDB BIT(0)
|
||||
#define PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB BIT(8)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_12 0x08b8
|
||||
#define PCIE_FORCE_PMA_RX_SPEED GENMASK(7, 4)
|
||||
#define PCIE_FORCE_SEL_PMA_RX_SPEED BIT(7)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_17 0x08e0
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_18 0x08e4
|
||||
#define PCIE_PXP_RX_VTH_SEL_PCIE_G1 GENMASK(4, 0)
|
||||
#define PCIE_PXP_RX_VTH_SEL_PCIE_G2 GENMASK(12, 8)
|
||||
#define PCIE_PXP_RX_VTH_SEL_PCIE_G3 GENMASK(20, 16)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_19 0x08e8
|
||||
#define PCIE_PCP_RX_REV0_PCIE_GEN1 GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_20 0x08ec
|
||||
#define PCIE_PCP_RX_REV0_PCIE_GEN2 GENMASK(15, 0)
|
||||
#define PCIE_PCP_RX_REV0_PCIE_GEN3 GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_21 0x08f0
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_22 0x08f4
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_27 0x0908
|
||||
#define REG_PCIE_PMA_DIG_RESERVE_30 0x0914
|
||||
|
||||
/* DTIME */
|
||||
#define REG_PCIE_PEXTP_DIG_GLB44 0x00
|
||||
#define PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL GENMASK(7, 0)
|
||||
#define PCIE_XTP_RXDET_EN_STB_T_SEL GENMASK(15, 8)
|
||||
#define PCIE_XTP_RXDET_FINISH_STB_T_SEL GENMASK(23, 16)
|
||||
#define PCIE_XTP_TXPD_TX_DATA_EN_DLY GENMASK(27, 24)
|
||||
#define PCIE_XTP_TXPD_RXDET_DONE_CDT BIT(28)
|
||||
#define PCIE_XTP_RXDET_LATCH_STB_T_SEL GENMASK(31, 29)
|
||||
|
||||
/* RX AEQ */
|
||||
#define REG_PCIE_PEXTP_DIG_LN_RX30_P0 0x0000
|
||||
#define PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT GENMASK(7, 0)
|
||||
#define PCIE_XTP_LN_RX_PDOWN_T2RLB_DIG_EN BIT(8)
|
||||
#define PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT GENMASK(31, 16)
|
||||
|
||||
#define REG_PCIE_PEXTP_DIG_LN_RX30_P1 0x0100
|
||||
|
||||
#endif /* _PHY_AIROHA_PCIE_H */
|
1286
drivers/phy/phy-airoha-pcie.c
Normal file
1286
drivers/phy/phy-airoha-pcie.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -664,7 +664,7 @@ out_unlock:
|
||||
*
|
||||
* Returns the phy driver, after getting a refcount to it; or
|
||||
* -ENODEV if there is no such phy. The caller is responsible for
|
||||
* calling phy_put() to release that count.
|
||||
* calling of_phy_put() to release that count.
|
||||
*/
|
||||
struct phy *of_phy_get(struct device_node *np, const char *con_id)
|
||||
{
|
||||
|
@ -489,6 +489,243 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x89),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x89),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x61),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x73),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xf0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xd3),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x10),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x50),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x06),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG1, 0x10),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_PRESET_P10_PRE, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_PRESET_P10_POST, 0x58),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG4, 0x19),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x49),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x2a),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
|
||||
@ -2535,6 +2772,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 = {
|
||||
.rx2 = 0x1800,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_ipq9574 = {
|
||||
.serdes = 0,
|
||||
.pcs = 0x1000,
|
||||
.pcs_misc = 0x1400,
|
||||
.tx = 0x0200,
|
||||
.rx = 0x0400,
|
||||
.tx2 = 0x0600,
|
||||
.rx2 = 0x0800,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v5_20 = {
|
||||
.serdes = 0x1000,
|
||||
.pcs = 0x1200,
|
||||
@ -2647,6 +2894,62 @@ static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq9574_gen3x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v4x1,
|
||||
|
||||
.tbls = {
|
||||
.serdes = ipq9574_gen3x1_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_serdes_tbl),
|
||||
.tx = ipq8074_pcie_gen3_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
|
||||
.rx = ipq9574_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(ipq9574_pcie_rx_tbl),
|
||||
.pcs = ipq9574_gen3x1_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_tbl),
|
||||
.pcs_misc = ipq9574_gen3x1_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_misc_tbl),
|
||||
},
|
||||
.reset_list = ipq8074_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
|
||||
.vreg_list = NULL,
|
||||
.num_vregs = 0,
|
||||
.regs = pciephy_v4_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
.pipe_clock_rate = 250000000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_ipq9574,
|
||||
|
||||
.tbls = {
|
||||
.serdes = ipq9574_gen3x2_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_serdes_tbl),
|
||||
.tx = ipq8074_pcie_gen3_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
|
||||
.rx = ipq9574_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(ipq9574_pcie_rx_tbl),
|
||||
.pcs = ipq9574_gen3x2_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_pcs_tbl),
|
||||
.pcs_misc = ipq9574_gen3x2_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_pcs_misc_tbl),
|
||||
},
|
||||
.reset_list = ipq8074_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
|
||||
.vreg_list = NULL,
|
||||
.num_vregs = 0,
|
||||
.regs = pciephy_v5_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
.pipe_clock_rate = 250000000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
@ -3730,14 +4033,11 @@ static int phy_aux_clk_register(struct qmp_pcie *qmp, struct device_node *np)
|
||||
{
|
||||
struct clk_fixed_rate *fixed = &qmp->aux_clk_fixed;
|
||||
struct clk_init_data init = { };
|
||||
int ret;
|
||||
char name[64];
|
||||
|
||||
ret = of_property_read_string_index(np, "clock-output-names", 1, &init.name);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "%pOFn: No clock-output-names index 1\n", np);
|
||||
return ret;
|
||||
}
|
||||
snprintf(name, sizeof(name), "%s::phy_aux_clk", dev_name(qmp->dev));
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_fixed_rate_ops;
|
||||
|
||||
fixed->fixed_rate = qmp->cfg->aux_clock_rate;
|
||||
@ -4030,6 +4330,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,ipq8074-qmp-pcie-phy",
|
||||
.data = &ipq8074_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy",
|
||||
.data = &ipq9574_gen3x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy",
|
||||
.data = &ipq9574_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,msm8998-qmp-pcie-phy",
|
||||
.data = &msm8998_pciephy_cfg,
|
||||
|
@ -11,8 +11,22 @@
|
||||
#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
|
||||
#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4 0x14
|
||||
#define QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
|
||||
#define QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x44
|
||||
#define QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0x48
|
||||
#define QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x4c
|
||||
#define QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0x50
|
||||
#define QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x54
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG1 0x5c
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG2 0x60
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG4 0x68
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0x7c
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0x84
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0x88
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6 0x8c
|
||||
#define QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
|
||||
#define QPHY_V5_PCS_PCIE_EQ_CONFIG1 0xa4
|
||||
#define QPHY_V5_PCS_PCIE_EQ_CONFIG2 0xa8
|
||||
#define QPHY_V5_PCS_PCIE_PRESET_P10_PRE 0xc0
|
||||
#define QPHY_V5_PCS_PCIE_PRESET_P10_POST 0xe4
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,9 @@
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - QSERDES PLL registers */
|
||||
#define QSERDES_PLL_BG_TIMER 0x00c
|
||||
#define QSERDES_PLL_SSC_EN_CENTER 0x010
|
||||
#define QSERDES_PLL_SSC_ADJ_PER1 0x014
|
||||
#define QSERDES_PLL_SSC_ADJ_PER2 0x018
|
||||
#define QSERDES_PLL_SSC_PER1 0x01c
|
||||
#define QSERDES_PLL_SSC_PER2 0x020
|
||||
#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
|
||||
|
@ -2252,6 +2252,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sa8775p-qmp-usb3-uni-phy",
|
||||
.data = &sa8775p_usb3_uniphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sc8180x-qmp-usb3-uni-phy",
|
||||
.data = &sm8150_usb3_uniphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sc8280xp-qmp-usb3-uni-phy",
|
||||
.data = &sc8280xp_usb3_uniphy_cfg,
|
||||
|
@ -86,7 +86,9 @@ config PHY_ROCKCHIP_PCIE
|
||||
config PHY_ROCKCHIP_SAMSUNG_HDPTX
|
||||
tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
select RATIONAL
|
||||
help
|
||||
Enable this to support the Rockchip HDMI/eDP Combo PHY
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -121,7 +121,7 @@
|
||||
#define EXYNOS_5420_USB_ISOL_HOST_OFFSET 0x70C
|
||||
#define EXYNOS_5250_USB_ISOL_ENABLE BIT(0)
|
||||
|
||||
/* Mode swtich register */
|
||||
/* Mode switch register */
|
||||
#define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230
|
||||
#define EXYNOS_5250_MODE_SWITCH_MASK 1
|
||||
#define EXYNOS_5250_MODE_SWITCH_DEVICE 0
|
||||
|
@ -228,11 +228,6 @@ struct miphy28lp_dev {
|
||||
int nphys;
|
||||
};
|
||||
|
||||
struct miphy_initval {
|
||||
u16 reg;
|
||||
u16 val;
|
||||
};
|
||||
|
||||
enum miphy_sata_gen { SATA_GEN1, SATA_GEN2, SATA_GEN3 };
|
||||
|
||||
static char *PHY_TYPE_name[] = { "sata-up", "pcie-up", "", "usb3-up" };
|
||||
|
@ -15,6 +15,16 @@ config PHY_STARFIVE_JH7110_DPHY_RX
|
||||
system. If M is selected, the module will be called
|
||||
phy-jh7110-dphy-rx.ko.
|
||||
|
||||
config PHY_STARFIVE_JH7110_DPHY_TX
|
||||
tristate "StarFive JH7110 D-PHY TX Support"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
select GENERIC_PHY_MIPI_DPHY
|
||||
help
|
||||
Choose this option if you have a StarFive D-PHY TX in your
|
||||
system. If M is selected, the module will be called
|
||||
phy-jh7110-dphy-tx.ko.
|
||||
|
||||
config PHY_STARFIVE_JH7110_PCIE
|
||||
tristate "Starfive JH7110 PCIE 2.0/USB 3.0 PHY support"
|
||||
depends on HAS_IOMEM
|
||||
|
@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PHY_STARFIVE_JH7110_DPHY_RX) += phy-jh7110-dphy-rx.o
|
||||
obj-$(CONFIG_PHY_STARFIVE_JH7110_DPHY_TX) += phy-jh7110-dphy-tx.o
|
||||
obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o
|
||||
obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
|
||||
|
@ -46,11 +46,6 @@
|
||||
|
||||
#define STF_MAP_LANES_NUM 6
|
||||
|
||||
struct regval {
|
||||
u32 addr;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct stf_dphy_info {
|
||||
/**
|
||||
* @maps:
|
||||
|
461
drivers/phy/starfive/phy-jh7110-dphy-tx.c
Normal file
461
drivers/phy/starfive/phy-jh7110-dphy-tx.c
Normal file
@ -0,0 +1,461 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* DPHY TX driver for the StarFive JH7110 SoC
|
||||
*
|
||||
* Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
* Author: Keith Zhao <keith.zhao@starfivetech.com>
|
||||
* Author: Shengyang Chen <shengyang.chen@starfivetech.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/phy/phy-mipi-dphy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#define STF_DPHY_APBIFSAIF_SYSCFG(x) (x)
|
||||
|
||||
#define STF_DPHY_AON_POWER_READY_N_ACTIVE 0
|
||||
#define STF_DPHY_AON_POWER_READY_N BIT(0)
|
||||
#define STF_DPHY_CFG_L0_SWAP_SEL GENMASK(14, 12)
|
||||
#define STF_DPHY_CFG_L1_SWAP_SEL GENMASK(17, 15)
|
||||
#define STF_DPHY_CFG_L2_SWAP_SEL GENMASK(20, 18)
|
||||
#define STF_DPHY_CFG_L3_SWAP_SEL GENMASK(23, 21)
|
||||
#define STF_DPHY_CFG_L4_SWAP_SEL GENMASK(26, 24)
|
||||
#define STF_DPHY_RGS_CDTX_PLL_UNLOCK BIT(18)
|
||||
#define STF_DPHY_RG_CDTX_L0N_HSTX_RES GENMASK(23, 19)
|
||||
#define STF_DPHY_RG_CDTX_L0P_HSTX_RES GENMASK(28, 24)
|
||||
|
||||
#define STF_DPHY_RG_CDTX_L1P_HSTX_RES GENMASK(9, 5)
|
||||
#define STF_DPHY_RG_CDTX_L2N_HSTX_RES GENMASK(14, 10)
|
||||
#define STF_DPHY_RG_CDTX_L2P_HSTX_RES GENMASK(19, 15)
|
||||
#define STF_DPHY_RG_CDTX_L3N_HSTX_RES GENMASK(24, 20)
|
||||
#define STF_DPHY_RG_CDTX_L3P_HSTX_RES GENMASK(29, 25)
|
||||
|
||||
#define STF_DPHY_RG_CDTX_L4N_HSTX_RES GENMASK(4, 0)
|
||||
#define STF_DPHY_RG_CDTX_L4P_HSTX_RES GENMASK(9, 5)
|
||||
#define STF_DPHY_RG_CDTX_PLL_FBK_FRA GENMASK(23, 0)
|
||||
|
||||
#define STF_DPHY_RG_CDTX_PLL_FBK_INT GENMASK(8, 0)
|
||||
#define STF_DPHY_RG_CDTX_PLL_FM_EN BIT(9)
|
||||
#define STF_DPHY_RG_CDTX_PLL_LDO_STB_X2_EN BIT(10)
|
||||
#define STF_DPHY_RG_CDTX_PLL_PRE_DIV GENMASK(12, 11)
|
||||
|
||||
#define STF_DPHY_RG_CDTX_PLL_SSC_EN BIT(18)
|
||||
|
||||
#define STF_DPHY_RG_CLANE_HS_CLK_POST_TIME GENMASK(7, 0)
|
||||
#define STF_DPHY_RG_CLANE_HS_CLK_PRE_TIME GENMASK(15, 8)
|
||||
#define STF_DPHY_RG_CLANE_HS_PRE_TIME GENMASK(23, 16)
|
||||
#define STF_DPHY_RG_CLANE_HS_TRAIL_TIME GENMASK(31, 24)
|
||||
|
||||
#define STF_DPHY_RG_CLANE_HS_ZERO_TIME GENMASK(7, 0)
|
||||
#define STF_DPHY_RG_DLANE_HS_PRE_TIME GENMASK(15, 8)
|
||||
#define STF_DPHY_RG_DLANE_HS_TRAIL_TIME GENMASK(23, 16)
|
||||
#define STF_DPHY_RG_DLANE_HS_ZERO_TIME GENMASK(31, 24)
|
||||
|
||||
#define STF_DPHY_RG_EXTD_CYCLE_SEL GENMASK(2, 0)
|
||||
#define STF_DPHY_SCFG_C_HS_PRE_ZERO_TIME GENMASK(31, 0)
|
||||
|
||||
#define STF_DPHY_SCFG_DSI_TXREADY_ESC_SEL GENMASK(2, 1)
|
||||
#define STF_DPHY_SCFG_PPI_C_READY_SEL GENMASK(4, 3)
|
||||
|
||||
#define STF_DPHY_REFCLK_IN_SEL GENMASK(28, 26)
|
||||
#define STF_DPHY_RESETB BIT(29)
|
||||
|
||||
#define STF_DPHY_REFCLK_12M 1
|
||||
#define STF_DPHY_BITRATE_ALIGN 10000000
|
||||
|
||||
#define STF_MAP_LANES_NUM 5
|
||||
|
||||
#define STF_DPHY_LSHIFT_16(x) (FIELD_PREP(GENMASK(23, 16), (x)))
|
||||
#define STF_DPHY_LSHIFT_8(x) (FIELD_PREP(GENMASK(15, 8), (x)))
|
||||
|
||||
#define STF_DPHY_HW_DELAY_US 200
|
||||
#define STF_DPHY_HW_TIMEOUT_US 5000
|
||||
|
||||
struct stf_dphy_config {
|
||||
unsigned long bitrate;
|
||||
u32 pll_fbk_int;
|
||||
u32 pll_fbk_fra_val;
|
||||
u32 extd_cycle_sel;
|
||||
u32 dlane_hs_pre_time;
|
||||
u32 dlane_hs_zero_time;
|
||||
u32 dlane_hs_trail_time;
|
||||
u32 clane_hs_pre_time;
|
||||
u32 clane_hs_zero_time;
|
||||
u32 clane_hs_trail_time;
|
||||
u32 clane_hs_clk_pre_time;
|
||||
u32 clane_hs_clk_post_time;
|
||||
};
|
||||
|
||||
static const struct stf_dphy_config reg_configs[] = {
|
||||
{160000000, 0x6a, 0xaa, 0x3, 0xa, 0x17, 0x11, 0x5, 0x2b, 0xd, 0x7, 0x3d},
|
||||
{170000000, 0x71, 0x55, 0x3, 0xb, 0x18, 0x11, 0x5, 0x2e, 0xd, 0x7, 0x3d},
|
||||
{180000000, 0x78, 0x0, 0x3, 0xb, 0x19, 0x12, 0x6, 0x30, 0xe, 0x7, 0x3e},
|
||||
{190000000, 0x7e, 0xaa, 0x3, 0xc, 0x1a, 0x12, 0x6, 0x33, 0xe, 0x7, 0x3e},
|
||||
{200000000, 0x85, 0x55, 0x3, 0xc, 0x1b, 0x13, 0x7, 0x35, 0xf, 0x7, 0x3f},
|
||||
{320000000, 0x6a, 0xaa, 0x2, 0x8, 0x14, 0xf, 0x5, 0x2b, 0xd, 0x3, 0x23},
|
||||
{330000000, 0x6e, 0x0, 0x2, 0x8, 0x15, 0xf, 0x5, 0x2d, 0xd, 0x3, 0x23},
|
||||
{340000000, 0x71, 0x55, 0x2, 0x9, 0x15, 0xf, 0x5, 0x2e, 0xd, 0x3, 0x23},
|
||||
{350000000, 0x74, 0xaa, 0x2, 0x9, 0x15, 0x10, 0x6, 0x2f, 0xe, 0x3, 0x24},
|
||||
{360000000, 0x78, 0x0, 0x2, 0x9, 0x16, 0x10, 0x6, 0x30, 0xe, 0x3, 0x24},
|
||||
{370000000, 0x7b, 0x55, 0x2, 0x9, 0x17, 0x10, 0x6, 0x32, 0xe, 0x3, 0x24},
|
||||
{380000000, 0x7e, 0xaa, 0x2, 0xa, 0x17, 0x10, 0x6, 0x33, 0xe, 0x3, 0x24},
|
||||
{390000000, 0x82, 0x0, 0x2, 0xa, 0x17, 0x11, 0x6, 0x35, 0xf, 0x3, 0x25},
|
||||
{400000000, 0x85, 0x55, 0x2, 0xa, 0x18, 0x11, 0x7, 0x35, 0xf, 0x3, 0x25},
|
||||
{410000000, 0x88, 0xaa, 0x2, 0xa, 0x19, 0x11, 0x7, 0x37, 0xf, 0x3, 0x25},
|
||||
{420000000, 0x8c, 0x0, 0x2, 0xa, 0x19, 0x12, 0x7, 0x38, 0x10, 0x3, 0x26},
|
||||
{430000000, 0x8f, 0x55, 0x2, 0xb, 0x19, 0x12, 0x7, 0x39, 0x10, 0x3, 0x26},
|
||||
{440000000, 0x92, 0xaa, 0x2, 0xb, 0x1a, 0x12, 0x7, 0x3b, 0x10, 0x3, 0x26},
|
||||
{450000000, 0x96, 0x0, 0x2, 0xb, 0x1b, 0x12, 0x8, 0x3c, 0x10, 0x3, 0x26},
|
||||
{460000000, 0x99, 0x55, 0x2, 0xb, 0x1b, 0x13, 0x8, 0x3d, 0x11, 0x3, 0x27},
|
||||
{470000000, 0x9c, 0xaa, 0x2, 0xc, 0x1b, 0x13, 0x8, 0x3e, 0x11, 0x3, 0x27},
|
||||
{480000000, 0xa0, 0x27, 0x2, 0xc, 0x1c, 0x13, 0x8, 0x40, 0x11, 0x3, 0x27},
|
||||
{490000000, 0xa3, 0x55, 0x2, 0xc, 0x1d, 0x14, 0x8, 0x42, 0x12, 0x3, 0x28},
|
||||
{500000000, 0xa6, 0xaa, 0x2, 0xc, 0x1d, 0x14, 0x9, 0x42, 0x12, 0x3, 0x28},
|
||||
{510000000, 0xaa, 0x0, 0x2, 0xc, 0x1e, 0x14, 0x9, 0x44, 0x12, 0x3, 0x28},
|
||||
{520000000, 0xad, 0x55, 0x2, 0xd, 0x1e, 0x15, 0x9, 0x45, 0x13, 0x3, 0x29},
|
||||
{530000000, 0xb0, 0xaa, 0x2, 0xd, 0x1e, 0x15, 0x9, 0x47, 0x13, 0x3, 0x29},
|
||||
{540000000, 0xb4, 0x0, 0x2, 0xd, 0x1f, 0x15, 0x9, 0x48, 0x13, 0x3, 0x29},
|
||||
{550000000, 0xb7, 0x55, 0x2, 0xd, 0x20, 0x16, 0x9, 0x4a, 0x14, 0x3, 0x2a},
|
||||
{560000000, 0xba, 0xaa, 0x2, 0xe, 0x20, 0x16, 0xa, 0x4a, 0x14, 0x3, 0x2a},
|
||||
{570000000, 0xbe, 0x0, 0x2, 0xe, 0x20, 0x16, 0xa, 0x4c, 0x14, 0x3, 0x2a},
|
||||
{580000000, 0xc1, 0x55, 0x2, 0xe, 0x21, 0x16, 0xa, 0x4d, 0x14, 0x3, 0x2a},
|
||||
{590000000, 0xc4, 0xaa, 0x2, 0xe, 0x22, 0x17, 0xa, 0x4f, 0x15, 0x3, 0x2b},
|
||||
{600000000, 0xc8, 0x0, 0x2, 0xe, 0x23, 0x17, 0xa, 0x50, 0x15, 0x3, 0x2b},
|
||||
{610000000, 0xcb, 0x55, 0x2, 0xf, 0x22, 0x17, 0xb, 0x50, 0x15, 0x3, 0x2b},
|
||||
{620000000, 0xce, 0xaa, 0x2, 0xf, 0x23, 0x18, 0xb, 0x52, 0x16, 0x3, 0x2c},
|
||||
{630000000, 0x69, 0x0, 0x1, 0x7, 0x12, 0xd, 0x5, 0x2a, 0xc, 0x1, 0x15},
|
||||
{640000000, 0x6a, 0xaa, 0x1, 0x7, 0x13, 0xe, 0x5, 0x2b, 0xd, 0x1, 0x16},
|
||||
{650000000, 0x6c, 0x55, 0x1, 0x7, 0x13, 0xe, 0x5, 0x2c, 0xd, 0x1, 0x16},
|
||||
{660000000, 0x6e, 0x0, 0x1, 0x7, 0x13, 0xe, 0x5, 0x2d, 0xd, 0x1, 0x16},
|
||||
{670000000, 0x6f, 0xaa, 0x1, 0x8, 0x13, 0xe, 0x5, 0x2d, 0xd, 0x1, 0x16},
|
||||
{680000000, 0x71, 0x55, 0x1, 0x8, 0x13, 0xe, 0x5, 0x2e, 0xd, 0x1, 0x16},
|
||||
{690000000, 0x73, 0x0, 0x1, 0x8, 0x14, 0xe, 0x6, 0x2e, 0xd, 0x1, 0x16},
|
||||
{700000000, 0x74, 0xaa, 0x1, 0x8, 0x14, 0xf, 0x6, 0x2f, 0xe, 0x1, 0x16},
|
||||
{710000000, 0x76, 0x55, 0x1, 0x8, 0x14, 0xf, 0x6, 0x2f, 0xe, 0x1, 0x17},
|
||||
{720000000, 0x78, 0x0, 0x1, 0x8, 0x15, 0xf, 0x6, 0x30, 0xe, 0x1, 0x17},
|
||||
{730000000, 0x79, 0xaa, 0x1, 0x8, 0x15, 0xf, 0x6, 0x31, 0xe, 0x1, 0x17},
|
||||
{740000000, 0x7b, 0x55, 0x1, 0x8, 0x15, 0xf, 0x6, 0x32, 0xe, 0x1, 0x17},
|
||||
{750000000, 0x7d, 0x0, 0x1, 0x8, 0x16, 0xf, 0x6, 0x32, 0xe, 0x1, 0x17},
|
||||
{760000000, 0x7e, 0xaa, 0x1, 0x9, 0x15, 0xf, 0x6, 0x33, 0xe, 0x1, 0x17},
|
||||
{770000000, 0x80, 0x55, 0x1, 0x9, 0x15, 0x10, 0x6, 0x34, 0xf, 0x1, 0x18},
|
||||
{780000000, 0x82, 0x0, 0x1, 0x9, 0x16, 0x10, 0x6, 0x35, 0xf, 0x1, 0x18,},
|
||||
{790000000, 0x83, 0xaa, 0x1, 0x9, 0x16, 0x10, 0x7, 0x34, 0xf, 0x1, 0x18},
|
||||
{800000000, 0x85, 0x55, 0x1, 0x9, 0x17, 0x10, 0x7, 0x35, 0xf, 0x1, 0x18},
|
||||
{810000000, 0x87, 0x0, 0x1, 0x9, 0x17, 0x10, 0x7, 0x36, 0xf, 0x1, 0x18},
|
||||
{820000000, 0x88, 0xaa, 0x1, 0x9, 0x17, 0x10, 0x7, 0x37, 0xf, 0x1, 0x18},
|
||||
{830000000, 0x8a, 0x55, 0x1, 0x9, 0x18, 0x10, 0x7, 0x37, 0xf, 0x1, 0x18},
|
||||
{840000000, 0x8c, 0x0, 0x1, 0x9, 0x18, 0x11, 0x7, 0x38, 0x10, 0x1, 0x19},
|
||||
{850000000, 0x8d, 0xaa, 0x1, 0xa, 0x17, 0x11, 0x7, 0x39, 0x10, 0x1, 0x19},
|
||||
{860000000, 0x8f, 0x55, 0x1, 0xa, 0x18, 0x11, 0x7, 0x39, 0x10, 0x1, 0x19},
|
||||
{870000000, 0x91, 0x0, 0x1, 0xa, 0x18, 0x11, 0x7, 0x3a, 0x10, 0x1, 0x19},
|
||||
{880000000, 0x92, 0xaa, 0x1, 0xa, 0x18, 0x11, 0x7, 0x3b, 0x10, 0x1, 0x19},
|
||||
{890000000, 0x94, 0x55, 0x1, 0xa, 0x19, 0x11, 0x7, 0x3c, 0x10, 0x1, 0x19},
|
||||
{900000000, 0x96, 0x0, 0x1, 0xa, 0x19, 0x12, 0x8, 0x3c, 0x10, 0x1, 0x19},
|
||||
{910000000, 0x97, 0xaa, 0x1, 0xa, 0x19, 0x12, 0x8, 0x3c, 0x11, 0x1, 0x1a},
|
||||
{920000000, 0x99, 0x55, 0x1, 0xa, 0x1a, 0x12, 0x8, 0x3d, 0x11, 0x1, 0x1a},
|
||||
{930000000, 0x9b, 0x0, 0x1, 0xa, 0x1a, 0x12, 0x8, 0x3e, 0x11, 0x1, 0x1a},
|
||||
{940000000, 0x9c, 0xaa, 0x1, 0xb, 0x1a, 0x12, 0x8, 0x3e, 0x11, 0x1, 0x1a},
|
||||
{950000000, 0x9e, 0x55, 0x1, 0xb, 0x1a, 0x12, 0x8, 0x3f, 0x11, 0x1, 0x1a},
|
||||
{960000000, 0xa0, 0x0, 0x1, 0xb, 0x1a, 0x12, 0x8, 0x40, 0x11, 0x1, 0x1a},
|
||||
{970000000, 0xa1, 0xaa, 0x1, 0xb, 0x1b, 0x13, 0x8, 0x41, 0x12, 0x1, 0x1b},
|
||||
{980000000, 0xa3, 0x55, 0x1, 0xb, 0x1b, 0x13, 0x8, 0x42, 0x12, 0x1, 0x1b},
|
||||
{990000000, 0xa5, 0x0, 0x1, 0xb, 0x1b, 0x13, 0x8, 0x42, 0x12, 0x1, 0x1b},
|
||||
{1000000000, 0xa6, 0xaa, 0x1, 0xb, 0x1c, 0x13, 0x9, 0x42, 0x12, 0x1, 0x1b},
|
||||
};
|
||||
|
||||
struct stf_dphy_info {
|
||||
/**
|
||||
* @maps:
|
||||
*
|
||||
* Physical lanes and logic lanes mapping table.
|
||||
*
|
||||
* The default order is:
|
||||
* [data lane 0, data lane 1, data lane 2, date lane 3, clk lane]
|
||||
*/
|
||||
u8 maps[STF_MAP_LANES_NUM];
|
||||
};
|
||||
|
||||
struct stf_dphy {
|
||||
struct device *dev;
|
||||
void __iomem *topsys;
|
||||
struct clk *txesc_clk;
|
||||
struct reset_control *sys_rst;
|
||||
|
||||
struct phy_configure_opts_mipi_dphy config;
|
||||
|
||||
struct phy *phy;
|
||||
const struct stf_dphy_info *info;
|
||||
};
|
||||
|
||||
static u32 stf_dphy_get_config_index(u32 bitrate)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reg_configs); i++) {
|
||||
if (reg_configs[i].bitrate == bitrate)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stf_dphy_hw_reset(struct stf_dphy *dphy, int assert)
|
||||
{
|
||||
int rc;
|
||||
u32 status = 0;
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RESETB, assert),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(100));
|
||||
|
||||
if (assert) {
|
||||
rc = readl_poll_timeout_atomic(dphy->topsys +
|
||||
STF_DPHY_APBIFSAIF_SYSCFG(8),
|
||||
status,
|
||||
!(FIELD_GET(STF_DPHY_RGS_CDTX_PLL_UNLOCK, status)),
|
||||
STF_DPHY_HW_DELAY_US, STF_DPHY_HW_TIMEOUT_US);
|
||||
if (rc)
|
||||
dev_err(dphy->dev, "MIPI dphy-tx # PLL Locked\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int stf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
|
||||
{
|
||||
struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
const struct stf_dphy_info *info = dphy->info;
|
||||
const struct stf_dphy_config *p = reg_configs;
|
||||
unsigned long alignment = STF_DPHY_BITRATE_ALIGN;
|
||||
u32 bitrate = opts->mipi_dphy.hs_clk_rate;
|
||||
u32 tmp;
|
||||
u32 i;
|
||||
|
||||
if (bitrate % alignment)
|
||||
bitrate += alignment - (bitrate % alignment);
|
||||
|
||||
i = stf_dphy_get_config_index(bitrate);
|
||||
|
||||
tmp = readl(dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(100));
|
||||
tmp &= ~STF_DPHY_REFCLK_IN_SEL;
|
||||
tmp |= FIELD_PREP(STF_DPHY_REFCLK_IN_SEL, STF_DPHY_REFCLK_12M);
|
||||
writel(tmp, dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(100));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_L0N_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L0P_HSTX_RES, 0x10),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(8));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_L0N_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L2N_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L3N_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L1P_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L2P_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L3P_HSTX_RES, 0x10),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(12));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_L4N_HSTX_RES, 0x10) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_L4P_HSTX_RES, 0x10),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(16));
|
||||
|
||||
/* Lane setting */
|
||||
writel(FIELD_PREP(STF_DPHY_AON_POWER_READY_N,
|
||||
STF_DPHY_AON_POWER_READY_N_ACTIVE) |
|
||||
FIELD_PREP(STF_DPHY_CFG_L0_SWAP_SEL, info->maps[0]) |
|
||||
FIELD_PREP(STF_DPHY_CFG_L1_SWAP_SEL, info->maps[1]) |
|
||||
FIELD_PREP(STF_DPHY_CFG_L2_SWAP_SEL, info->maps[2]) |
|
||||
FIELD_PREP(STF_DPHY_CFG_L3_SWAP_SEL, info->maps[3]) |
|
||||
FIELD_PREP(STF_DPHY_CFG_L4_SWAP_SEL, info->maps[4]),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(0));
|
||||
|
||||
/* PLL setting */
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_PLL_SSC_EN, 0x0),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(28));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_PLL_LDO_STB_X2_EN, 0x1) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_PLL_FM_EN, 0x1) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_PLL_PRE_DIV, 0x0) |
|
||||
FIELD_PREP(STF_DPHY_RG_CDTX_PLL_FBK_INT, p[i].pll_fbk_int),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(24));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CDTX_PLL_FBK_FRA,
|
||||
STF_DPHY_LSHIFT_16(p[i].pll_fbk_fra_val) |
|
||||
STF_DPHY_LSHIFT_8(p[i].pll_fbk_fra_val) |
|
||||
p[i].pll_fbk_fra_val),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(20));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_EXTD_CYCLE_SEL, p[i].extd_cycle_sel),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(40));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_DLANE_HS_PRE_TIME, p[i].dlane_hs_pre_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_DLANE_HS_ZERO_TIME, p[i].dlane_hs_zero_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_DLANE_HS_TRAIL_TIME, p[i].dlane_hs_trail_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_CLANE_HS_ZERO_TIME, p[i].clane_hs_zero_time),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(36));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_RG_CLANE_HS_PRE_TIME, p[i].clane_hs_pre_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_CLANE_HS_TRAIL_TIME, p[i].clane_hs_trail_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_CLANE_HS_CLK_PRE_TIME, p[i].clane_hs_clk_pre_time) |
|
||||
FIELD_PREP(STF_DPHY_RG_CLANE_HS_CLK_POST_TIME, p[i].clane_hs_clk_post_time),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(32));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stf_dphy_init(struct phy *phy)
|
||||
{
|
||||
struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
stf_dphy_hw_reset(dphy, 1);
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_SCFG_PPI_C_READY_SEL, 0) |
|
||||
FIELD_PREP(STF_DPHY_SCFG_DSI_TXREADY_ESC_SEL, 0),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(48));
|
||||
|
||||
writel(FIELD_PREP(STF_DPHY_SCFG_C_HS_PRE_ZERO_TIME, 0x30),
|
||||
dphy->topsys + STF_DPHY_APBIFSAIF_SYSCFG(44));
|
||||
|
||||
ret = clk_prepare_enable(dphy->txesc_clk);
|
||||
if (ret) {
|
||||
dev_err(dphy->dev, "Failed to prepare/enable txesc_clk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(dphy->sys_rst);
|
||||
if (ret) {
|
||||
dev_err(dphy->dev, "Failed to deassert sys_rst\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stf_dphy_exit(struct phy *phy)
|
||||
{
|
||||
struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = reset_control_assert(dphy->sys_rst);
|
||||
if (ret) {
|
||||
dev_err(dphy->dev, "Failed to assert sys_rst\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(dphy->txesc_clk);
|
||||
|
||||
stf_dphy_hw_reset(dphy, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stf_dphy_power_on(struct phy *phy)
|
||||
{
|
||||
struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
|
||||
return pm_runtime_resume_and_get(dphy->dev);
|
||||
}
|
||||
|
||||
static int stf_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
if (mode != PHY_MODE_MIPI_DPHY)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stf_dphy_power_off(struct phy *phy)
|
||||
{
|
||||
struct stf_dphy *dphy = phy_get_drvdata(phy);
|
||||
|
||||
return pm_runtime_put_sync(dphy->dev);
|
||||
}
|
||||
|
||||
static const struct phy_ops stf_dphy_ops = {
|
||||
.power_on = stf_dphy_power_on,
|
||||
.power_off = stf_dphy_power_off,
|
||||
.init = stf_dphy_init,
|
||||
.exit = stf_dphy_exit,
|
||||
.configure = stf_dphy_configure,
|
||||
.validate = stf_dphy_validate,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int stf_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct stf_dphy *dphy;
|
||||
|
||||
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
if (!dphy)
|
||||
return -ENOMEM;
|
||||
|
||||
dphy->info = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
dphy->dev = &pdev->dev;
|
||||
dev_set_drvdata(&pdev->dev, dphy);
|
||||
|
||||
dphy->topsys = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(dphy->topsys))
|
||||
return PTR_ERR(dphy->topsys);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
dphy->txesc_clk = devm_clk_get(&pdev->dev, "txesc");
|
||||
if (IS_ERR(dphy->txesc_clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(dphy->txesc_clk),
|
||||
"Failed to get txesc clock\n");
|
||||
|
||||
dphy->sys_rst = devm_reset_control_get_exclusive(&pdev->dev, "sys");
|
||||
if (IS_ERR(dphy->sys_rst))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(dphy->sys_rst),
|
||||
"Failed to get sys reset\n");
|
||||
|
||||
dphy->phy = devm_phy_create(&pdev->dev, NULL, &stf_dphy_ops);
|
||||
if (IS_ERR(dphy->phy))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(dphy->phy),
|
||||
"Failed to create phy\n");
|
||||
|
||||
phy_set_drvdata(dphy->phy, dphy);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(phy_provider),
|
||||
"Failed to register phy\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct stf_dphy_info starfive_dphy_info = {
|
||||
.maps = {0, 1, 2, 3, 4},
|
||||
};
|
||||
|
||||
static const struct of_device_id stf_dphy_dt_ids[] = {
|
||||
{
|
||||
.compatible = "starfive,jh7110-dphy-tx",
|
||||
.data = &starfive_dphy_info,
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stf_dphy_dt_ids);
|
||||
|
||||
static struct platform_driver stf_dphy_driver = {
|
||||
.driver = {
|
||||
.name = "starfive-dphy-tx",
|
||||
.of_match_table = stf_dphy_dt_ids,
|
||||
},
|
||||
.probe = stf_dphy_probe,
|
||||
};
|
||||
module_platform_driver(stf_dphy_driver);
|
||||
|
||||
MODULE_AUTHOR("Keith Zhao <keith.zhao@starfivetech.com>");
|
||||
MODULE_AUTHOR("Shengyang Chen <shengyang.chen@starfivetech.com>");
|
||||
MODULE_DESCRIPTION("StarFive JH7110 DPHY TX driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -30,7 +30,6 @@
|
||||
#define LANE_R058 0x258
|
||||
#define LANE_R06c 0x26c
|
||||
#define LANE_R070 0x270
|
||||
#define LANE_R070 0x270
|
||||
#define LANE_R19C 0x39c
|
||||
|
||||
#define COMLANE_R004 0xa04
|
||||
|
@ -1076,27 +1076,12 @@ static int wiz_clock_register(struct wiz *wiz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
|
||||
static void wiz_clock_init(struct wiz *wiz)
|
||||
{
|
||||
const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
|
||||
struct device *dev = wiz->dev;
|
||||
struct device_node *clk_node;
|
||||
const char *node_name;
|
||||
unsigned long rate;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
clk = devm_clk_get(dev, "core_ref_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "core_ref_clk clock not found\n");
|
||||
ret = PTR_ERR(clk);
|
||||
return ret;
|
||||
}
|
||||
wiz->input_clks[WIZ_CORE_REFCLK] = clk;
|
||||
|
||||
rate = clk_get_rate(clk);
|
||||
if (rate >= 100000000)
|
||||
rate = clk_get_rate(wiz->input_clks[WIZ_CORE_REFCLK]);
|
||||
if (rate >= REF_CLK_100MHZ)
|
||||
regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
|
||||
else
|
||||
regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
|
||||
@ -1120,35 +1105,55 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
|
||||
break;
|
||||
}
|
||||
|
||||
if (wiz->data->pma_cmn_refclk1_int_mode) {
|
||||
clk = devm_clk_get(dev, "core_ref1_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "core_ref1_clk clock not found\n");
|
||||
ret = PTR_ERR(clk);
|
||||
return ret;
|
||||
}
|
||||
wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
|
||||
|
||||
rate = clk_get_rate(clk);
|
||||
if (rate >= 100000000)
|
||||
if (wiz->input_clks[WIZ_CORE_REFCLK1]) {
|
||||
rate = clk_get_rate(wiz->input_clks[WIZ_CORE_REFCLK1]);
|
||||
if (rate >= REF_CLK_100MHZ)
|
||||
regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1);
|
||||
else
|
||||
regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3);
|
||||
}
|
||||
|
||||
clk = devm_clk_get(dev, "ext_ref_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "ext_ref_clk clock not found\n");
|
||||
ret = PTR_ERR(clk);
|
||||
return ret;
|
||||
}
|
||||
wiz->input_clks[WIZ_EXT_REFCLK] = clk;
|
||||
|
||||
rate = clk_get_rate(clk);
|
||||
if (rate >= 100000000)
|
||||
rate = clk_get_rate(wiz->input_clks[WIZ_EXT_REFCLK]);
|
||||
if (rate >= REF_CLK_100MHZ)
|
||||
regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
|
||||
else
|
||||
regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
|
||||
}
|
||||
|
||||
static int wiz_clock_probe(struct wiz *wiz, struct device_node *node)
|
||||
{
|
||||
const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
|
||||
struct device *dev = wiz->dev;
|
||||
struct device_node *clk_node;
|
||||
const char *node_name;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
clk = devm_clk_get(dev, "core_ref_clk");
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"core_ref_clk clock not found\n");
|
||||
|
||||
wiz->input_clks[WIZ_CORE_REFCLK] = clk;
|
||||
|
||||
if (wiz->data->pma_cmn_refclk1_int_mode) {
|
||||
clk = devm_clk_get(dev, "core_ref1_clk");
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"core_ref1_clk clock not found\n");
|
||||
|
||||
wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
|
||||
}
|
||||
|
||||
clk = devm_clk_get(dev, "ext_ref_clk");
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"ext_ref_clk clock not found\n");
|
||||
|
||||
wiz->input_clks[WIZ_EXT_REFCLK] = clk;
|
||||
|
||||
wiz_clock_init(wiz);
|
||||
|
||||
switch (wiz->type) {
|
||||
case AM64_WIZ_10G:
|
||||
@ -1157,8 +1162,9 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
|
||||
case J721S2_WIZ_10G:
|
||||
ret = wiz_clock_register(wiz);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to register wiz clocks\n");
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret, "Failed to register wiz clocks\n");
|
||||
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1167,16 +1173,15 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
|
||||
node_name = clk_mux_sel[i].node_name;
|
||||
clk_node = of_get_child_by_name(node, node_name);
|
||||
if (!clk_node) {
|
||||
dev_err(dev, "Unable to get %s node\n", node_name);
|
||||
ret = -EINVAL;
|
||||
ret = dev_err_probe(dev, -EINVAL, "Unable to get %s node\n", node_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = wiz_mux_of_clk_register(wiz, clk_node, wiz->mux_sel_field[i],
|
||||
clk_mux_sel[i].table);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
dev_err_probe(dev, ret, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
of_node_put(clk_node);
|
||||
goto err;
|
||||
}
|
||||
@ -1188,16 +1193,15 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
|
||||
node_name = clk_div_sel[i].node_name;
|
||||
clk_node = of_get_child_by_name(node, node_name);
|
||||
if (!clk_node) {
|
||||
dev_err(dev, "Unable to get %s node\n", node_name);
|
||||
ret = -EINVAL;
|
||||
ret = dev_err_probe(dev, -EINVAL, "Unable to get %s node\n", node_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = wiz_div_clk_register(wiz, clk_node, wiz->div_sel_field[i],
|
||||
clk_div_sel[i].table);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
dev_err_probe(dev, ret, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
of_node_put(clk_node);
|
||||
goto err;
|
||||
}
|
||||
@ -1593,7 +1597,7 @@ static int wiz_probe(struct platform_device *pdev)
|
||||
goto err_get_sync;
|
||||
}
|
||||
|
||||
ret = wiz_clock_init(wiz, node);
|
||||
ret = wiz_clock_probe(wiz, node);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "Failed to initialize clocks\n");
|
||||
goto err_get_sync;
|
||||
@ -1655,12 +1659,41 @@ static void wiz_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(dev);
|
||||
}
|
||||
|
||||
static int wiz_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct wiz *wiz = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
/* Enable supplemental Control override if available */
|
||||
if (wiz->sup_legacy_clk_override)
|
||||
regmap_field_write(wiz->sup_legacy_clk_override, 1);
|
||||
|
||||
wiz_clock_init(wiz);
|
||||
|
||||
ret = wiz_init(wiz);
|
||||
if (ret) {
|
||||
dev_err(dev, "WIZ initialization failed\n");
|
||||
goto err_wiz_init;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_wiz_init:
|
||||
wiz_clock_cleanup(wiz, node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
.driver = {
|
||||
.name = "wiz",
|
||||
.of_match_table = wiz_id_table,
|
||||
.pm = pm_sleep_ptr(&wiz_pm_ops),
|
||||
},
|
||||
};
|
||||
module_platform_driver(wiz_driver);
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -80,7 +81,8 @@
|
||||
|
||||
/* Reference clock selection parameters */
|
||||
#define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4)
|
||||
#define L0_REF_CLK_SEL_MASK 0x8f
|
||||
#define L0_REF_CLK_LCL_SEL BIT(7)
|
||||
#define L0_REF_CLK_SEL_MASK 0x9f
|
||||
|
||||
/* Calibration digital logic parameters */
|
||||
#define L3_TM_CALIB_DIG19 0xec4c
|
||||
@ -122,6 +124,15 @@
|
||||
#define ICM_PROTOCOL_DP 0x4
|
||||
#define ICM_PROTOCOL_SGMII 0x5
|
||||
|
||||
static const char *const xpsgtr_icm_str[] = {
|
||||
[ICM_PROTOCOL_PD] = "none",
|
||||
[ICM_PROTOCOL_PCIE] = "PCIe",
|
||||
[ICM_PROTOCOL_SATA] = "SATA",
|
||||
[ICM_PROTOCOL_USB] = "USB",
|
||||
[ICM_PROTOCOL_DP] = "DisplayPort",
|
||||
[ICM_PROTOCOL_SGMII] = "SGMII",
|
||||
};
|
||||
|
||||
/* Test Mode common reset control parameters */
|
||||
#define TM_CMN_RST 0x10018
|
||||
#define TM_CMN_RST_EN 0x1
|
||||
@ -146,22 +157,6 @@
|
||||
/* Total number of controllers */
|
||||
#define CONTROLLERS_PER_LANE 5
|
||||
|
||||
/* Protocol Type parameters */
|
||||
#define XPSGTR_TYPE_USB0 0 /* USB controller 0 */
|
||||
#define XPSGTR_TYPE_USB1 1 /* USB controller 1 */
|
||||
#define XPSGTR_TYPE_SATA_0 2 /* SATA controller lane 0 */
|
||||
#define XPSGTR_TYPE_SATA_1 3 /* SATA controller lane 1 */
|
||||
#define XPSGTR_TYPE_PCIE_0 4 /* PCIe controller lane 0 */
|
||||
#define XPSGTR_TYPE_PCIE_1 5 /* PCIe controller lane 1 */
|
||||
#define XPSGTR_TYPE_PCIE_2 6 /* PCIe controller lane 2 */
|
||||
#define XPSGTR_TYPE_PCIE_3 7 /* PCIe controller lane 3 */
|
||||
#define XPSGTR_TYPE_DP_0 8 /* Display Port controller lane 0 */
|
||||
#define XPSGTR_TYPE_DP_1 9 /* Display Port controller lane 1 */
|
||||
#define XPSGTR_TYPE_SGMII0 10 /* Ethernet SGMII controller 0 */
|
||||
#define XPSGTR_TYPE_SGMII1 11 /* Ethernet SGMII controller 1 */
|
||||
#define XPSGTR_TYPE_SGMII2 12 /* Ethernet SGMII controller 2 */
|
||||
#define XPSGTR_TYPE_SGMII3 13 /* Ethernet SGMII controller 3 */
|
||||
|
||||
/* Timeout values */
|
||||
#define TIMEOUT_US 1000
|
||||
|
||||
@ -184,7 +179,8 @@ struct xpsgtr_ssc {
|
||||
/**
|
||||
* struct xpsgtr_phy - representation of a lane
|
||||
* @phy: pointer to the kernel PHY device
|
||||
* @type: controller which uses this lane
|
||||
* @instance: instance of the protocol type (such as the lane within a
|
||||
* protocol, or the USB/Ethernet controller)
|
||||
* @lane: lane number
|
||||
* @protocol: protocol in which the lane operates
|
||||
* @skip_phy_init: skip phy_init() if true
|
||||
@ -193,7 +189,7 @@ struct xpsgtr_ssc {
|
||||
*/
|
||||
struct xpsgtr_phy {
|
||||
struct phy *phy;
|
||||
u8 type;
|
||||
u8 instance;
|
||||
u8 lane;
|
||||
u8 protocol;
|
||||
bool skip_phy_init;
|
||||
@ -308,10 +304,30 @@ static int xpsgtr_wait_pll_lock(struct phy *phy)
|
||||
struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
|
||||
struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
|
||||
unsigned int timeout = TIMEOUT_US;
|
||||
u8 protocol = gtr_phy->protocol;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gtr_dev->dev, "Waiting for PLL lock\n");
|
||||
|
||||
/*
|
||||
* For DP and PCIe, only the instance 0 PLL is used. Switch to that phy
|
||||
* so we wait on the right PLL.
|
||||
*/
|
||||
if ((protocol == ICM_PROTOCOL_DP || protocol == ICM_PROTOCOL_PCIE) &&
|
||||
gtr_phy->instance) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_LANES; i++) {
|
||||
gtr_phy = >r_dev->phys[i];
|
||||
|
||||
if (gtr_phy->protocol == protocol && !gtr_phy->instance)
|
||||
goto got_phy;
|
||||
}
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
got_phy:
|
||||
while (1) {
|
||||
u32 reg = xpsgtr_read_phy(gtr_phy, L0_PLL_STATUS_READ_1);
|
||||
|
||||
@ -330,8 +346,8 @@ static int xpsgtr_wait_pll_lock(struct phy *phy)
|
||||
|
||||
if (ret == -ETIMEDOUT)
|
||||
dev_err(gtr_dev->dev,
|
||||
"lane %u (type %u, protocol %u): PLL lock timeout\n",
|
||||
gtr_phy->lane, gtr_phy->type, gtr_phy->protocol);
|
||||
"lane %u (protocol %u, instance %u): PLL lock timeout\n",
|
||||
gtr_phy->lane, gtr_phy->protocol, gtr_phy->instance);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -349,11 +365,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy)
|
||||
PLL_FREQ_MASK, ssc->pll_ref_clk);
|
||||
|
||||
/* Enable lane clock sharing, if required */
|
||||
if (gtr_phy->refclk != gtr_phy->lane) {
|
||||
/* Lane3 Ref Clock Selection Register */
|
||||
if (gtr_phy->refclk == gtr_phy->lane)
|
||||
xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
|
||||
L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL);
|
||||
else
|
||||
xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
|
||||
L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk);
|
||||
}
|
||||
|
||||
/* SSC step size [7:0] */
|
||||
xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB,
|
||||
@ -573,7 +590,7 @@ static int xpsgtr_phy_init(struct phy *phy)
|
||||
mutex_lock(>r_dev->gtr_mutex);
|
||||
|
||||
/* Configure and enable the clock when peripheral phy_init call */
|
||||
if (clk_prepare_enable(gtr_dev->clk[gtr_phy->lane]))
|
||||
if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk]))
|
||||
goto out;
|
||||
|
||||
/* Skip initialization if not required. */
|
||||
@ -625,7 +642,7 @@ static int xpsgtr_phy_exit(struct phy *phy)
|
||||
gtr_phy->skip_phy_init = false;
|
||||
|
||||
/* Ensure that disable clock only, which configure for lane */
|
||||
clk_disable_unprepare(gtr_dev->clk[gtr_phy->lane]);
|
||||
clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -638,16 +655,7 @@ static int xpsgtr_phy_power_on(struct phy *phy)
|
||||
/* Skip initialization if not required. */
|
||||
if (!xpsgtr_phy_init_required(gtr_phy))
|
||||
return ret;
|
||||
/*
|
||||
* Wait for the PLL to lock. For DP, only wait on DP0 to avoid
|
||||
* cumulating waits for both lanes. The user is expected to initialize
|
||||
* lane 0 last.
|
||||
*/
|
||||
if (gtr_phy->protocol != ICM_PROTOCOL_DP ||
|
||||
gtr_phy->type == XPSGTR_TYPE_DP_0)
|
||||
ret = xpsgtr_wait_pll_lock(phy);
|
||||
|
||||
return ret;
|
||||
return xpsgtr_wait_pll_lock(phy);
|
||||
}
|
||||
|
||||
static int xpsgtr_phy_configure(struct phy *phy, union phy_configure_opts *opts)
|
||||
@ -674,73 +682,33 @@ static const struct phy_ops xpsgtr_phyops = {
|
||||
* OF Xlate Support
|
||||
*/
|
||||
|
||||
/* Set the lane type and protocol based on the PHY type and instance number. */
|
||||
/* Set the lane protocol and instance based on the PHY type and instance number. */
|
||||
static int xpsgtr_set_lane_type(struct xpsgtr_phy *gtr_phy, u8 phy_type,
|
||||
unsigned int phy_instance)
|
||||
{
|
||||
unsigned int num_phy_types;
|
||||
const int *phy_types;
|
||||
|
||||
switch (phy_type) {
|
||||
case PHY_TYPE_SATA: {
|
||||
static const int types[] = {
|
||||
XPSGTR_TYPE_SATA_0,
|
||||
XPSGTR_TYPE_SATA_1,
|
||||
};
|
||||
|
||||
phy_types = types;
|
||||
num_phy_types = ARRAY_SIZE(types);
|
||||
case PHY_TYPE_SATA:
|
||||
num_phy_types = 2;
|
||||
gtr_phy->protocol = ICM_PROTOCOL_SATA;
|
||||
break;
|
||||
}
|
||||
case PHY_TYPE_USB3: {
|
||||
static const int types[] = {
|
||||
XPSGTR_TYPE_USB0,
|
||||
XPSGTR_TYPE_USB1,
|
||||
};
|
||||
|
||||
phy_types = types;
|
||||
num_phy_types = ARRAY_SIZE(types);
|
||||
case PHY_TYPE_USB3:
|
||||
num_phy_types = 2;
|
||||
gtr_phy->protocol = ICM_PROTOCOL_USB;
|
||||
break;
|
||||
}
|
||||
case PHY_TYPE_DP: {
|
||||
static const int types[] = {
|
||||
XPSGTR_TYPE_DP_0,
|
||||
XPSGTR_TYPE_DP_1,
|
||||
};
|
||||
|
||||
phy_types = types;
|
||||
num_phy_types = ARRAY_SIZE(types);
|
||||
case PHY_TYPE_DP:
|
||||
num_phy_types = 2;
|
||||
gtr_phy->protocol = ICM_PROTOCOL_DP;
|
||||
break;
|
||||
}
|
||||
case PHY_TYPE_PCIE: {
|
||||
static const int types[] = {
|
||||
XPSGTR_TYPE_PCIE_0,
|
||||
XPSGTR_TYPE_PCIE_1,
|
||||
XPSGTR_TYPE_PCIE_2,
|
||||
XPSGTR_TYPE_PCIE_3,
|
||||
};
|
||||
|
||||
phy_types = types;
|
||||
num_phy_types = ARRAY_SIZE(types);
|
||||
case PHY_TYPE_PCIE:
|
||||
num_phy_types = 4;
|
||||
gtr_phy->protocol = ICM_PROTOCOL_PCIE;
|
||||
break;
|
||||
}
|
||||
case PHY_TYPE_SGMII: {
|
||||
static const int types[] = {
|
||||
XPSGTR_TYPE_SGMII0,
|
||||
XPSGTR_TYPE_SGMII1,
|
||||
XPSGTR_TYPE_SGMII2,
|
||||
XPSGTR_TYPE_SGMII3,
|
||||
};
|
||||
|
||||
phy_types = types;
|
||||
num_phy_types = ARRAY_SIZE(types);
|
||||
case PHY_TYPE_SGMII:
|
||||
num_phy_types = 4;
|
||||
gtr_phy->protocol = ICM_PROTOCOL_SGMII;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -748,22 +716,25 @@ static int xpsgtr_set_lane_type(struct xpsgtr_phy *gtr_phy, u8 phy_type,
|
||||
if (phy_instance >= num_phy_types)
|
||||
return -EINVAL;
|
||||
|
||||
gtr_phy->type = phy_types[phy_instance];
|
||||
gtr_phy->instance = phy_instance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Valid combinations of controllers and lanes (Interconnect Matrix).
|
||||
* Valid combinations of controllers and lanes (Interconnect Matrix). Each
|
||||
* "instance" represents one controller for a lane. For PCIe and DP, the
|
||||
* "instance" is the logical lane in the link. For SATA, USB, and SGMII,
|
||||
* the instance is the index of the controller.
|
||||
*
|
||||
* This information is only used to validate the devicetree reference, and is
|
||||
* not used when programming the hardware.
|
||||
*/
|
||||
static const unsigned int icm_matrix[NUM_LANES][CONTROLLERS_PER_LANE] = {
|
||||
{ XPSGTR_TYPE_PCIE_0, XPSGTR_TYPE_SATA_0, XPSGTR_TYPE_USB0,
|
||||
XPSGTR_TYPE_DP_1, XPSGTR_TYPE_SGMII0 },
|
||||
{ XPSGTR_TYPE_PCIE_1, XPSGTR_TYPE_SATA_1, XPSGTR_TYPE_USB0,
|
||||
XPSGTR_TYPE_DP_0, XPSGTR_TYPE_SGMII1 },
|
||||
{ XPSGTR_TYPE_PCIE_2, XPSGTR_TYPE_SATA_0, XPSGTR_TYPE_USB0,
|
||||
XPSGTR_TYPE_DP_1, XPSGTR_TYPE_SGMII2 },
|
||||
{ XPSGTR_TYPE_PCIE_3, XPSGTR_TYPE_SATA_1, XPSGTR_TYPE_USB1,
|
||||
XPSGTR_TYPE_DP_0, XPSGTR_TYPE_SGMII3 }
|
||||
/* PCIe, SATA, USB, DP, SGMII */
|
||||
{ 0, 0, 0, 1, 0 }, /* Lane 0 */
|
||||
{ 1, 1, 0, 0, 1 }, /* Lane 1 */
|
||||
{ 2, 0, 0, 1, 2 }, /* Lane 2 */
|
||||
{ 3, 1, 1, 0, 3 }, /* Lane 3 */
|
||||
};
|
||||
|
||||
/* Translate OF phandle and args to PHY instance. */
|
||||
@ -798,6 +769,7 @@ static struct phy *xpsgtr_xlate(struct device *dev,
|
||||
phy_type = args->args[1];
|
||||
phy_instance = args->args[2];
|
||||
|
||||
guard(mutex)(>r_phy->phy->mutex);
|
||||
ret = xpsgtr_set_lane_type(gtr_phy, phy_type, phy_instance);
|
||||
if (ret < 0) {
|
||||
dev_err(gtr_dev->dev, "Invalid PHY type and/or instance\n");
|
||||
@ -818,13 +790,41 @@ static struct phy *xpsgtr_xlate(struct device *dev,
|
||||
* is allowed to operate on the lane.
|
||||
*/
|
||||
for (i = 0; i < CONTROLLERS_PER_LANE; i++) {
|
||||
if (icm_matrix[phy_lane][i] == gtr_phy->type)
|
||||
if (icm_matrix[phy_lane][i] == gtr_phy->instance)
|
||||
return gtr_phy->phy;
|
||||
}
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* DebugFS
|
||||
*/
|
||||
|
||||
static int xpsgtr_status_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct device *dev = seq->private;
|
||||
struct xpsgtr_phy *gtr_phy = dev_get_drvdata(dev);
|
||||
struct clk *clk;
|
||||
u32 pll_status;
|
||||
|
||||
mutex_lock(>r_phy->phy->mutex);
|
||||
pll_status = xpsgtr_read_phy(gtr_phy, L0_PLL_STATUS_READ_1);
|
||||
clk = gtr_phy->dev->clk[gtr_phy->refclk];
|
||||
|
||||
seq_printf(seq, "Lane: %u\n", gtr_phy->lane);
|
||||
seq_printf(seq, "Protocol: %s\n",
|
||||
xpsgtr_icm_str[gtr_phy->protocol]);
|
||||
seq_printf(seq, "Instance: %u\n", gtr_phy->instance);
|
||||
seq_printf(seq, "Reference clock: %u (%pC)\n", gtr_phy->refclk, clk);
|
||||
seq_printf(seq, "Reference rate: %lu\n", clk_get_rate(clk));
|
||||
seq_printf(seq, "PLL locked: %s\n",
|
||||
pll_status & PLL_STATUS_LOCKED ? "yes" : "no");
|
||||
|
||||
mutex_unlock(>r_phy->phy->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Power Management
|
||||
*/
|
||||
@ -974,6 +974,8 @@ static int xpsgtr_probe(struct platform_device *pdev)
|
||||
|
||||
gtr_phy->phy = phy;
|
||||
phy_set_drvdata(phy, gtr_phy);
|
||||
debugfs_create_devm_seqfile(&phy->dev, "status", phy->debugfs,
|
||||
xpsgtr_status_read);
|
||||
}
|
||||
|
||||
/* Register the PHY provider. */
|
||||
|
@ -660,5 +660,7 @@
|
||||
/* For Tensor GS101 */
|
||||
#define GS101_SYSIP_DAT0 (0x810)
|
||||
#define GS101_SYSTEM_CONFIGURATION (0x3A00)
|
||||
#define GS101_PHY_CTRL_USB20 (0x3EB0)
|
||||
#define GS101_PHY_CTRL_USBDP (0x3EB4)
|
||||
|
||||
#endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
|
||||
|
Loading…
Reference in New Issue
Block a user