mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 15:22:21 -04:00
Merge tag 'phy-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
Pull phy updates from Vinod Koul:
"As usual bunch of new device and driver support and updates to
existing drivers and addition of Manivannan to help with reviews.
New Support:
- Mediatek MT8196 DSI PHY support
- Renesas RZ/G3L usb2 support
- Qualcomm SM8475 QMP USB PHY and PCIe phy, IPQ9650 QMP PCIe PHY,
QUSB2 Phy for Shikra SoC, Hawi support for QMP PCIe phy and UFS
PHY. Glymur QMP PCIe Multi-PHY driver and multiple link-mode
support, ipq5210 PCIe phy support
- Spacemit USB3/PCIe comb PHY driver
Updates:
- Samsung hdptx driver improvements for modernizing the register
access and code cleanup
- Qualcomm drop duplicate v8 DP headers, improved runtime handling
for qmp drivers
- Rockchip clock lane phase tuning and 2500 Mbps support and TMDS
rate handling
- Freescale imx8mq improvements for runtime pm, pd handling"
* tag 'phy-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (76 commits)
MAINTAINERS: Add Manivannan Sadhasivam as the Reviewer for Generic PHY Framework
phy: rockchip-samsung-dcphy: fix out-of-range max_register
phy: qcom: qmp-pcie: Add QMP PCIe Multi-PHY driver
dt-bindings: phy: qcom: Add Glymur QMP PCIe multiple link-mode PHY
phy: rockchip: samsung-hdptx: Consistently use bitfield macros
phy: rockchip: samsung-hdptx: Simplify GRF access with FIELD_PREP_WM16()
phy: rockchip: samsung-hdptx: Drop restrict_rate_change handling
phy: rockchip: samsung-hdptx: Consolidate consumer_put on error path
phy: rockchip: samsung-hdptx: Drop TMDS rate setup workaround
phy: rockchip: samsung-hdptx: Handle uncommitted PHY config changes
phy: rockchip: samsung-hdptx: Fix rate recalculation for 3.2GHz FRL
phy: rockchip: samsung-hdptx: Guard against clk rate integer underflow
phy: rockchip: samsung-hdptx: Prevent divide-by-zero when computing clk rate
phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc
phy: qcom: qmp-combo: Drop qmp_v4_calibrate_dp_phy
phy: qcom: qmp-combo: Correct pre-emphasis table for QMP v4 DP PHYs
phy: renesas: rcar-gen3-usb2: Ignore missing VBUS regulator
phy: qcom: qmp-pcie: Add support for SM8475 Gen3x1 PCIe0 port
phy: qcom: qmp-pcie: Add pcs_lane1 offset to V5 offsets
dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Add SM8475 QMP PHY
...
This commit is contained in:
@@ -39,6 +39,7 @@ properties:
|
||||
- const: mediatek,mt2701-mipi-tx
|
||||
- const: mediatek,mt8173-mipi-tx
|
||||
- const: mediatek,mt8183-mipi-tx
|
||||
- const: mediatek,mt8196-mipi-tx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,glymur-qmp-gen5x8-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PCIe multiple link-mode PHY controller (PCIe, Glymur)
|
||||
|
||||
maintainers:
|
||||
- Qiang Yu <qiang.yu@oss.qualcomm.com>
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
The Glymur SoC uses a single PCIe Gen5 PHY hardware block for the
|
||||
PCIe3a/PCIe3b controllers. This block supports two link modes, selected
|
||||
at runtime via a TCSR syscon register:
|
||||
|
||||
1. x8 - a single 8-lane PHY instance is exposed (PCIe3a only)
|
||||
2. x4+x4 - two independent 4-lane PHY instances are exposed (PCIe3a and
|
||||
PCIe3b)
|
||||
|
||||
The node always describes both PHY instances ("port a" and "port b"),
|
||||
regardless of which link mode is active on the board.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-qmp-gen5x8-pcie-phy
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: port_a
|
||||
- const: port_b
|
||||
|
||||
clocks:
|
||||
maxItems: 10
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg_ahb
|
||||
- const: ref
|
||||
- const: rchng
|
||||
- const: pipe
|
||||
- const: phy_b_aux
|
||||
- const: cfg_ahb_b
|
||||
- const: rchng_b
|
||||
- const: pipe_b
|
||||
- const: pipediv2_b
|
||||
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: port_a
|
||||
- const: port_b
|
||||
|
||||
resets:
|
||||
maxItems: 4
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: port_a
|
||||
- const: port_a_nocsr
|
||||
- const: port_b
|
||||
- const: port_b_nocsr
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
vdda-refgen0p9-supply: true
|
||||
|
||||
vdda-refgen1p2-supply: true
|
||||
|
||||
qcom,link-mode:
|
||||
description:
|
||||
Reference to a register in the TCSR syscon that reports the link
|
||||
mode the PCIe PHY is currently configured for, either a single x8
|
||||
link or two independent x4 links. The link mode is programmed by
|
||||
firmware before Linux boots; this property is only used to read
|
||||
the active link mode, specified as a phandle to the syscon and
|
||||
the register offset.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle of TCSR syscon
|
||||
- description: offset of link mode register
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
- description: Name of the PHY A pipe clock output.
|
||||
- description: Name of the PHY B pipe clock output.
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description:
|
||||
The cell is the index of the sub-PHY within the active link
|
||||
mode, e.g. on Glymur, 0 for "port a" and 1 for "port b" in
|
||||
x4x4 mode, and only index 0 (the single wide PHY) is valid in
|
||||
x8 mode.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- vdda-refgen0p9-supply
|
||||
- vdda-refgen1p2-supply
|
||||
- qcom,link-mode
|
||||
- "#clock-cells"
|
||||
- clock-output-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,glymur-gcc.h>
|
||||
#include <dt-bindings/clock/qcom,glymur-tcsr.h>
|
||||
|
||||
phy@f00000 {
|
||||
compatible = "qcom,glymur-qmp-gen5x8-pcie-phy";
|
||||
reg = <0x00f00000 0x10000>, <0x00f10000 0x10000>;
|
||||
reg-names = "port_a", "port_b";
|
||||
|
||||
clocks = <&gcc GCC_PCIE_PHY_3A_AUX_CLK>,
|
||||
<&gcc GCC_PCIE_3A_CFG_AHB_CLK>,
|
||||
<&tcsr TCSR_PCIE_3_CLKREF_EN>,
|
||||
<&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>,
|
||||
<&gcc GCC_PCIE_3A_PIPE_CLK>,
|
||||
<&gcc GCC_PCIE_PHY_3B_AUX_CLK>,
|
||||
<&gcc GCC_PCIE_3B_CFG_AHB_CLK>,
|
||||
<&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>,
|
||||
<&gcc GCC_PCIE_3B_PIPE_CLK>,
|
||||
<&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>;
|
||||
clock-names = "aux", "cfg_ahb", "ref", "rchng", "pipe",
|
||||
"phy_b_aux", "cfg_ahb_b", "rchng_b", "pipe_b",
|
||||
"pipediv2_b";
|
||||
|
||||
resets = <&gcc GCC_PCIE_3A_PHY_BCR>,
|
||||
<&gcc GCC_PCIE_3A_NOCSR_COM_PHY_BCR>,
|
||||
<&gcc GCC_PCIE_3B_PHY_BCR>,
|
||||
<&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>;
|
||||
reset-names = "port_a", "port_a_nocsr", "port_b", "port_b_nocsr";
|
||||
|
||||
power-domains = <&gcc GCC_PCIE_3A_PHY_GDSC>,
|
||||
<&gcc GCC_PCIE_3B_PHY_GDSC>;
|
||||
power-domain-names = "port_a", "port_b";
|
||||
|
||||
vdda-phy-supply = <&vreg_l3c>;
|
||||
vdda-pll-supply = <&vreg_l2c>;
|
||||
|
||||
vdda-refgen0p9-supply = <&vreg_l3c>;
|
||||
vdda-refgen1p2-supply = <&vreg_l2c>;
|
||||
|
||||
qcom,link-mode = <&tcsr 0x5000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "pcie3a_pipe_clk", "pcie3b_pipe_clk";
|
||||
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
@@ -17,17 +17,21 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,ipq5210-qmp-gen3x1-pcie-phy
|
||||
- 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
|
||||
- qcom,ipq9650-qmp-gen3x1-pcie-phy
|
||||
- qcom,ipq9650-qmp-gen3x2-pcie-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,ipq5424-qmp-gen3x1-pcie-phy
|
||||
- const: qcom,ipq9574-qmp-gen3x1-pcie-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,ipq5210-qmp-gen3x2-pcie-phy
|
||||
- qcom,ipq5424-qmp-gen3x2-pcie-phy
|
||||
- const: qcom,ipq9574-qmp-gen3x2-pcie-phy
|
||||
|
||||
@@ -61,6 +65,8 @@ properties:
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
refgen-supply: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -72,6 +78,21 @@ required:
|
||||
- clock-output-names
|
||||
- "#phy-cells"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,ipq9650-qmp-gen3x1-pcie-phy
|
||||
- qcom,ipq9650-qmp-gen3x2-pcie-phy
|
||||
then:
|
||||
required:
|
||||
- refgen-supply
|
||||
else:
|
||||
properties:
|
||||
refgen-supply: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -19,6 +19,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,glymur-m31-eusb2-phy
|
||||
- qcom,hawi-m31-eusb2-phy
|
||||
- qcom,kaanapali-m31-eusb2-phy
|
||||
- const: qcom,sm8750-m31-eusb2-phy
|
||||
- const: qcom,sm8750-m31-eusb2-phy
|
||||
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qcs615-qmp-usb3-dp-phy
|
||||
- qcom,shikra-qmp-usb3-dp-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -33,12 +34,15 @@ properties:
|
||||
- const: pipe
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
reset-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: phy_phy
|
||||
- const: dp_phy
|
||||
- const: phy
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
@@ -63,6 +67,22 @@ properties:
|
||||
- description: offset of the PHY mode register
|
||||
description: Clamp and PHY mode register present in the TCSR
|
||||
|
||||
orientation-switch:
|
||||
description:
|
||||
Flag the PHY as possible handler of USB Type-C orientation switching
|
||||
type: boolean
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Output endpoint of the PHY
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Incoming endpoint from the USB controller
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -78,6 +98,33 @@ required:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,shikra-qmp-usb3-dp-phy
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 3
|
||||
reset-names:
|
||||
minItems: 3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs615-qmp-usb3-dp-phy
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
maxItems: 2
|
||||
reset-names:
|
||||
maxItems: 2
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,qcs615-gcc.h>
|
||||
|
||||
@@ -28,6 +28,7 @@ properties:
|
||||
- qcom,qcm2290-qusb2-phy
|
||||
- qcom,qcs615-qusb2-phy
|
||||
- qcom,sdm660-qusb2-phy
|
||||
- qcom,shikra-qusb2-phy
|
||||
- qcom,sm4250-qusb2-phy
|
||||
- qcom,sm6115-qusb2-phy
|
||||
- items:
|
||||
|
||||
@@ -35,6 +35,17 @@ properties:
|
||||
phy-supply:
|
||||
description:
|
||||
Phandle to a regulator that provides power to the PHY.
|
||||
deprecated: true
|
||||
|
||||
vdda-0p9-supply:
|
||||
description:
|
||||
Phandle to a 0.9V regulator supply to the PHY, which draws a peak
|
||||
current of 46 mA.
|
||||
|
||||
vdda-1p2-supply:
|
||||
description:
|
||||
Phandle to a 1.2V regulator supply to the PHY, which draws a peak
|
||||
current of 15 mA.
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
@@ -20,6 +20,8 @@ properties:
|
||||
- qcom,eliza-qmp-gen3x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,hawi-qmp-gen3x2-pcie-phy
|
||||
- qcom,hawi-qmp-gen4x1-pcie-phy
|
||||
- qcom,kaanapali-qmp-gen3x2-pcie-phy
|
||||
- qcom,qcs615-qmp-gen3x1-pcie-phy
|
||||
- qcom,qcs8300-qmp-gen4x2-pcie-phy
|
||||
@@ -43,6 +45,7 @@ properties:
|
||||
- qcom,sm8350-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8450-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8450-qmp-gen4x2-pcie-phy
|
||||
- qcom,sm8475-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8550-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8550-qmp-gen4x2-pcie-phy
|
||||
- qcom,sm8650-qmp-gen3x2-pcie-phy
|
||||
@@ -175,6 +178,7 @@ allOf:
|
||||
- qcom,sm8350-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8450-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8450-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8475-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8550-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8550-qmp-gen4x2-pcie-phy
|
||||
- qcom,sm8650-qmp-gen3x2-pcie-phy
|
||||
@@ -196,6 +200,8 @@ allOf:
|
||||
- qcom,eliza-qmp-gen3x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,hawi-qmp-gen3x2-pcie-phy
|
||||
- qcom,hawi-qmp-gen4x1-pcie-phy
|
||||
- qcom,qcs8300-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x4-pcie-phy
|
||||
@@ -223,6 +229,8 @@ allOf:
|
||||
- qcom,eliza-qmp-gen3x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,hawi-qmp-gen3x2-pcie-phy
|
||||
- qcom,hawi-qmp-gen4x1-pcie-phy
|
||||
- qcom,kaanapali-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8550-qmp-gen4x2-pcie-phy
|
||||
- qcom,sm8650-qmp-gen4x2-pcie-phy
|
||||
|
||||
@@ -38,6 +38,7 @@ properties:
|
||||
- qcom,kaanapali-qmp-ufs-phy
|
||||
- const: qcom,sm8750-qmp-ufs-phy
|
||||
- enum:
|
||||
- qcom,hawi-qmp-ufs-phy
|
||||
- qcom,milos-qmp-ufs-phy
|
||||
- qcom,msm8996-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
@@ -108,6 +109,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hawi-qmp-ufs-phy
|
||||
- qcom,milos-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sa8775p-qmp-ufs-phy
|
||||
|
||||
@@ -26,6 +26,7 @@ properties:
|
||||
- const: qcom,sm8750-qmp-usb3-dp-phy
|
||||
- enum:
|
||||
- qcom,glymur-qmp-usb3-dp-phy
|
||||
- qcom,hawi-qmp-usb3-dp-phy
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc7180-qmp-usb3-dp-phy
|
||||
- qcom,sc7280-qmp-usb3-dp-phy
|
||||
@@ -37,6 +38,7 @@ properties:
|
||||
- qcom,sm8250-qmp-usb3-dp-phy
|
||||
- qcom,sm8350-qmp-usb3-dp-phy
|
||||
- qcom,sm8450-qmp-usb3-dp-phy
|
||||
- qcom,sm8475-qmp-usb3-dp-phy
|
||||
- qcom,sm8550-qmp-usb3-dp-phy
|
||||
- qcom,sm8650-qmp-usb3-dp-phy
|
||||
- qcom,sm8750-qmp-usb3-dp-phy
|
||||
@@ -209,6 +211,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-dp-phy
|
||||
- qcom,hawi-qmp-usb3-dp-phy
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sm6350-qmp-usb3-dp-phy
|
||||
|
||||
@@ -16,6 +16,7 @@ properties:
|
||||
- enum:
|
||||
- renesas,usb2-phy-r8a77470 # RZ/G1C
|
||||
- renesas,usb2-phy-r9a08g045 # RZ/G3S
|
||||
- renesas,usb2-phy-r9a08g046 # RZ/G3L
|
||||
- renesas,usb2-phy-r9a09g057 # RZ/V2H(P)
|
||||
|
||||
- items:
|
||||
@@ -132,6 +133,7 @@ allOf:
|
||||
enum:
|
||||
- renesas,usb2-phy-r9a09g057
|
||||
- renesas,usb2-phy-r9a08g045
|
||||
- renesas,usb2-phy-r9a08g046
|
||||
- renesas,rzg2l-usb2-phy
|
||||
then:
|
||||
properties:
|
||||
|
||||
@@ -56,6 +56,16 @@ properties:
|
||||
description:
|
||||
Some additional phy settings are access through GRF regs.
|
||||
|
||||
rockchip,clk-lane-phase:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
default: 3
|
||||
description:
|
||||
Clock lane sampling phase selection (hardware tap index 0–7). Each step
|
||||
corresponds to an approximately 40 ps delay as described in the hardware
|
||||
specification.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/spacemit,k3-combo-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Spacemit K3 PCIE/USB3 Comb PHY
|
||||
|
||||
maintainers:
|
||||
- Inochi Amaoto <inochiama@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: spacemit,k3-combo-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 2
|
||||
description:
|
||||
The first one is phy id, the second one is phy type. This
|
||||
only supports types are PCIe and USB .
|
||||
|
||||
spacemit,apb-spare:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to APB SPARE system controller interface, used for
|
||||
PHY calibration.
|
||||
|
||||
spacemit,apmu:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle of APMU syscon
|
||||
- description: configuration of the PHY lanes
|
||||
description: |
|
||||
Phandle to control PHY mux configuration. The configuration
|
||||
is described as follows:
|
||||
bit 4: 0 - PCIe A x8 mode, 1 - PCIe lane share mode
|
||||
bit 3: 0 - PCIe A x4 mode, 1 - PCIe A x2 and PCIe B x2 mode
|
||||
bit 2: 0 - PCIe C lane 0 is PCIe mode , 1 - USB mode
|
||||
bit 1: 0 - PCIe C lane 1 is PCIe mode , 1 - USB mode
|
||||
bit 0: 0 - PCIe D lane is PCIe mode , 1 - USB mode
|
||||
|
||||
The bit[3:0] is only valid when bit 4 is 1.
|
||||
|
||||
This mux control does not affect the PHY for PCIe E, it is always
|
||||
in PCIe mode.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
- spacemit,apb-spare
|
||||
- spacemit,apmu
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@81d00000 {
|
||||
compatible = "spacemit,k3-combo-phy";
|
||||
reg = <0x81d00000 0x600000>;
|
||||
#phy-cells = <2>;
|
||||
spacemit,apb-spare = <&apb_spare>;
|
||||
spacemit,apmu = <&apmu 0x00>;
|
||||
};
|
||||
@@ -10979,6 +10979,7 @@ F: include/uapi/asm-generic/
|
||||
GENERIC PHY FRAMEWORK
|
||||
M: Vinod Koul <vkoul@kernel.org>
|
||||
R: Neil Armstrong <neil.armstrong@linaro.org>
|
||||
R: Manivannan Sadhasivam <mani@kernel.org>
|
||||
L: linux-phy@lists.infradead.org
|
||||
S: Supported
|
||||
Q: https://patchwork.kernel.org/project/linux-phy/list/
|
||||
@@ -29873,6 +29874,7 @@ F: drivers/edac/zynqmp_edac.c
|
||||
|
||||
XILINX ZYNQMP PSGTR PHY DRIVER
|
||||
M: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
|
||||
M: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
T: git https://github.com/Xilinx/linux-xlnx.git
|
||||
|
||||
@@ -7,6 +7,7 @@ config PHY_FSL_IMX8MQ_USB
|
||||
depends on OF && HAS_IOMEM
|
||||
depends on TYPEC || TYPEC=n
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
default ARCH_MXC && ARM64
|
||||
|
||||
config PHY_MIXEL_LVDS_PHY
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Copyright (c) 2017 NXP. */
|
||||
/* Copyright 2017-2026 NXP. */
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
@@ -9,7 +9,10 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/usb/typec_mux.h>
|
||||
|
||||
#define PHY_CTRL0 0x0
|
||||
@@ -55,6 +58,8 @@
|
||||
#define PHY_CTRL6_ALT_CLK_EN BIT(1)
|
||||
#define PHY_CTRL6_ALT_CLK_SEL BIT(0)
|
||||
|
||||
#define PHY_CRCTL 0x30
|
||||
|
||||
#define PHY_TUNE_DEFAULT 0xffffffff
|
||||
|
||||
#define TCA_CLK_RST 0x00
|
||||
@@ -118,6 +123,7 @@ struct imx8mq_usb_phy {
|
||||
void __iomem *base;
|
||||
struct regulator *vbus;
|
||||
struct tca_blk *tca;
|
||||
struct regmap *cr_regmap;
|
||||
u32 pcs_tx_swing_full;
|
||||
u32 pcs_tx_deemph_3p5db;
|
||||
u32 tx_vref_tune;
|
||||
@@ -127,6 +133,10 @@ struct imx8mq_usb_phy {
|
||||
u32 comp_dis_tune;
|
||||
};
|
||||
|
||||
struct imx8mq_usb_phy_drvdata {
|
||||
const struct phy_ops *ops;
|
||||
bool need_genpd_rpm_on;
|
||||
};
|
||||
|
||||
static void tca_blk_orientation_set(struct tca_blk *tca,
|
||||
enum typec_orientation orientation);
|
||||
@@ -136,17 +146,15 @@ static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
|
||||
struct tca_blk *tca = imx_phy->tca;
|
||||
int ret;
|
||||
|
||||
if (tca->orientation == orientation)
|
||||
return 0;
|
||||
|
||||
ret = clk_prepare_enable(imx_phy->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
PM_RUNTIME_ACQUIRE_IF_ENABLED(&imx_phy->phy->dev, pm);
|
||||
if (PM_RUNTIME_ACQUIRE_ERR(&pm))
|
||||
return -ENXIO;
|
||||
|
||||
tca_blk_orientation_set(tca, orientation);
|
||||
clk_disable_unprepare(imx_phy->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -173,9 +181,9 @@ static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device
|
||||
return sw;
|
||||
}
|
||||
|
||||
static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
|
||||
static void tca_blk_put_typec_switch(void *data)
|
||||
{
|
||||
typec_switch_unregister(sw);
|
||||
typec_switch_unregister(data);
|
||||
}
|
||||
|
||||
static void tca_blk_orientation_set(struct tca_blk *tca,
|
||||
@@ -248,6 +256,7 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct tca_blk *tca;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res)
|
||||
@@ -266,19 +275,13 @@ static struct tca_blk *imx95_usb_phy_get_tca(struct platform_device *pdev,
|
||||
tca->orientation = TYPEC_ORIENTATION_NORMAL;
|
||||
tca->sw = tca_blk_get_typec_switch(pdev, imx_phy);
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev, tca_blk_put_typec_switch, tca->sw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return tca;
|
||||
}
|
||||
|
||||
static void imx95_usb_phy_put_tca(struct imx8mq_usb_phy *imx_phy)
|
||||
{
|
||||
struct tca_blk *tca = imx_phy->tca;
|
||||
|
||||
if (!tca)
|
||||
return;
|
||||
|
||||
tca_blk_put_typec_switch(tca->sw);
|
||||
}
|
||||
|
||||
static u32 phy_tx_vref_tune_from_property(u32 percent)
|
||||
{
|
||||
percent = clamp(percent, 94U, 124U);
|
||||
@@ -625,16 +628,6 @@ static int imx8mq_phy_power_on(struct phy *phy)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(imx_phy->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(imx_phy->alt_clk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(imx_phy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable rx term override */
|
||||
value = readl(imx_phy->base + PHY_CTRL6);
|
||||
value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
|
||||
@@ -653,8 +646,6 @@ static int imx8mq_phy_power_off(struct phy *phy)
|
||||
value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL;
|
||||
writel(value, imx_phy->base + PHY_CTRL6);
|
||||
|
||||
clk_disable_unprepare(imx_phy->alt_clk);
|
||||
clk_disable_unprepare(imx_phy->clk);
|
||||
regulator_disable(imx_phy->vbus);
|
||||
|
||||
return 0;
|
||||
@@ -674,23 +665,45 @@ static const struct phy_ops imx8mp_usb_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct imx8mq_usb_phy_drvdata imx8mq_usb_phy_data = {
|
||||
.ops = &imx8mq_usb_phy_ops,
|
||||
};
|
||||
|
||||
static const struct imx8mq_usb_phy_drvdata imx8mp_usb_phy_data = {
|
||||
.ops = &imx8mp_usb_phy_ops,
|
||||
.need_genpd_rpm_on = true,
|
||||
};
|
||||
|
||||
static const struct imx8mq_usb_phy_drvdata imx95_usb_phy_data = {
|
||||
.ops = &imx8mp_usb_phy_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx8mq_usb_phy_of_match[] = {
|
||||
{.compatible = "fsl,imx8mq-usb-phy",
|
||||
.data = &imx8mq_usb_phy_ops,},
|
||||
.data = &imx8mq_usb_phy_data,},
|
||||
{.compatible = "fsl,imx8mp-usb-phy",
|
||||
.data = &imx8mp_usb_phy_ops,},
|
||||
.data = &imx8mp_usb_phy_data,},
|
||||
{.compatible = "fsl,imx95-usb-phy",
|
||||
.data = &imx8mp_usb_phy_ops,},
|
||||
.data = &imx95_usb_phy_data,},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx8mq_usb_phy_of_match);
|
||||
|
||||
static const struct regmap_config imx_cr_regmap_config = {
|
||||
.name = "cr",
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0x7,
|
||||
};
|
||||
|
||||
static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct imx8mq_usb_phy *imx_phy;
|
||||
const struct phy_ops *phy_ops;
|
||||
const struct imx8mq_usb_phy_drvdata *phy_data;
|
||||
int ret;
|
||||
|
||||
imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
|
||||
if (!imx_phy)
|
||||
@@ -698,13 +711,13 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, imx_phy);
|
||||
|
||||
imx_phy->clk = devm_clk_get(dev, "phy");
|
||||
imx_phy->clk = devm_clk_get_enabled(dev, "phy");
|
||||
if (IS_ERR(imx_phy->clk)) {
|
||||
dev_err(dev, "failed to get imx8mq usb phy clock\n");
|
||||
return PTR_ERR(imx_phy->clk);
|
||||
}
|
||||
|
||||
imx_phy->alt_clk = devm_clk_get_optional(dev, "alt");
|
||||
imx_phy->alt_clk = devm_clk_get_optional_enabled(dev, "alt");
|
||||
if (IS_ERR(imx_phy->alt_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(imx_phy->alt_clk),
|
||||
"Failed to get alt clk\n");
|
||||
@@ -713,45 +726,120 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(imx_phy->base))
|
||||
return PTR_ERR(imx_phy->base);
|
||||
|
||||
phy_ops = of_device_get_match_data(dev);
|
||||
if (!phy_ops)
|
||||
return -EINVAL;
|
||||
|
||||
imx_phy->phy = devm_phy_create(dev, NULL, phy_ops);
|
||||
if (IS_ERR(imx_phy->phy))
|
||||
return PTR_ERR(imx_phy->phy);
|
||||
imx_phy->cr_regmap = devm_regmap_init_mmio(dev, imx_phy->base + PHY_CRCTL,
|
||||
&imx_cr_regmap_config);
|
||||
if (IS_ERR(imx_phy->cr_regmap)) {
|
||||
dev_warn(dev, "Fail to init debug register regmap\n");
|
||||
imx_phy->cr_regmap = NULL;
|
||||
}
|
||||
|
||||
imx_phy->vbus = devm_regulator_get(dev, "vbus");
|
||||
if (IS_ERR(imx_phy->vbus))
|
||||
return dev_err_probe(dev, PTR_ERR(imx_phy->vbus), "failed to get vbus\n");
|
||||
|
||||
phy_data = of_device_get_match_data(dev);
|
||||
if (!phy_data)
|
||||
return -EINVAL;
|
||||
|
||||
if (phy_data->need_genpd_rpm_on) {
|
||||
ret = dev_pm_genpd_rpm_always_on(dev, true);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
dev_warn(dev, "failed to set genpd rpm always on\n");
|
||||
}
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
imx_phy->phy = devm_phy_create(dev, NULL, phy_data->ops);
|
||||
if (IS_ERR(imx_phy->phy)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(imx_phy->phy),
|
||||
"failed to create PHY\n");
|
||||
goto disable_rpm;
|
||||
}
|
||||
|
||||
phy_set_drvdata(imx_phy->phy, imx_phy);
|
||||
|
||||
imx_phy->tca = imx95_usb_phy_get_tca(pdev, imx_phy);
|
||||
if (IS_ERR(imx_phy->tca))
|
||||
return dev_err_probe(dev, PTR_ERR(imx_phy->tca),
|
||||
"failed to get tca\n");
|
||||
if (IS_ERR(imx_phy->tca)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(imx_phy->tca),
|
||||
"failed to get tca\n");
|
||||
goto disable_rpm;
|
||||
}
|
||||
|
||||
imx8m_get_phy_tuning_data(imx_phy);
|
||||
device_set_wakeup_capable(dev, true);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(phy_provider),
|
||||
"failed to register phy provider\n");
|
||||
goto disable_rpm;
|
||||
}
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
return 0;
|
||||
|
||||
disable_rpm:
|
||||
pm_runtime_disable(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void imx8mq_usb_phy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = platform_get_drvdata(pdev);
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
imx95_usb_phy_put_tca(imx_phy);
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "failed to resume on remove: %d\n", ret);
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
}
|
||||
|
||||
static int imx8mq_usb_phy_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
|
||||
|
||||
if (imx_phy->cr_regmap)
|
||||
regcache_cache_only(imx_phy->cr_regmap, true);
|
||||
|
||||
clk_disable_unprepare(imx_phy->alt_clk);
|
||||
clk_disable_unprepare(imx_phy->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx8mq_usb_phy_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(imx_phy->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(imx_phy->alt_clk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(imx_phy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (imx_phy->cr_regmap)
|
||||
regcache_cache_only(imx_phy->cr_regmap, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(imx8mq_usb_phy_pm_ops, imx8mq_usb_phy_runtime_suspend,
|
||||
imx8mq_usb_phy_runtime_resume, NULL);
|
||||
|
||||
static struct platform_driver imx8mq_usb_phy_driver = {
|
||||
.probe = imx8mq_usb_phy_probe,
|
||||
.remove = imx8mq_usb_phy_remove,
|
||||
.driver = {
|
||||
.name = "imx8mq-usb-phy",
|
||||
.of_match_table = imx8mq_usb_phy_of_match,
|
||||
.pm = pm_ptr(&imx8mq_usb_phy_pm_ops),
|
||||
.suppress_bind_attrs = true,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -387,7 +387,7 @@ static void lynx_10g_backup_pccr_val(struct lynx_lane *lane)
|
||||
*/
|
||||
static bool lynx_10g_pccr_val_enabled(u32 pccr)
|
||||
{
|
||||
return FIELD_PREP(PCCR8_SGMIIa_CFG, pccr) != 0;
|
||||
return FIELD_GET(PCCR8_SGMIIa_CFG, pccr) != 0;
|
||||
}
|
||||
|
||||
static bool lynx_10g_lane_is_3_125g(struct lynx_lane *lane)
|
||||
|
||||
@@ -679,12 +679,15 @@ static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
register_clk_failed:
|
||||
pm_runtime_disable(phy->dev);
|
||||
pm_runtime_put_noidle(phy->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
|
||||
{
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused fsl_samsung_hdmi_phy_suspend(struct device *dev)
|
||||
|
||||
@@ -21,4 +21,5 @@ obj-$(CONFIG_PHY_MTK_MIPI_CSI_0_5) += phy-mtk-mipi-csi-0-5.o
|
||||
phy-mtk-mipi-dsi-drv-y := phy-mtk-mipi-dsi.o
|
||||
phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8173.o
|
||||
phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8183.o
|
||||
phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8196.o
|
||||
obj-$(CONFIG_PHY_MTK_MIPI_DSI) += phy-mtk-mipi-dsi-drv.o
|
||||
|
||||
201
drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
Normal file
201
drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
Normal file
@@ -0,0 +1,201 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2019 MediaTek Inc.
|
||||
* Author: jitao.shi <jitao.shi@mediatek.com>
|
||||
*
|
||||
* Copyright (c) 2026 Collabora Ltd.
|
||||
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
*/
|
||||
|
||||
#include "phy-mtk-io.h"
|
||||
#include "phy-mtk-mipi-dsi.h"
|
||||
|
||||
#define MIPITX_LANE_CON 0x0004
|
||||
#define RG_DSI_CPHY_T1DRV_EN BIT(0)
|
||||
#define RG_DSI_ANA_CK_SEL BIT(1)
|
||||
#define RG_DSI_PHY_CK_SEL BIT(2)
|
||||
#define RG_DSI_CPHY_EN BIT(3)
|
||||
#define RG_DSI_PHYCK_INV_EN BIT(4)
|
||||
#define RG_DSI_PWR04_EN BIT(5)
|
||||
#define RG_DSI_BG_LPF_EN BIT(6)
|
||||
#define RG_DSI_BG_CORE_EN BIT(7)
|
||||
#define RG_DSI_PAD_TIEL_SEL BIT(8)
|
||||
|
||||
#define MIPITX_VOLTAGE_SEL 0x0008
|
||||
#define RG_DSI_HSTX_LDO_REF_SEL GENMASK(9, 6)
|
||||
#define RG_DSI_PRD_REF_SEL GENMASK(5, 0)
|
||||
#define RG_DSI_PRD_REF_MINI 0
|
||||
#define RG_DSI_PRD_REF_DEF 4
|
||||
#define RG_DSI_PRD_REF_MAX 7
|
||||
|
||||
#define MIPITX_PRESERVED 0x000c
|
||||
#define MIPITX_PRESERVED_DEF 0xffff0040
|
||||
#define MIPITX_PRESERVED_MINI 0xffff00f0
|
||||
|
||||
#define MIPITX_PLL_PWR 0x0028
|
||||
#define AD_DSI_PLL_SDM_PWR_ON BIT(0)
|
||||
#define AD_DSI_PLL_SDM_ISO_EN BIT(1)
|
||||
#define MIPITX_PLL_CON0 0x002c
|
||||
#define MIPITX_PLL_CON1 0x0030
|
||||
#define RG_DSI_PLL_EN BIT(0)
|
||||
#define RG_DSI_PLL_POSDIV GENMASK(10, 8)
|
||||
#define MIPITX_PLL_CON2 0x0034
|
||||
#define MIPITX_PLL_CON3 0x0038
|
||||
#define MIPITX_PLL_CON4 0x003c
|
||||
#define RG_DSI_PLL_IBIAS GENMASK(11, 10)
|
||||
|
||||
#define MIPITX_D2_SW_CTL_EN 0x015c
|
||||
#define MIPITX_D0_SW_CTL_EN 0x025c
|
||||
#define MIPITX_CK_CKMODE_EN 0x0320
|
||||
#define DSI_CK_CKMODE_EN BIT(0)
|
||||
#define MIPITX_CK_SW_CTL_EN 0x035c
|
||||
#define MIPITX_D1_SW_CTL_EN 0x045c
|
||||
#define MIPITX_D3_SW_CTL_EN 0x055c
|
||||
#define DSI_SW_CTL_EN BIT(0)
|
||||
|
||||
#define DSI_PHY_XTAL_CLK_HZ 26000000
|
||||
#define DSI_PHY_PLL_MIN_RATE_HZ 125000000
|
||||
#define DSI_PHY_PLL_MAX_RATE_HZ 2000000000
|
||||
|
||||
static int mtk_mipi_tx_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
|
||||
void __iomem *base = mipi_tx->regs;
|
||||
u32 voltage = RG_DSI_PRD_REF_MINI;
|
||||
u32 pres = MIPITX_PRESERVED_MINI;
|
||||
unsigned long long pcw_calc;
|
||||
unsigned int txdiv, txdiv0;
|
||||
u32 pcw;
|
||||
|
||||
dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate);
|
||||
|
||||
if (mipi_tx->data_rate >= DSI_PHY_PLL_MAX_RATE_HZ) {
|
||||
/* Select higher signaling voltage for fast data rates */
|
||||
voltage = RG_DSI_PRD_REF_DEF;
|
||||
pres = MIPITX_PRESERVED_DEF;
|
||||
txdiv = 1;
|
||||
txdiv0 = 0;
|
||||
} else if (mipi_tx->data_rate >= 1000000000) {
|
||||
txdiv = 2;
|
||||
txdiv0 = 1;
|
||||
} else if (mipi_tx->data_rate >= 500000000) {
|
||||
txdiv = 4;
|
||||
txdiv0 = 2;
|
||||
} else if (mipi_tx->data_rate > 250000000) {
|
||||
txdiv = 8;
|
||||
txdiv0 = 3;
|
||||
} else if (mipi_tx->data_rate >= 125000000) {
|
||||
txdiv = 16;
|
||||
txdiv0 = 4;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pcw_calc = ((u64)(mipi_tx->data_rate / 2) * txdiv) << 24;
|
||||
pcw_calc = div_u64(pcw_calc, DSI_PHY_XTAL_CLK_HZ);
|
||||
|
||||
if (pcw_calc > U32_MAX) {
|
||||
dev_err(mipi_tx->dev, "Calculated PCW=%llu overflow!\n", pcw_calc);
|
||||
return -EINVAL;
|
||||
}
|
||||
pcw = (u32)pcw_calc;
|
||||
|
||||
mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_PRD_REF_SEL, voltage);
|
||||
writel(pres, base + MIPITX_PRESERVED);
|
||||
|
||||
/* Enable the SDM and wait for power to stabilize */
|
||||
mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
|
||||
mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
|
||||
udelay(30);
|
||||
|
||||
/* Disable isolation and program PLL's PCW and dividers */
|
||||
mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
|
||||
writel(pcw, base + MIPITX_PLL_CON0);
|
||||
mtk_phy_update_field(base + MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, txdiv0);
|
||||
|
||||
/* Enable the PLL and wait for the clock output to stabilize */
|
||||
mtk_phy_set_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
|
||||
udelay(30);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
|
||||
void __iomem *base = mipi_tx->regs;
|
||||
|
||||
mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
|
||||
|
||||
mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
|
||||
mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
|
||||
}
|
||||
|
||||
static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
req->rate = clamp_val(req->rate,
|
||||
DSI_PHY_PLL_MIN_RATE_HZ, DSI_PHY_PLL_MAX_RATE_HZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops mtk_mipi_tx_pll_ops = {
|
||||
.enable = mtk_mipi_tx_pll_enable,
|
||||
.disable = mtk_mipi_tx_pll_disable,
|
||||
.determine_rate = mtk_mipi_tx_pll_determine_rate,
|
||||
.set_rate = mtk_mipi_tx_pll_set_rate,
|
||||
.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
|
||||
};
|
||||
|
||||
static void mtk_mipi_tx_power_on_signal(struct phy *phy)
|
||||
{
|
||||
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
|
||||
void __iomem *base = mipi_tx->regs;
|
||||
|
||||
/* BG_LPF_EN / BG_CORE_EN */
|
||||
writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON);
|
||||
/* Wait for MIPI core to enable */
|
||||
usleep_range(30, 100);
|
||||
writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, base + MIPITX_LANE_CON);
|
||||
|
||||
/* Switch OFF each Lane */
|
||||
mtk_phy_clear_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_clear_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_clear_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_clear_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_clear_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
|
||||
/*
|
||||
* The MIPI TX drive strength is in the range of 3000 ~ 6000 microamps:
|
||||
* RG_DSI_HSTX_LDO_REF_SEL expresses an offset from the minimum drive
|
||||
* strength (3000uA) and can add a maximum offset of 3000uA, reaching a
|
||||
* maximum drive strength of 3000+3000=6000uA.
|
||||
*/
|
||||
mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_HSTX_LDO_REF_SEL,
|
||||
(mipi_tx->mipitx_drive - 3000) / 200);
|
||||
|
||||
mtk_phy_set_bits(base + MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
|
||||
}
|
||||
|
||||
static void mtk_mipi_tx_power_off_signal(struct phy *phy)
|
||||
{
|
||||
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
|
||||
void __iomem *base = mipi_tx->regs;
|
||||
|
||||
/* Switch ON each lane one by one */
|
||||
mtk_phy_set_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_set_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_set_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_set_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
mtk_phy_set_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
|
||||
|
||||
writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON);
|
||||
writel(RG_DSI_PAD_TIEL_SEL, base + MIPITX_LANE_CON);
|
||||
}
|
||||
|
||||
const struct mtk_mipitx_data mt8196_mipitx_data = {
|
||||
.mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops,
|
||||
.mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal,
|
||||
.mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal,
|
||||
};
|
||||
@@ -183,6 +183,7 @@ static const struct of_device_id mtk_mipi_tx_match[] = {
|
||||
{ .compatible = "mediatek,mt2701-mipi-tx", .data = &mt2701_mipitx_data },
|
||||
{ .compatible = "mediatek,mt8173-mipi-tx", .data = &mt8173_mipitx_data },
|
||||
{ .compatible = "mediatek,mt8183-mipi-tx", .data = &mt8183_mipitx_data },
|
||||
{ .compatible = "mediatek,mt8196-mipi-tx", .data = &mt8196_mipitx_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_mipi_tx_match);
|
||||
|
||||
@@ -42,5 +42,5 @@ unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
|
||||
extern const struct mtk_mipitx_data mt2701_mipitx_data;
|
||||
extern const struct mtk_mipitx_data mt8173_mipitx_data;
|
||||
extern const struct mtk_mipitx_data mt8183_mipitx_data;
|
||||
|
||||
extern const struct mtk_mipitx_data mt8196_mipitx_data;
|
||||
#endif
|
||||
|
||||
@@ -198,7 +198,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
|
||||
|
||||
if (drvdata->flags & CAN_TRANSCEIVER_SILENT_PRESENT) {
|
||||
silent_gpio = devm_gpiod_get_index_optional(dev, "silent", i,
|
||||
GPIOD_OUT_LOW);
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(silent_gpio))
|
||||
return PTR_ERR(silent_gpio);
|
||||
can_transceiver_phy->silent_gpio = silent_gpio;
|
||||
|
||||
@@ -77,6 +77,16 @@ config PHY_QCOM_QMP_PCIE
|
||||
Enable this to support the QMP PCIe PHY transceiver that is used
|
||||
with PCIe controllers on Qualcomm chips.
|
||||
|
||||
config PHY_QCOM_QMP_PCIE_MULTIPHY
|
||||
tristate "Qualcomm QMP PCIe Multi PHY Driver"
|
||||
depends on PCI || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the QMP PCIe PHY transceiver that is used
|
||||
with PCIe controllers on Qualcomm chips. This PHY is a single
|
||||
multi-lane QMP block that can be configured either as one wide
|
||||
link or as multiple narrower independent links (bifurcation).
|
||||
|
||||
config PHY_QCOM_QMP_PCIE_8996
|
||||
tristate "Qualcomm QMP PCIe 8996 PHY Driver"
|
||||
depends on PCI || COMPILE_TEST
|
||||
|
||||
@@ -10,6 +10,7 @@ obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o
|
||||
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o phy-qcom-qmp-usbc.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_PCIE) += phy-qcom-qmp-pcie.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_PCIE_MULTIPHY) += phy-qcom-qmp-pcie-multiphy.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996) += phy-qcom-qmp-pcie-msm8996.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP_USB) += phy-qcom-qmp-usb.o
|
||||
|
||||
15
drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
Normal file
15
drivers/phy/qualcomm/phy-qcom-qmp-com-aon-v10.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_COM_AON_V10_H_
|
||||
#define QCOM_PHY_QMP_COM_AON_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - COM AON registers */
|
||||
|
||||
#define QPHY_V10_COM_AON_USB3_AON_TOGGLE_ENABLE 0x00
|
||||
#define QPHY_V10_COM_AON_DP_AON_TOGGLE_ENABLE 0x04
|
||||
#define QPHY_V10_COM_AON_DUMMY_STATUS 0x08
|
||||
|
||||
#endif
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "phy-qcom-qmp.h"
|
||||
#include "phy-qcom-qmp-pcs-aon-v6.h"
|
||||
#include "phy-qcom-qmp-pcs-aon-v8.h"
|
||||
#include "phy-qcom-qmp-pcs-aon-v10.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v3.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v4.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v5.h"
|
||||
@@ -40,6 +41,7 @@
|
||||
#include "phy-qcom-qmp-pcs-usb-v5.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v6.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v8.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v10.h"
|
||||
|
||||
#include "phy-qcom-qmp-dp-com-v3.h"
|
||||
|
||||
@@ -49,9 +51,12 @@
|
||||
#include "phy-qcom-qmp-dp-phy-v5.h"
|
||||
#include "phy-qcom-qmp-dp-phy-v6.h"
|
||||
#include "phy-qcom-qmp-dp-phy-v8.h"
|
||||
#include "phy-qcom-qmp-dp-phy-v10.h"
|
||||
|
||||
#include "phy-qcom-qmp-usb43-pcs-v8.h"
|
||||
|
||||
#include "phy-qcom-qmp-com-aon-v10.h"
|
||||
|
||||
/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
|
||||
/* DP PHY soft reset */
|
||||
#define SW_DPPHY_RESET BIT(0)
|
||||
@@ -268,6 +273,36 @@ static const unsigned int qmp_v8_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_TX_TRANSCEIVER_BIAS_EN,
|
||||
};
|
||||
|
||||
static const unsigned int qmp_v10_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = QPHY_V10_PCS_SW_RESET,
|
||||
[QPHY_START_CTRL] = QPHY_V10_PCS_START_CONTROL,
|
||||
[QPHY_PCS_STATUS] = QPHY_V10_PCS_PCS_STATUS1,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_PCS_POWER_DOWN_CONTROL,
|
||||
|
||||
/* In PCS_USB */
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V10_PCS_USB3_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V10_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V10_PCS_AON_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_AON_TOGGLE_ENABLE] = QPHY_V10_COM_AON_USB3_AON_TOGGLE_ENABLE,
|
||||
[QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V10_COM_AON_DP_AON_TOGGLE_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V10_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V10_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V10_COM_CMN_STATUS,
|
||||
[QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V10_COM_BIAS_EN_CLKBUFLR_EN,
|
||||
|
||||
[QPHY_DP_PHY_STATUS] = QSERDES_V10_DP_PHY_STATUS,
|
||||
[QPHY_DP_PHY_VCO_DIV] = QSERDES_V10_DP_PHY_VCO_DIV,
|
||||
|
||||
[QPHY_TX_TX_POL_INV] = QSERDES_V10_TX_TX_POL_INV,
|
||||
[QPHY_TX_TX_DRV_LVL] = QSERDES_V10_TX_TX_DRV_LVL,
|
||||
[QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V10_TX_TX_EMP_POST1_LVL,
|
||||
[QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V10_TX_HIGHZ_DRVR_EN,
|
||||
[QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V10_TX_TRANSCEIVER_BIAS_EN,
|
||||
};
|
||||
|
||||
static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = QPHY_V8_USB43_PCS_SW_RESET,
|
||||
[QPHY_START_CTRL] = QPHY_V8_USB43_PCS_START_CONTROL,
|
||||
@@ -1063,6 +1098,55 @@ static const struct qmp_phy_init_tbl sm8350_usb3_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8475_usb3_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_PI_CONTROLS, 0x99),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_GAIN1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_GAIN2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL1, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CNTRL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xdf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xfe),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xdc),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_EN_TIMER, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_DCC_CTRL1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_VTH_CODE, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_CTRL1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8475_usb3_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8550_usb3_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
@@ -1337,6 +1421,29 @@ static const struct qmp_phy_init_tbl qmp_v5_5nm_dp_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_5NM_TX_TX_BAND, 0x01),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_v1_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x3b),
|
||||
@@ -1471,6 +1578,54 @@ static const struct qmp_phy_init_tbl qmp_v8_n3p_dp_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_v1_serdes_tbl_rbr[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x69),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x6f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xe2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_v1_serdes_tbl_hbr[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x69),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xe2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_v1_serdes_tbl_hbr2[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x8c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x2e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x21),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_v1_serdes_tbl_hbr3[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x69),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x2a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xe2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34),
|
||||
@@ -2058,6 +2213,141 @@ static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_usb3_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MSB_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE1, 0x75),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE1_MODE1, 0x25),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE2_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CORE_CLK_DIV_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE0, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE0, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MSB_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE0, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE0, 0x75),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE1_MODE0, 0x25),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_BUF_ENABLE, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_EN_SEL, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP_CFG, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORE_CLK_EN, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_ADDITIONAL_MISC, 0x0c),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_usb3_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_TX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_RX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_1, 0xe5),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_3, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_4, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_5, 0x5d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RCV_DETECT_LVL_2, 0x12),
|
||||
QMP_PHY_INIT_CFG_LANE(QSERDES_V10_TX_PI_QEC_CTRL, 0x21, 1),
|
||||
QMP_PHY_INIT_CFG_LANE(QSERDES_V10_TX_PI_QEC_CTRL, 0x05, 2),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_usb3_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FO_GAIN, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_GAIN, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_PI_CONTROLS, 0x99),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_GAIN1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_GAIN2, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_AUX_DATA_TCOARSE_TFINE, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL1, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_GM_CAL, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_ENABLES, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CNTRL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_LOW, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH3, 0xdf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH4, 0xed),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_LOW, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH2, 0x91),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH3, 0xb7),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH4, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_EN_TIMER, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_DCC_CTRL1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_VTH_CODE, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_CTRL1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_TRIM, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_usb3_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG1, 0xc4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG2, 0x89),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG3, 0x20),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_LOCK_DETECT_CONFIG6, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_REFGEN_REQ_CONFIG1, 0x21),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_SIGDET_LVL, 0x55),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_CONFIG, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_ALIGN_DETECT_CONFIG1, 0x88),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_ALIGN_DETECT_CONFIG2, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG1, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG5, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_usb3_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00),
|
||||
};
|
||||
|
||||
/* list of regulators */
|
||||
static struct regulator_bulk_data qmp_phy_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 21800, },
|
||||
@@ -2108,7 +2398,7 @@ static const u8 qmp_dp_v4_pre_emphasis_hbr3_hbr2[4][4] = {
|
||||
static const u8 qmp_dp_v4_pre_emphasis_hbr_rbr[4][4] = {
|
||||
{ 0x00, 0x0d, 0x14, 0x1a },
|
||||
{ 0x00, 0x0e, 0x15, 0xff },
|
||||
{ 0x00, 0x0d, 0xff, 0xff },
|
||||
{ 0x00, 0x0e, 0xff, 0xff },
|
||||
{ 0x03, 0xff, 0xff, 0xff }
|
||||
};
|
||||
|
||||
@@ -2198,6 +2488,7 @@ struct qmp_combo_offsets {
|
||||
u16 dp_txa;
|
||||
u16 dp_txb;
|
||||
u16 dp_dp_phy;
|
||||
u16 aon_toggle;
|
||||
};
|
||||
|
||||
struct qmp_phy_cfg {
|
||||
@@ -2270,6 +2561,7 @@ struct qmp_combo {
|
||||
const struct qmp_phy_cfg *cfg;
|
||||
|
||||
void __iomem *com;
|
||||
void __iomem *aon_toggle;
|
||||
|
||||
void __iomem *serdes;
|
||||
void __iomem *tx;
|
||||
@@ -2325,7 +2617,6 @@ static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp);
|
||||
static void qmp_v4_dp_aux_init(struct qmp_combo *qmp);
|
||||
static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp);
|
||||
static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp);
|
||||
static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp);
|
||||
|
||||
static void qmp_v8_dp_aux_init(struct qmp_combo *qmp);
|
||||
static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp);
|
||||
@@ -2416,6 +2707,24 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = {
|
||||
.dp_dp_phy = 0x3c00,
|
||||
};
|
||||
|
||||
static const struct qmp_combo_offsets qmp_combo_offsets_v10 = {
|
||||
.com = 0x0000,
|
||||
.aon_toggle = 0x0400,
|
||||
.txa = 0x1400,
|
||||
.rxa = 0x1600,
|
||||
.txb = 0x1800,
|
||||
.rxb = 0x1a00,
|
||||
.usb3_serdes = 0x1000,
|
||||
.usb3_pcs_misc = 0x1c00,
|
||||
.usb3_pcs = 0x1e00,
|
||||
.usb3_pcs_aon = 0x2000,
|
||||
.usb3_pcs_usb = 0x2100,
|
||||
.dp_serdes = 0x3000,
|
||||
.dp_txa = 0x3400,
|
||||
.dp_txb = 0x3800,
|
||||
.dp_dp_phy = 0x3c00,
|
||||
};
|
||||
|
||||
static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = {
|
||||
.com = 0x0000,
|
||||
.usb3_pcs_aon = 0x0100,
|
||||
@@ -2466,7 +2775,6 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.regs = qmp_v6_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
@@ -2603,7 +2911,6 @@ static const struct qmp_phy_cfg sc8180x_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
@@ -2650,7 +2957,6 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
@@ -2696,7 +3002,6 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
@@ -2705,6 +3010,27 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = {
|
||||
.regs = qmp_v6_n4_usb3phy_regs_layout,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg hawi_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_offsets_v10,
|
||||
|
||||
.serdes_tbl = hawi_usb3_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(hawi_usb3_serdes_tbl),
|
||||
.tx_tbl = hawi_usb3_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(hawi_usb3_tx_tbl),
|
||||
.rx_tbl = hawi_usb3_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(hawi_usb3_rx_tbl),
|
||||
.pcs_tbl = hawi_usb3_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_tbl),
|
||||
.pcs_usb_tbl = hawi_usb3_pcs_usb_tbl,
|
||||
.pcs_usb_tbl_num = ARRAY_SIZE(hawi_usb3_pcs_usb_tbl),
|
||||
|
||||
.regs = qmp_v10_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_offsets_v3,
|
||||
|
||||
@@ -2785,7 +3111,6 @@ static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
@@ -2834,7 +3159,6 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
@@ -2845,6 +3169,51 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = {
|
||||
.has_pwrdn_delay = true,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8475_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_offsets_v3,
|
||||
|
||||
.serdes_tbl = sar2130p_usb3_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(sar2130p_usb3_serdes_tbl),
|
||||
.tx_tbl = sm8550_usb3_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(sm8550_usb3_tx_tbl),
|
||||
.rx_tbl = sm8475_usb3_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(sm8475_usb3_rx_tbl),
|
||||
.pcs_tbl = sm8550_usb3_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_tbl),
|
||||
.pcs_usb_tbl = sm8475_usb3_pcs_usb_tbl,
|
||||
.pcs_usb_tbl_num = ARRAY_SIZE(sm8475_usb3_pcs_usb_tbl),
|
||||
|
||||
.dp_serdes_tbl = qmp_v6_dp_v1_serdes_tbl,
|
||||
.dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_v1_serdes_tbl),
|
||||
.dp_tx_tbl = qmp_v6_dp_tx_tbl,
|
||||
.dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl),
|
||||
|
||||
.serdes_tbl_rbr = qmp_v6_dp_v1_serdes_tbl_rbr,
|
||||
.serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_v1_serdes_tbl_rbr),
|
||||
.serdes_tbl_hbr = qmp_v6_dp_v1_serdes_tbl_hbr,
|
||||
.serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_v1_serdes_tbl_hbr),
|
||||
.serdes_tbl_hbr2 = qmp_v6_dp_v1_serdes_tbl_hbr2,
|
||||
.serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_v1_serdes_tbl_hbr2),
|
||||
.serdes_tbl_hbr3 = qmp_v6_dp_v1_serdes_tbl_hbr3,
|
||||
.serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_v1_serdes_tbl_hbr3),
|
||||
|
||||
.swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr,
|
||||
.pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr,
|
||||
.swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2,
|
||||
.pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2,
|
||||
|
||||
.dp_aux_init = qmp_v4_dp_aux_init,
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
|
||||
.regs = qmp_v6_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_offsets_v3,
|
||||
|
||||
@@ -2882,7 +3251,6 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.regs = qmp_v6_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
@@ -2928,7 +3296,6 @@ static const struct qmp_phy_cfg sm8650_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.regs = qmp_v6_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
@@ -2974,7 +3341,6 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v3_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v4_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.regs = qmp_v8_usb3phy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
@@ -3020,7 +3386,6 @@ static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = {
|
||||
.configure_dp_tx = qmp_v4_configure_dp_tx,
|
||||
.configure_dp_clocks = qmp_v8_configure_dp_clocks,
|
||||
.configure_dp_phy = qmp_v8_configure_dp_phy,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
.regs = qmp_v8_n3_usb43dpphy_regs_layout,
|
||||
.reset_list = msm8996_usb3phy_reset_l,
|
||||
@@ -3316,7 +3681,6 @@ static void qmp_v4_dp_aux_init(struct qmp_combo *qmp)
|
||||
writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
|
||||
writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
|
||||
writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
|
||||
qmp->dp_aux_cfg = 0;
|
||||
|
||||
writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
|
||||
PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
|
||||
@@ -3345,7 +3709,6 @@ static void qmp_v8_dp_aux_init(struct qmp_combo *qmp)
|
||||
writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
|
||||
writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
|
||||
writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
|
||||
qmp->dp_aux_cfg = 0;
|
||||
|
||||
writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
|
||||
PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
|
||||
@@ -3605,24 +3968,6 @@ static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to calibrate the aux setting here as many times
|
||||
* as the caller tries
|
||||
*/
|
||||
static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp)
|
||||
{
|
||||
static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
|
||||
u8 val;
|
||||
|
||||
qmp->dp_aux_cfg++;
|
||||
qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
|
||||
val = cfg1_settings[qmp->dp_aux_cfg];
|
||||
|
||||
writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_combo_dp_configure(struct phy *phy, union phy_configure_opts *opts)
|
||||
{
|
||||
const struct phy_configure_opts_dp *dp_opts = &opts->dp;
|
||||
@@ -3662,13 +4007,18 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
void __iomem *com = qmp->com;
|
||||
void __iomem *pcs_aon = qmp->pcs_aon;
|
||||
void __iomem *aon_toggle;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
if (!force && qmp->init_count++)
|
||||
return 0;
|
||||
|
||||
if (qmp->aon_toggle)
|
||||
aon_toggle = qmp->aon_toggle;
|
||||
else
|
||||
aon_toggle = qmp->pcs_aon;
|
||||
|
||||
ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
|
||||
@@ -3706,9 +4056,9 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
|
||||
SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
|
||||
|
||||
/* override hardware control for reset of qmp phy */
|
||||
if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) {
|
||||
qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1);
|
||||
qphy_clrbits(pcs_aon, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1);
|
||||
if (aon_toggle && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) {
|
||||
qphy_clrbits(aon_toggle, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1);
|
||||
qphy_clrbits(aon_toggle, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1);
|
||||
}
|
||||
|
||||
/* Use software based port select and switch on typec orientation */
|
||||
@@ -4735,6 +5085,9 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
|
||||
}
|
||||
qmp->dp_dp_phy = base + offs->dp_dp_phy;
|
||||
|
||||
if (offs->aon_toggle)
|
||||
qmp->aon_toggle = base + offs->aon_toggle;
|
||||
|
||||
ret = qmp_combo_clk_init(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -4934,10 +5287,16 @@ static int qmp_combo_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
|
||||
/*
|
||||
* Enable runtime PM before creating the PHYs, phy_create() only enables
|
||||
* it on the PHY devices if already enabled on the parent. Hold a usage
|
||||
* reference so callbacks cannot run until the PHY is ready.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
/*
|
||||
* Prevent runtime pm from being ON by default. Users can enable
|
||||
* it using power/control in sysfs.
|
||||
@@ -4946,14 +5305,13 @@ static int qmp_combo_probe(struct platform_device *pdev)
|
||||
|
||||
ret = qmp_combo_register_clocks(qmp, usb_np, dp_np);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
|
||||
goto err_pm_put;
|
||||
|
||||
qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops);
|
||||
if (IS_ERR(qmp->usb_phy)) {
|
||||
ret = PTR_ERR(qmp->usb_phy);
|
||||
dev_err(dev, "failed to create USB PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
phy_set_drvdata(qmp->usb_phy, qmp);
|
||||
@@ -4962,7 +5320,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(qmp->dp_phy)) {
|
||||
ret = PTR_ERR(qmp->dp_phy);
|
||||
dev_err(dev, "failed to create DP PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
phy_set_drvdata(qmp->dp_phy, qmp);
|
||||
@@ -4972,11 +5330,20 @@ static int qmp_combo_probe(struct platform_device *pdev)
|
||||
else
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
of_node_put(usb_np);
|
||||
of_node_put(dp_np);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put_noidle(dev);
|
||||
err_node_put:
|
||||
of_node_put(usb_np);
|
||||
of_node_put(dp_np);
|
||||
@@ -4988,6 +5355,10 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
|
||||
.compatible = "qcom,glymur-qmp-usb3-dp-phy",
|
||||
.data = &glymur_usb3dpphy_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,hawi-qmp-usb3-dp-phy",
|
||||
.data = &hawi_usb3dpphy_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sar2130p-qmp-usb3-dp-phy",
|
||||
.data = &sar2130p_usb3dpphy_cfg,
|
||||
@@ -5032,6 +5403,10 @@ static const struct of_device_id qmp_combo_of_match_table[] = {
|
||||
.compatible = "qcom,sm8450-qmp-usb3-dp-phy",
|
||||
.data = &sm8350_usb3dpphy_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sm8475-qmp-usb3-dp-phy",
|
||||
.data = &sm8475_usb3dpphy_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sm8550-qmp-usb3-dp-phy",
|
||||
.data = &sm8550_usb3dpphy_cfg,
|
||||
|
||||
15
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
Normal file
15
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v10.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_DP_PHY_V10_H_
|
||||
#define QCOM_PHY_QMP_DP_PHY_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - DP PHY registers */
|
||||
|
||||
#define QSERDES_V10_DP_PHY_VCO_DIV 0x070
|
||||
#define QSERDES_V10_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0
|
||||
#define QSERDES_V10_DP_PHY_STATUS 0x0e4
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_
|
||||
#define QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_
|
||||
|
||||
/* Only for DP QMP V8 PHY - QSERDES COM registers */
|
||||
#define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c
|
||||
#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058
|
||||
#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c
|
||||
#define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060
|
||||
#define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064
|
||||
#define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070
|
||||
#define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074
|
||||
#define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078
|
||||
#define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c
|
||||
#define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080
|
||||
#define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084
|
||||
#define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088
|
||||
#define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090
|
||||
#define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094
|
||||
#define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098
|
||||
#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0
|
||||
#define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8
|
||||
#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4
|
||||
#define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac
|
||||
#define DP_QSERDES_V8_COM_BG_TIMER 0x0bc
|
||||
#define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0
|
||||
#define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4
|
||||
#define DP_QSERDES_V8_COM_SSC_PER1 0x0cc
|
||||
#define DP_QSERDES_V8_COM_SSC_PER2 0x0d0
|
||||
#define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc
|
||||
#define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0
|
||||
#define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4
|
||||
#define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8
|
||||
#define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4
|
||||
#define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110
|
||||
#define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118
|
||||
#define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120
|
||||
#define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c
|
||||
#define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140
|
||||
#define DP_QSERDES_V8_COM_CLK_SELECT 0x164
|
||||
#define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170
|
||||
#define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174
|
||||
#define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180
|
||||
#define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4
|
||||
#define DP_QSERDES_V8_COM_CMN_STATUS 0x314
|
||||
#define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c
|
||||
|
||||
#endif
|
||||
743
drivers/phy/qualcomm/phy-qcom-qmp-pcie-multiphy.c
Normal file
743
drivers/phy/qualcomm/phy-qcom-qmp-pcie-multiphy.c
Normal file
@@ -0,0 +1,743 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "phy-qcom-qmp.h"
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT_US 10000
|
||||
|
||||
enum qmp_pcie_glymur_link_mode {
|
||||
QMP_PCIE_GLYMUR_MODE_X8,
|
||||
QMP_PCIE_GLYMUR_MODE_X4X4,
|
||||
};
|
||||
|
||||
enum qphy_reg_layout {
|
||||
QPHY_PCS_STATUS,
|
||||
QPHY_LAYOUT_SIZE
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1,
|
||||
};
|
||||
|
||||
struct qmp_pcie_offsets {
|
||||
u16 pcs;
|
||||
};
|
||||
|
||||
struct qmp_phy_cfg {
|
||||
const struct qmp_pcie_offsets *offsets;
|
||||
const char * const *reg_names;
|
||||
int num_regs;
|
||||
const char * const *pd_names;
|
||||
int num_pds;
|
||||
const char * const *nocsr_reset_list;
|
||||
int num_nocsr_resets;
|
||||
const char * const *vreg_list;
|
||||
int num_vregs;
|
||||
const unsigned int *regs;
|
||||
unsigned int phy_status;
|
||||
const char * const *clk_list;
|
||||
int num_clks;
|
||||
const char * const *pipe_clk_list;
|
||||
int num_pipe_clks;
|
||||
};
|
||||
|
||||
struct qmp_pcie {
|
||||
struct device *dev;
|
||||
const struct qmp_phy_cfg *cfg;
|
||||
void __iomem **base;
|
||||
struct clk_bulk_data *clks;
|
||||
struct clk_bulk_data *pipe_clks;
|
||||
struct reset_control_bulk_data *nocsr_resets;
|
||||
struct regulator_bulk_data *vregs;
|
||||
struct device **pd_devs;
|
||||
};
|
||||
|
||||
struct qmp_pcie_multiphy {
|
||||
struct phy **phys;
|
||||
const struct qmp_pcie_link_mode_cfg *mode_cfg;
|
||||
int num_pipe_outputs;
|
||||
struct clk_fixed_rate *pipe_out_clks;
|
||||
};
|
||||
|
||||
struct qmp_pcie_link_mode_cfg {
|
||||
const struct qmp_phy_cfg * const *cfgs;
|
||||
u32 num_phys;
|
||||
};
|
||||
|
||||
struct qmp_pcie_match_data {
|
||||
const struct qmp_pcie_link_mode_cfg *mode_cfgs;
|
||||
u32 num_modes;
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_clk_l[] = {
|
||||
"aux", "cfg_ahb", "ref", "rchng", "phy_b_aux",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_a_clk_l[] = {
|
||||
"aux", "cfg_ahb", "ref", "rchng",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_b_clk_l[] = {
|
||||
"phy_b_aux", "cfg_ahb_b", "ref", "rchng_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_pipeclk_l[] = {
|
||||
"pipe",
|
||||
};
|
||||
|
||||
static const char * const glymur_pipephy_b_pipeclk_l[] = {
|
||||
"pipe_b", "pipediv2_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_vreg_l[] = {
|
||||
"vdda-phy", "vdda-pll", "vdda-refgen0p9", "vdda-refgen1p2",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_a_reg_l[] = {
|
||||
"port_a",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_b_reg_l[] = {
|
||||
"port_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_reg_l[] = {
|
||||
"port_a", "port_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_a_pd_l[] = {
|
||||
"port_a",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_b_pd_l[] = {
|
||||
"port_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_pd_l[] = {
|
||||
"port_a", "port_b",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_a_nocsr_reset_l[] = {
|
||||
"port_a_nocsr",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_nocsr_reset_l[] = {
|
||||
"port_a_nocsr", "port_b_nocsr",
|
||||
};
|
||||
|
||||
static const char * const glymur_pciephy_b_nocsr_reset_l[] = {
|
||||
"port_b_nocsr",
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets glymur_pcie_offsets_v8_50 = {
|
||||
.pcs = 0x9000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_a_cfg = {
|
||||
.offsets = &glymur_pcie_offsets_v8_50,
|
||||
.reg_names = glymur_pciephy_a_reg_l,
|
||||
.num_regs = ARRAY_SIZE(glymur_pciephy_a_reg_l),
|
||||
.pd_names = glymur_pciephy_a_pd_l,
|
||||
.num_pds = ARRAY_SIZE(glymur_pciephy_a_pd_l),
|
||||
.nocsr_reset_list = glymur_pciephy_a_nocsr_reset_l,
|
||||
.num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_a_nocsr_reset_l),
|
||||
.vreg_list = glymur_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(glymur_vreg_l),
|
||||
.regs = pciephy_v8_50_regs_layout,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
.pipe_clk_list = glymur_pciephy_pipeclk_l,
|
||||
.num_pipe_clks = ARRAY_SIZE(glymur_pciephy_pipeclk_l),
|
||||
.clk_list = glymur_pciephy_a_clk_l,
|
||||
.num_clks = ARRAY_SIZE(glymur_pciephy_a_clk_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_b_cfg = {
|
||||
.offsets = &glymur_pcie_offsets_v8_50,
|
||||
.reg_names = glymur_pciephy_b_reg_l,
|
||||
.num_regs = ARRAY_SIZE(glymur_pciephy_b_reg_l),
|
||||
.pd_names = glymur_pciephy_b_pd_l,
|
||||
.num_pds = ARRAY_SIZE(glymur_pciephy_b_pd_l),
|
||||
.nocsr_reset_list = glymur_pciephy_b_nocsr_reset_l,
|
||||
.num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_b_nocsr_reset_l),
|
||||
.vreg_list = glymur_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(glymur_vreg_l),
|
||||
.regs = pciephy_v8_50_regs_layout,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
.pipe_clk_list = glymur_pipephy_b_pipeclk_l,
|
||||
.num_pipe_clks = ARRAY_SIZE(glymur_pipephy_b_pipeclk_l),
|
||||
.clk_list = glymur_pciephy_b_clk_l,
|
||||
.num_clks = ARRAY_SIZE(glymur_pciephy_b_clk_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_qmp_gen5x8_pciephy_cfg = {
|
||||
.offsets = &glymur_pcie_offsets_v8_50,
|
||||
.reg_names = glymur_pciephy_reg_l,
|
||||
.num_regs = ARRAY_SIZE(glymur_pciephy_reg_l),
|
||||
.pd_names = glymur_pciephy_pd_l,
|
||||
.num_pds = ARRAY_SIZE(glymur_pciephy_pd_l),
|
||||
.nocsr_reset_list = glymur_pciephy_nocsr_reset_l,
|
||||
.num_nocsr_resets = ARRAY_SIZE(glymur_pciephy_nocsr_reset_l),
|
||||
.vreg_list = glymur_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(glymur_vreg_l),
|
||||
.regs = pciephy_v8_50_regs_layout,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
.pipe_clk_list = glymur_pciephy_pipeclk_l,
|
||||
.num_pipe_clks = ARRAY_SIZE(glymur_pciephy_pipeclk_l),
|
||||
.clk_list = glymur_pciephy_clk_l,
|
||||
.num_clks = ARRAY_SIZE(glymur_pciephy_clk_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg * const glymur_qmp_gen5x8_mode_x8_cfgs[] = {
|
||||
&glymur_qmp_gen5x8_pciephy_cfg,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg * const glymur_qmp_gen5x8_mode_x4x4_cfgs[] = {
|
||||
&glymur_qmp_gen5x4_pciephy_a_cfg,
|
||||
&glymur_qmp_gen5x4_pciephy_b_cfg,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_link_mode_cfg glymur_qmp_gen5x8_mode_cfgs[] = {
|
||||
[QMP_PCIE_GLYMUR_MODE_X8] = {
|
||||
.cfgs = glymur_qmp_gen5x8_mode_x8_cfgs,
|
||||
.num_phys = ARRAY_SIZE(glymur_qmp_gen5x8_mode_x8_cfgs),
|
||||
},
|
||||
[QMP_PCIE_GLYMUR_MODE_X4X4] = {
|
||||
.cfgs = glymur_qmp_gen5x8_mode_x4x4_cfgs,
|
||||
.num_phys = ARRAY_SIZE(glymur_qmp_gen5x8_mode_x4x4_cfgs),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_match_data glymur_qmp_gen5x8_match_data = {
|
||||
.mode_cfgs = glymur_qmp_gen5x8_mode_cfgs,
|
||||
.num_modes = ARRAY_SIZE(glymur_qmp_gen5x8_mode_cfgs),
|
||||
};
|
||||
|
||||
static int qmp_pcie_pd_power_on(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < cfg->num_pds; i++) {
|
||||
ret = pm_runtime_resume_and_get(qmp->pd_devs[i]);
|
||||
if (ret < 0) {
|
||||
dev_err(qmp->dev, "failed to power on %s domain: %d\n",
|
||||
cfg->pd_names[i], ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_power_off:
|
||||
while (--i >= 0)
|
||||
pm_runtime_put(qmp->pd_devs[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qmp_pcie_pd_power_off(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
int i;
|
||||
|
||||
for (i = cfg->num_pds - 1; i >= 0; i--)
|
||||
pm_runtime_put(qmp->pd_devs[i]);
|
||||
}
|
||||
|
||||
static int qmp_pcie_init(struct phy *phy)
|
||||
{
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
int ret;
|
||||
|
||||
ret = qmp_pcie_pd_power_on(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "failed to enable regulators: %d\n", ret);
|
||||
goto err_pd_power_off;
|
||||
}
|
||||
|
||||
ret = reset_control_bulk_assert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset assert failed: %d\n", ret);
|
||||
goto err_disable_regulators;
|
||||
}
|
||||
|
||||
usleep_range(200, 300);
|
||||
|
||||
ret = clk_bulk_prepare_enable(qmp->cfg->num_clks, qmp->clks);
|
||||
if (ret)
|
||||
goto err_disable_regulators;
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_regulators:
|
||||
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
|
||||
err_pd_power_off:
|
||||
qmp_pcie_pd_power_off(qmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_pcie_exit(struct phy *phy)
|
||||
{
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
|
||||
reset_control_bulk_assert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets);
|
||||
|
||||
clk_bulk_disable_unprepare(qmp->cfg->num_clks, qmp->clks);
|
||||
regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
|
||||
qmp_pcie_pd_power_off(qmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_pcie_power_on(struct phy *phy)
|
||||
{
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
const struct qmp_pcie_offsets *offs = cfg->offsets;
|
||||
void __iomem *status;
|
||||
unsigned int val;
|
||||
int i, ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(qmp->cfg->num_pipe_clks, qmp->pipe_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_bulk_deassert(qmp->cfg->num_nocsr_resets, qmp->nocsr_resets);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset deassert failed: %d\n", ret);
|
||||
goto err_disable_pipe_clk;
|
||||
}
|
||||
|
||||
for (i = 0; i < cfg->num_regs; i++) {
|
||||
status = qmp->base[i] + offs->pcs + cfg->regs[QPHY_PCS_STATUS];
|
||||
ret = readl_poll_timeout(status, val, !(val & cfg->phy_status), 200,
|
||||
PHY_INIT_COMPLETE_TIMEOUT_US);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "PHY power on timed-out (%s): %d\n",
|
||||
cfg->reg_names[i], ret);
|
||||
goto err_disable_pipe_clk;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_pipe_clk:
|
||||
clk_bulk_disable_unprepare(qmp->cfg->num_pipe_clks, qmp->pipe_clks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_pcie_power_off(struct phy *phy)
|
||||
{
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
|
||||
clk_bulk_disable_unprepare(qmp->cfg->num_pipe_clks, qmp->pipe_clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_pcie_enable(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = qmp_pcie_init(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qmp_pcie_power_on(phy);
|
||||
if (ret)
|
||||
qmp_pcie_exit(phy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_pcie_disable(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = qmp_pcie_power_off(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return qmp_pcie_exit(phy);
|
||||
}
|
||||
|
||||
static const struct phy_ops qmp_pcie_phy_ops = {
|
||||
.power_on = qmp_pcie_enable,
|
||||
.power_off = qmp_pcie_disable,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void qmp_pcie_pd_detach(void *data)
|
||||
{
|
||||
struct qmp_pcie *qmp = data;
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cfg->num_pds; i++) {
|
||||
if (!IS_ERR_OR_NULL(qmp->pd_devs[i]))
|
||||
dev_pm_domain_detach(qmp->pd_devs[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
static int qmp_pcie_pd_init(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
int i, ret;
|
||||
|
||||
if (!cfg->num_pds)
|
||||
return 0;
|
||||
|
||||
qmp->pd_devs = devm_kcalloc(dev, cfg->num_pds, sizeof(*qmp->pd_devs),
|
||||
GFP_KERNEL);
|
||||
if (!qmp->pd_devs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_pds; i++) {
|
||||
qmp->pd_devs[i] = dev_pm_domain_attach_by_name(dev,
|
||||
cfg->pd_names[i]);
|
||||
if (IS_ERR_OR_NULL(qmp->pd_devs[i])) {
|
||||
ret = PTR_ERR(qmp->pd_devs[i]) ? : -ENODATA;
|
||||
goto err_detach;
|
||||
}
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, qmp_pcie_pd_detach, qmp);
|
||||
|
||||
err_detach:
|
||||
while (--i >= 0)
|
||||
dev_pm_domain_detach(qmp->pd_devs[i], false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_pcie_vreg_init(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
int i;
|
||||
|
||||
qmp->vregs = devm_kcalloc(dev, cfg->num_vregs, sizeof(*qmp->vregs),
|
||||
GFP_KERNEL);
|
||||
if (!qmp->vregs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_vregs; i++)
|
||||
qmp->vregs[i].supply = cfg->vreg_list[i];
|
||||
|
||||
return devm_regulator_bulk_get(dev, cfg->num_vregs, qmp->vregs);
|
||||
}
|
||||
|
||||
static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
int i, ret;
|
||||
|
||||
qmp->nocsr_resets = devm_kcalloc(dev, cfg->num_nocsr_resets,
|
||||
sizeof(*qmp->nocsr_resets),
|
||||
GFP_KERNEL);
|
||||
if (!qmp->nocsr_resets)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_nocsr_resets; i++)
|
||||
qmp->nocsr_resets[i].id = cfg->nocsr_reset_list[i];
|
||||
|
||||
ret = devm_reset_control_bulk_get_exclusive(dev,
|
||||
cfg->num_nocsr_resets,
|
||||
qmp->nocsr_resets);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to get no-csr resets\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
int i, ret;
|
||||
|
||||
qmp->clks = devm_kcalloc(dev, cfg->num_clks, sizeof(*qmp->clks),
|
||||
GFP_KERNEL);
|
||||
if (!qmp->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_clks; i++)
|
||||
qmp->clks[i].id = cfg->clk_list[i];
|
||||
|
||||
ret = devm_clk_bulk_get_optional(dev, cfg->num_clks, qmp->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qmp->pipe_clks = devm_kcalloc(dev, cfg->num_pipe_clks,
|
||||
sizeof(*qmp->pipe_clks), GFP_KERNEL);
|
||||
if (!qmp->pipe_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_pipe_clks; i++)
|
||||
qmp->pipe_clks[i].id = cfg->pipe_clk_list[i];
|
||||
|
||||
return devm_clk_bulk_get_optional(dev, cfg->num_pipe_clks,
|
||||
qmp->pipe_clks);
|
||||
}
|
||||
|
||||
static int __phy_pipe_clk_register(struct device *dev, struct device_node *np,
|
||||
int idx, struct clk_fixed_rate *fixed)
|
||||
{
|
||||
struct clk_init_data init = { };
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_string_index(np, "clock-output-names", idx,
|
||||
&init.name);
|
||||
if (ret) {
|
||||
dev_err(dev, "%pOFn: No clock-output-names\n", np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
init.ops = &clk_fixed_rate_ops;
|
||||
|
||||
fixed->fixed_rate = 125000000;
|
||||
|
||||
fixed->hw.init = &init;
|
||||
|
||||
return devm_clk_hw_register(dev, &fixed->hw);
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
qmp_pcie_multiphy_clk_hw_get(struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
struct qmp_pcie_multiphy *qmp_data = data;
|
||||
unsigned int idx = 0;
|
||||
|
||||
if (clkspec->args_count)
|
||||
idx = clkspec->args[0];
|
||||
|
||||
if (idx < (unsigned int)qmp_data->num_pipe_outputs)
|
||||
return &qmp_data->pipe_out_clks[idx].hw;
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static int qmp_pcie_multiphy_register_clocks(struct device *dev,
|
||||
struct device_node *np,
|
||||
struct qmp_pcie_multiphy *qmp_data)
|
||||
{
|
||||
int num_pipe_outputs;
|
||||
int i, ret;
|
||||
|
||||
num_pipe_outputs = of_property_count_strings(np, "clock-output-names");
|
||||
|
||||
qmp_data->num_pipe_outputs = num_pipe_outputs;
|
||||
qmp_data->pipe_out_clks = devm_kcalloc(dev, num_pipe_outputs,
|
||||
sizeof(*qmp_data->pipe_out_clks),
|
||||
GFP_KERNEL);
|
||||
if (!qmp_data->pipe_out_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_pipe_outputs; i++) {
|
||||
ret = __phy_pipe_clk_register(dev, np, i,
|
||||
&qmp_data->pipe_out_clks[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, qmp_pcie_multiphy_clk_hw_get, qmp_data);
|
||||
}
|
||||
|
||||
static int qmp_pcie_get_mmio(struct qmp_pcie *qmp)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(qmp->dev);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
void __iomem *base;
|
||||
int i;
|
||||
|
||||
qmp->base = devm_kcalloc(dev, cfg->num_regs, sizeof(*qmp->base),
|
||||
GFP_KERNEL);
|
||||
if (!qmp->base)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < cfg->num_regs; i++) {
|
||||
base = devm_platform_ioremap_resource_byname(pdev, cfg->reg_names[i]);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
qmp->base[i] = base;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_pcie_read_link_mode(struct device *dev, unsigned int *link_mode)
|
||||
{
|
||||
struct regmap *map;
|
||||
unsigned int args[1];
|
||||
|
||||
map = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,link-mode",
|
||||
ARRAY_SIZE(args), args);
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
|
||||
return regmap_read(map, args[0], link_mode);
|
||||
}
|
||||
|
||||
static struct phy *qmp_pcie_multiphy_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
{
|
||||
struct qmp_pcie_multiphy *qmp_data = dev_get_drvdata(dev);
|
||||
unsigned int idx;
|
||||
|
||||
if (!qmp_data || args->args_count < 1)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
idx = args->args[0];
|
||||
|
||||
if (idx < (unsigned int)qmp_data->mode_cfg->num_phys)
|
||||
return qmp_data->phys[idx] ?: ERR_PTR(-EINVAL);
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static int qmp_pcie_probe_phy(struct qmp_pcie *qmp, struct device_node *np,
|
||||
struct phy **out_phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = qmp_pcie_get_mmio(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qmp_pcie_clk_init(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qmp_pcie_reset_init(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qmp_pcie_vreg_init(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qmp_pcie_pd_init(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*out_phy = devm_phy_create(qmp->dev, np, &qmp_pcie_phy_ops);
|
||||
if (IS_ERR(*out_phy))
|
||||
return PTR_ERR(*out_phy);
|
||||
|
||||
phy_set_drvdata(*out_phy, qmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_pcie_multiphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qmp_pcie_match_data *match_data;
|
||||
struct qmp_pcie_multiphy *qmp_data;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int link_mode;
|
||||
struct qmp_pcie *qmp;
|
||||
struct phy **phys;
|
||||
int phy_index;
|
||||
int ret;
|
||||
|
||||
qmp_data = devm_kzalloc(dev, sizeof(*qmp_data), GFP_KERNEL);
|
||||
|
||||
match_data = of_device_get_match_data(dev);
|
||||
if (!match_data)
|
||||
return -EINVAL;
|
||||
|
||||
if (!qmp_data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = qmp_pcie_read_link_mode(dev, &link_mode);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to read qcom,link-mode\n");
|
||||
|
||||
if (link_mode >= match_data->num_modes)
|
||||
return dev_err_probe(dev, -EINVAL, "invalid qcom,link-mode: %u\n",
|
||||
link_mode);
|
||||
|
||||
qmp_data->mode_cfg = &match_data->mode_cfgs[link_mode];
|
||||
|
||||
qmp = devm_kcalloc(dev, qmp_data->mode_cfg->num_phys, sizeof(*qmp), GFP_KERNEL);
|
||||
if (!qmp)
|
||||
return -ENOMEM;
|
||||
|
||||
phys = devm_kcalloc(dev, qmp_data->mode_cfg->num_phys, sizeof(*phys), GFP_KERNEL);
|
||||
if (!phys)
|
||||
return -ENOMEM;
|
||||
|
||||
qmp_data->phys = phys;
|
||||
dev_set_drvdata(dev, qmp_data);
|
||||
|
||||
for (phy_index = 0; phy_index < qmp_data->mode_cfg->num_phys; phy_index++) {
|
||||
qmp[phy_index].dev = dev;
|
||||
qmp[phy_index].cfg = qmp_data->mode_cfg->cfgs[phy_index];
|
||||
ret = qmp_pcie_probe_phy(&qmp[phy_index], dev->of_node, &phys[phy_index]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = qmp_pcie_multiphy_register_clocks(dev, dev->of_node, qmp_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, qmp_pcie_multiphy_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id qmp_pcie_multiphy_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,glymur-qmp-gen5x8-pcie-phy",
|
||||
.data = &glymur_qmp_gen5x8_match_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qmp_pcie_multiphy_of_match_table);
|
||||
|
||||
static struct platform_driver qmp_pcie_multiphy_driver = {
|
||||
.probe = qmp_pcie_multiphy_probe,
|
||||
.driver = {
|
||||
.name = "qcom-qmp-pcie-multiphy",
|
||||
.of_match_table = qmp_pcie_multiphy_of_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(qmp_pcie_multiphy_driver);
|
||||
|
||||
MODULE_AUTHOR("Qiang Yu <qiang.yu@oss.qualcomm.com>");
|
||||
MODULE_DESCRIPTION("Qualcomm QMP PCIe Multi-PHY driver for Glymur");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "phy-qcom-qmp-qserdes-com-v8.h"
|
||||
#include "phy-qcom-qmp-pcs-pcie-v8.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h"
|
||||
#include "phy-qcom-qmp-pcs-pcie-v10.h"
|
||||
#include "phy-qcom-qmp-pcs-pcie-v10_60.h"
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
||||
|
||||
@@ -116,6 +118,20 @@ static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_v10_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = QPHY_V10_PCS_SW_RESET,
|
||||
[QPHY_START_CTRL] = QPHY_V10_PCS_START_CONTROL,
|
||||
[QPHY_PCS_STATUS] = QPHY_V10_PCS_PCS_STATUS1,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_PCS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_v10_60_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = QPHY_V10_60_PCS_SW_RESET,
|
||||
[QPHY_START_CTRL] = QPHY_V10_60_PCS_START_CONTROL,
|
||||
[QPHY_PCS_STATUS] = QPHY_V10_60_PCS_PCS_STATUS1,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_60_PCS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl msm8998_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),
|
||||
@@ -620,6 +636,89 @@ 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 ipq5210_gen3x1_pcie_ep_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x23),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x23),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xfe),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xfe),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq5210_gen3x1_pcie_ep_rx_tbl[] = {
|
||||
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_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_RX_IDAC_TSETTLE_LOW, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xf0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x01),
|
||||
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_MODE_01_LOW, 0x01),
|
||||
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_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_DFE_EN_TIMER, 0x04),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq5210_gen3x1_pcie_ep_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
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_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x11),
|
||||
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_OSC_DTCT_CONFIG1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_CONFIG4, 0xff),
|
||||
};
|
||||
|
||||
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),
|
||||
@@ -857,6 +956,152 @@ static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9650_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER2, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x53),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x29),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xa2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xb5),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9650_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_HIGHZ_DRVR_EN, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xb5),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9650_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
|
||||
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, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_LSB, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_MSB, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_POST_THRESH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_MAIN_THRESH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
|
||||
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_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x67),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3a),
|
||||
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 ipq9650_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x25),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
|
||||
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, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9650_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
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_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P2_P3_POST, 0x34),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_POST, 0x40),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qcs615_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V2_COM_CLK_ENABLE1, 0x10),
|
||||
@@ -2454,6 +2699,82 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl[] =
|
||||
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8475_qmp_gen3x1_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xea),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_3, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8475_qmp_gen3x1_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xb7),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xea),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x89),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xdc),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH, 0x94),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xf0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIDGET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8475_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8550_qmp_gen3x2_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
|
||||
@@ -3326,6 +3647,287 @@ static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] =
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1, 0x93),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYS_CLK_CTRL, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_IVCO, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE0, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE1, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE1, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE_MAP, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_ADDITIONAL_MISC_3, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORE_CLK_EN, 0xa0),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_GM_CAL, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH2, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH3, 0xb7),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH4, 0xec),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_LOW, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH2, 0x49),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH3, 0x1b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH4, 0x9c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_LOW, 0xd1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH2, 0x49),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH3, 0x1b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH4, 0x9c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_LOW, 0xd1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_PRE_THRESH1, 0x3e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_PRE_THRESH2, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_POST_THRESH, 0xd2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FO_GAIN, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_GAIN, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL2, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CNTRL, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_TRIM, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_1, 0x25),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_3, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_4, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_5, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_PI_QEC_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX, 0x14),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_REFGEN_REQ_CONFIG1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_SIGDET_LVL, 0x77),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_RATE_SLEW_CNTRL1, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG, 0x8c),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_PCS_G3S2_PRE_GAIN, 0x2e),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_EQ_CONFIG1, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_RXEQEVAL_TIME, 0x27),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG2, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG6, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_OSC_DTCT_ACTIONS, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE1, 0x93),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP1_MODE1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP2_MODE1, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DEC_START_MODE1, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORECLK_DIV_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP1_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP2_MODE0, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SYS_CLK_CTRL, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP_EN, 0x46),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP_CFG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_VCO_TUNE_MAP, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORE_CLK_EN, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_MISC1, 0x88),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_MODE, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_VCO_DC_LEVEL_CTRL, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_SPARE_FOR_ECO, 0x02),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_TX, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_RX, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_TRIM, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_TX_BAND0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_TX_BAND1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SEL_10B_8B, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SEL_20B_10B, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE3, 0x22),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE4, 0x22),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_PHPRE_CTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE3, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE2, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE3, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL3, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL4, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SVS_MODE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RXCLK_DIV2_CTRL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_BAND_CTRL0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE2, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE3, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE4, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE2, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE3, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE4, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CONTROLS, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE3, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE4, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_LSB, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_MSB, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_VGA_CAL_CNTRL1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_VGA_CAL_MAN_VAL, 0x8e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_GM_CAL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_EQU_ADAPTOR_CNTRL6, 0xca),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CNTRL, 0x6f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_LVL, 0x84),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_DEGLITCH_CNTRL, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE32, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE45, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B0, 0xc2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B1, 0xc2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B2, 0xd8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B3, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B4, 0x98),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B5, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B6, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B7, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B8, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B9, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B10, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B2, 0xd8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B3, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B4, 0x98),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B5, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B6, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B7, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B8, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B9, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B10, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B0, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B1, 0xd3),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B2, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B3, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B4, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B5, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B6, 0x4c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B7, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B8, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B9, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B10, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B1, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B2, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B3, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B4, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B5, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B6, 0x2c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B7, 0x86),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B8, 0x83),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B9, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B10, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_2, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_3, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_G3S2_PRE_GAIN, 0x2e),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_RX_SIGDET_LVL, 0xcc),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_ELECIDLE_DLY_SEL, 0x40),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_PCS_TX_RX_CONFIG1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_PCS_TX_RX_CONFIG2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_EQ_CONFIG4, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_EQ_CONFIG5, 0x22),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG2, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_TX_RX_CONFIG, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_EQ_CONFIG1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G3_RXEQEVAL_TIME, 0x27),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_RXEQEVAL_TIME, 0x27),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_EQ_CONFIG5, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_PRE_GAIN, 0x2e),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG3, 0x28),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG5, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G3_FOM_EQ_CONFIG5, 0xf2),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_FOM_EQ_CONFIG5, 0xf2),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG6, 0x1f),
|
||||
};
|
||||
|
||||
struct qmp_pcie_offsets {
|
||||
u16 serdes;
|
||||
u16 pcs;
|
||||
@@ -3484,6 +4086,10 @@ static const char * const qmp_phy_vreg_l[] = {
|
||||
"vdda-phy", "vdda-pll",
|
||||
};
|
||||
|
||||
static const char * const ipq9650_qmp_phy_vreg_l[] = {
|
||||
"refgen",
|
||||
};
|
||||
|
||||
static const char * const sm8550_qmp_phy_vreg_l[] = {
|
||||
"vdda-phy", "vdda-pll", "vdda-qref",
|
||||
};
|
||||
@@ -3527,6 +4133,14 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x1 = {
|
||||
.rx = 0x0400,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_9650_v4x1 = {
|
||||
.serdes = 0,
|
||||
.pcs = 0x0600,
|
||||
.pcs_misc = 0x0a00,
|
||||
.tx = 0x0200,
|
||||
.rx = 0x0400,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x2 = {
|
||||
.serdes = 0,
|
||||
.pcs = 0x0a00,
|
||||
@@ -3554,6 +4168,7 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 = {
|
||||
.pcs_misc = 0x0600,
|
||||
.tx = 0x0e00,
|
||||
.rx = 0x1000,
|
||||
.pcs_lane1 = 0x1400,
|
||||
.tx2 = 0x1600,
|
||||
.rx2 = 0x1800,
|
||||
};
|
||||
@@ -3638,6 +4253,24 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
|
||||
.txrxz = 0xd000,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v10_0 = {
|
||||
.serdes = 0x0000,
|
||||
.pcs = 0x0400,
|
||||
.pcs_misc = 0x0800,
|
||||
.tx = 0x1000,
|
||||
.rx = 0x1200,
|
||||
.tx2 = 0x1800,
|
||||
.rx2 = 0x1a00,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v10_60 = {
|
||||
.tx = 0x0000,
|
||||
/* no .rx; tx and rx share the same register block */
|
||||
.serdes = 0x1000,
|
||||
.pcs = 0x1400,
|
||||
.pcs_misc = 0x1800,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg eliza_qmp_gen3x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
@@ -3746,6 +4379,49 @@ static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq5210_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),
|
||||
},
|
||||
|
||||
.tbls_ep = &(const struct qmp_phy_cfg_tbls) {
|
||||
.serdes = ipq5210_gen3x1_pcie_ep_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_serdes_tbl),
|
||||
.tx = ipq6018_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
|
||||
.rx = ipq5210_gen3x1_pcie_ep_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_rx_tbl),
|
||||
.pcs = ipq6018_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
|
||||
.pcs_misc = ipq5210_gen3x1_pcie_ep_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_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_gen3x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
@@ -3802,6 +4478,62 @@ static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = {
|
||||
.pipe_clock_rate = 250000000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq9650_gen3x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_9650_v4x1,
|
||||
|
||||
.tbls = {
|
||||
.serdes = ipq9650_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl),
|
||||
.tx = ipq9650_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl),
|
||||
.rx = ipq9650_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl),
|
||||
.pcs = ipq9650_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl),
|
||||
.pcs_misc = ipq9650_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl),
|
||||
},
|
||||
.reset_list = ipq8074_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
|
||||
.vreg_list = ipq9650_qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l),
|
||||
.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 ipq9650_gen3x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v4x2,
|
||||
|
||||
.tbls = {
|
||||
.serdes = ipq9650_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl),
|
||||
.tx = ipq9650_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl),
|
||||
.rx = ipq9650_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl),
|
||||
.pcs = ipq9650_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl),
|
||||
.pcs_misc = ipq9650_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl),
|
||||
},
|
||||
.reset_list = ipq8074_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
|
||||
.vreg_list = ipq9650_qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l),
|
||||
.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 qcs615_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
@@ -4405,6 +5137,35 @@ static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
|
||||
.aux_clock_rate = 20000000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8475_qmp_gen3x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v5,
|
||||
|
||||
.tbls = {
|
||||
.serdes = sm8475_qmp_gen3x1_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(sm8475_qmp_gen3x1_pcie_serdes_tbl),
|
||||
.tx = sm8550_qmp_gen3x2_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl),
|
||||
.rx = sm8475_qmp_gen3x1_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(sm8475_qmp_gen3x1_pcie_rx_tbl),
|
||||
.pcs = sm8550_qmp_gen3x2_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl),
|
||||
.pcs_misc = sm8475_qmp_gen3x1_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(sm8475_qmp_gen3x1_pcie_pcs_misc_tbl),
|
||||
.pcs_lane1 = sar2130p_qmp_gen3x2_pcie_pcs_lane1_tbl,
|
||||
.pcs_lane1_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_pcs_lane1_tbl),
|
||||
},
|
||||
.reset_list = sdm845_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
.regs = pciephy_v6_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
@@ -4781,6 +5542,60 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg hawi_qmp_gen3x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v10_0,
|
||||
|
||||
.tbls = {
|
||||
.serdes = hawi_qmp_gen3x2_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_serdes_tbl),
|
||||
.tx = hawi_qmp_gen3x2_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_tx_tbl),
|
||||
.rx = hawi_qmp_gen3x2_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_rx_tbl),
|
||||
.pcs = hawi_qmp_gen3x2_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_pcs_tbl),
|
||||
.pcs_misc = hawi_qmp_gen3x2_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_pcs_misc_tbl),
|
||||
},
|
||||
|
||||
.reset_list = sdm845_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
.regs = pciephy_v10_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg hawi_qmp_gen4x1_pciephy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v10_60,
|
||||
|
||||
.tbls = {
|
||||
.serdes = hawi_qmp_gen4x1_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_serdes_tbl),
|
||||
.tx = hawi_qmp_gen4x1_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_tx_tbl),
|
||||
.pcs = hawi_qmp_gen4x1_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_pcs_tbl),
|
||||
.pcs_misc = hawi_qmp_gen4x1_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_pcs_misc_tbl),
|
||||
},
|
||||
|
||||
.reset_list = sdm845_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
.regs = pciephy_v10_60_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
};
|
||||
|
||||
static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
@@ -4862,6 +5677,7 @@ static int qmp_pcie_init(struct phy *phy)
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
void __iomem *pcs = qmp->pcs;
|
||||
bool skip_reset;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -4877,6 +5693,9 @@ static int qmp_pcie_init(struct phy *phy)
|
||||
qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
|
||||
qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
|
||||
|
||||
skip_reset = qmp->skip_init && !qphy_checkbits(pcs, cfg->regs[QPHY_PCS_STATUS],
|
||||
cfg->phy_status);
|
||||
|
||||
if (!qmp->skip_init && !cfg->tbls.serdes_num) {
|
||||
dev_err(qmp->dev, "Init sequence not available\n");
|
||||
return -ENODATA;
|
||||
@@ -4900,13 +5719,15 @@ static int qmp_pcie_init(struct phy *phy)
|
||||
}
|
||||
}
|
||||
|
||||
ret = reset_control_assert(qmp->nocsr_reset);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset assert failed\n");
|
||||
goto err_assert_reset;
|
||||
}
|
||||
if (!skip_reset) {
|
||||
ret = reset_control_assert(qmp->nocsr_reset);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset assert failed\n");
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
usleep_range(200, 300);
|
||||
usleep_range(200, 300);
|
||||
}
|
||||
|
||||
if (!qmp->skip_init) {
|
||||
ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
|
||||
@@ -4956,8 +5777,11 @@ static int qmp_pcie_power_on(struct phy *phy)
|
||||
void __iomem *pcs = qmp->pcs;
|
||||
void __iomem *status;
|
||||
unsigned int mask, val;
|
||||
bool skip_reset;
|
||||
int ret;
|
||||
|
||||
skip_reset = qmp->skip_init && !qphy_checkbits(pcs, cfg->regs[QPHY_PCS_STATUS],
|
||||
cfg->phy_status);
|
||||
/*
|
||||
* Write CSR register for PHY that doesn't support no_csr reset or has not
|
||||
* been initialized.
|
||||
@@ -4981,10 +5805,12 @@ static int qmp_pcie_power_on(struct phy *phy)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(qmp->nocsr_reset);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset deassert failed\n");
|
||||
goto err_disable_pipe_clk;
|
||||
if (!skip_reset) {
|
||||
ret = reset_control_deassert(qmp->nocsr_reset);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "no-csr reset deassert failed\n");
|
||||
goto err_disable_pipe_clk;
|
||||
}
|
||||
}
|
||||
|
||||
if (qmp->skip_init)
|
||||
@@ -5543,6 +6369,15 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
|
||||
.data = &glymur_qmp_gen5x4_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,hawi-qmp-gen3x2-pcie-phy",
|
||||
.data = &hawi_qmp_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,hawi-qmp-gen4x1-pcie-phy",
|
||||
.data = &hawi_qmp_gen4x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq5210-qmp-gen3x1-pcie-phy",
|
||||
.data = &ipq5210_gen3x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq6018-qmp-pcie-phy",
|
||||
.data = &ipq6018_pciephy_cfg,
|
||||
@@ -5558,6 +6393,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy",
|
||||
.data = &ipq9574_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq9650-qmp-gen3x1-pcie-phy",
|
||||
.data = &ipq9650_gen3x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy",
|
||||
.data = &ipq9650_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy",
|
||||
.data = &qmp_v8_gen3x2_pciephy_cfg,
|
||||
@@ -5630,6 +6471,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
|
||||
.data = &sm8450_qmp_gen4x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm8475-qmp-gen3x1-pcie-phy",
|
||||
.data = &sm8475_qmp_gen3x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm8550-qmp-gen3x2-pcie-phy",
|
||||
.data = &sm8550_qmp_gen3x2_pciephy_cfg,
|
||||
|
||||
13
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
Normal file
13
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v10.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_AON_V10_H_
|
||||
#define QCOM_PHY_QMP_PCS_AON_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - PCS AON registers */
|
||||
|
||||
#define QPHY_V10_PCS_AON_CLAMP_ENABLE 0x00
|
||||
|
||||
#endif
|
||||
18
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h
Normal file
18
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_PCIE_V10_H_
|
||||
#define QCOM_PHY_QMP_PCS_PCIE_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - PCIE PCS registers */
|
||||
#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG2 0x00c
|
||||
#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG4 0x014
|
||||
#define QPHY_PCIE_V10_PCS_ENDPOINT_REFCLK_DRIVE 0x020
|
||||
#define QPHY_PCIE_V10_PCS_OSC_DTCT_ACTIONS 0x094
|
||||
#define QPHY_PCIE_V10_PCS_EQ_CONFIG1 0x0a4
|
||||
#define QPHY_PCIE_V10_PCS_RXEQEVAL_TIME 0x0f4
|
||||
#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG6 0x0f8
|
||||
|
||||
#endif
|
||||
26
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h
Normal file
26
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_PCIE_V10_60_H_
|
||||
#define QCOM_PHY_QMP_PCS_PCIE_V10_60_H_
|
||||
|
||||
/* Only for QMP V10_60 PHY - PCIE PCS registers */
|
||||
#define QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG2 0x00c
|
||||
#define QPHY_PCIE_V10_60_PCS_TX_RX_CONFIG 0x018
|
||||
#define QPHY_PCIE_V10_60_PCS_ENDPOINT_REFCLK_DRIVE 0x01c
|
||||
#define QPHY_PCIE_V10_60_PCS_OSC_DTCT_ACTIONS 0x090
|
||||
#define QPHY_PCIE_V10_60_PCS_EQ_CONFIG1 0x0a0
|
||||
#define QPHY_PCIE_V10_60_PCS_G3_RXEQEVAL_TIME 0x0f0
|
||||
#define QPHY_PCIE_V10_60_PCS_G4_RXEQEVAL_TIME 0x0f4
|
||||
#define QPHY_PCIE_V10_60_PCS_G4_EQ_CONFIG5 0x108
|
||||
#define QPHY_PCIE_V10_60_PCS_G4_PRE_GAIN 0x15c
|
||||
#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG1 0x17c
|
||||
#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG3 0x184
|
||||
#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG5 0x18c
|
||||
#define QPHY_PCIE_V10_60_PCS_G3_FOM_EQ_CONFIG5 0x1ac
|
||||
#define QPHY_PCIE_V10_60_PCS_G4_FOM_EQ_CONFIG5 0x1c0
|
||||
#define QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG6 0x1d0
|
||||
|
||||
#endif
|
||||
24
drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
Normal file
24
drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_UFS_V7_H_
|
||||
#define QCOM_PHY_QMP_PCS_UFS_V7_H_
|
||||
|
||||
/* Only for QMP V7 PHY - UFS PCS registers */
|
||||
#define QPHY_V7_PCS_UFS_PHY_START 0x000
|
||||
#define QPHY_V7_PCS_UFS_POWER_DOWN_CONTROL 0x004
|
||||
#define QPHY_V7_PCS_UFS_SW_RESET 0x008
|
||||
#define QPHY_V7_PCS_UFS_PCS_CTRL1 0x01c
|
||||
#define QPHY_V7_PCS_UFS_PLL_CNTL 0x028
|
||||
#define QPHY_V7_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x02c
|
||||
#define QPHY_V7_PCS_UFS_TX_HSGEAR_CAPABILITY 0x060
|
||||
#define QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY 0x094
|
||||
#define QPHY_V7_PCS_UFS_LINECFG_DISABLE 0x140
|
||||
#define QPHY_V7_PCS_UFS_RX_SIGDET_CTRL2 0x150
|
||||
#define QPHY_V7_PCS_UFS_READY_STATUS 0x16c
|
||||
#define QPHY_V7_PCS_UFS_TX_MID_TERM_CTRL1 0x1b8
|
||||
#define QPHY_V7_PCS_UFS_MULTI_LANE_CTRL1 0x1c0
|
||||
|
||||
#endif
|
||||
19
drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
Normal file
19
drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v10.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_USB_V10_H_
|
||||
#define QCOM_PHY_QMP_PCS_USB_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - USB PCS registers */
|
||||
|
||||
#define QPHY_V10_PCS_USB3_POWER_STATE_CONFIG1 0x00
|
||||
#define QPHY_V10_PCS_USB3_AUTONOMOUS_MODE_CTRL 0x08
|
||||
#define QPHY_V10_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR 0x14
|
||||
#define QPHY_V10_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18
|
||||
#define QPHY_V10_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c
|
||||
#define QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40
|
||||
#define QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_H 0x44
|
||||
|
||||
#endif
|
||||
36
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
Normal file
36
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_V10_H_
|
||||
#define QCOM_PHY_QMP_PCS_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - PCS registers */
|
||||
|
||||
#define QPHY_V10_PCS_SW_RESET 0x000
|
||||
#define QPHY_V10_PCS_PCS_STATUS1 0x014
|
||||
#define QPHY_V10_PCS_POWER_DOWN_CONTROL 0x040
|
||||
#define QPHY_V10_PCS_START_CONTROL 0x044
|
||||
#define QPHY_V10_PCS_POWER_STATE_CONFIG1 0x090
|
||||
#define QPHY_V10_PCS_LOCK_DETECT_CONFIG1 0x0c4
|
||||
#define QPHY_V10_PCS_LOCK_DETECT_CONFIG2 0x0c8
|
||||
#define QPHY_V10_PCS_LOCK_DETECT_CONFIG3 0x0cc
|
||||
#define QPHY_V10_PCS_LOCK_DETECT_CONFIG6 0x0d8
|
||||
#define QPHY_V10_PCS_REFGEN_REQ_CONFIG1 0x0dc
|
||||
#define QPHY_V10_PCS_G12S1_TXDEEMPH_M6DB 0x168
|
||||
#define QPHY_V10_PCS_G3S2_PRE_GAIN 0x170
|
||||
#define QPHY_V10_PCS_RX_SIGDET_LVL 0x188
|
||||
#define QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
|
||||
#define QPHY_V10_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
|
||||
#define QPHY_V10_PCS_RATE_SLEW_CNTRL1 0x198
|
||||
#define QPHY_V10_PCS_RX_CONFIG 0x1b0
|
||||
#define QPHY_V10_PCS_ALIGN_DETECT_CONFIG1 0x1c0
|
||||
#define QPHY_V10_PCS_ALIGN_DETECT_CONFIG2 0x1c4
|
||||
#define QPHY_V10_PCS_PCS_TX_RX_CONFIG 0x1d0
|
||||
#define QPHY_V10_PCS_PCS_TX_RX_CONFIG2 0x1d4
|
||||
#define QPHY_V10_PCS_EQ_CONFIG1 0x1e0
|
||||
#define QPHY_V10_PCS_EQ_CONFIG2 0x1e4
|
||||
#define QPHY_V10_PCS_EQ_CONFIG5 0x1f0
|
||||
|
||||
#endif
|
||||
23
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h
Normal file
23
drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_V10_60_H_
|
||||
#define QCOM_PHY_QMP_PCS_V10_60_H_
|
||||
|
||||
/* Only for QMP V10_60 PHY - PCIe PCS registers */
|
||||
#define QPHY_V10_60_PCS_SW_RESET 0x000
|
||||
#define QPHY_V10_60_PCS_PCS_STATUS1 0x014
|
||||
#define QPHY_V10_60_PCS_POWER_DOWN_CONTROL 0x040
|
||||
#define QPHY_V10_60_PCS_START_CONTROL 0x044
|
||||
#define QPHY_V10_60_PCS_G12S1_TXDEEMPH_M6DB 0x170
|
||||
#define QPHY_V10_60_PCS_G3S2_PRE_GAIN 0x178
|
||||
#define QPHY_V10_60_PCS_RX_SIGDET_LVL 0x190
|
||||
#define QPHY_V10_60_PCS_ELECIDLE_DLY_SEL 0x1b8
|
||||
#define QPHY_V10_60_PCS_PCS_TX_RX_CONFIG1 0x1dc
|
||||
#define QPHY_V10_60_PCS_PCS_TX_RX_CONFIG2 0x1e0
|
||||
#define QPHY_V10_60_PCS_EQ_CONFIG4 0x1f8
|
||||
#define QPHY_V10_60_PCS_EQ_CONFIG5 0x1fc
|
||||
|
||||
#endif
|
||||
89
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
Normal file
89
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_COM_V10_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_COM_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - QSERDES COM registers */
|
||||
|
||||
#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1 0x00
|
||||
#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1 0x04
|
||||
#define QSERDES_V10_COM_CP_CTRL_MODE1 0x10
|
||||
#define QSERDES_V10_COM_PLL_RCTRL_MODE1 0x14
|
||||
#define QSERDES_V10_COM_PLL_CCTRL_MODE1 0x18
|
||||
#define QSERDES_V10_COM_CORECLK_DIV_MODE1 0x1c
|
||||
#define QSERDES_V10_COM_LOCK_CMP1_MODE1 0x20
|
||||
#define QSERDES_V10_COM_LOCK_CMP2_MODE1 0x24
|
||||
#define QSERDES_V10_COM_DEC_START_MODE1 0x28
|
||||
#define QSERDES_V10_COM_DEC_START_MSB_MODE1 0x2c
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START1_MODE1 0x30
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START2_MODE1 0x34
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START3_MODE1 0x38
|
||||
#define QSERDES_V10_COM_HSCLK_SEL_1 0x3c
|
||||
#define QSERDES_V10_COM_INTEGLOOP_GAIN0_MODE1 0x40
|
||||
#define QSERDES_V10_COM_INTEGLOOP_GAIN1_MODE1 0x44
|
||||
#define QSERDES_V10_COM_VCO_TUNE1_MODE1 0x48
|
||||
#define QSERDES_V10_COM_VCO_TUNE2_MODE1 0x4c
|
||||
#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x50
|
||||
#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x54
|
||||
#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x58
|
||||
#define QSERDES_V10_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x5c
|
||||
#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0 0x60
|
||||
#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0 0x64
|
||||
#define QSERDES_V10_COM_CP_CTRL_MODE0 0x70
|
||||
#define QSERDES_V10_COM_PLL_RCTRL_MODE0 0x74
|
||||
#define QSERDES_V10_COM_PLL_CCTRL_MODE0 0x78
|
||||
#define QSERDES_V10_COM_PLL_CORE_CLK_DIV_MODE0 0x7c
|
||||
#define QSERDES_V10_COM_LOCK_CMP1_MODE0 0x80
|
||||
#define QSERDES_V10_COM_LOCK_CMP2_MODE0 0x84
|
||||
#define QSERDES_V10_COM_DEC_START_MODE0 0x88
|
||||
#define QSERDES_V10_COM_DEC_START_MSB_MODE0 0x8c
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START1_MODE0 0x90
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START2_MODE0 0x94
|
||||
#define QSERDES_V10_COM_DIV_FRAC_START3_MODE0 0x98
|
||||
#define QSERDES_V10_COM_HSCLK_HS_SWITCH_SEL_1 0x9c
|
||||
#define QSERDES_V10_COM_INTEGLOOP_GAIN0_MODE0 0xa0
|
||||
#define QSERDES_V10_COM_INTEGLOOP_GAIN1_MODE0 0xa4
|
||||
#define QSERDES_V10_COM_VCO_TUNE1_MODE0 0xa8
|
||||
#define QSERDES_V10_COM_VCO_TUNE2_MODE0 0xac
|
||||
#define QSERDES_V10_COM_BG_TIMER 0xbc
|
||||
#define QSERDES_V10_COM_SSC_EN_CENTER 0xc0
|
||||
#define QSERDES_V10_COM_SSC_ADJ_PER1 0xc4
|
||||
#define QSERDES_V10_COM_SSC_PER1 0xcc
|
||||
#define QSERDES_V10_COM_SSC_PER2 0xd0
|
||||
#define QSERDES_V10_COM_POST_DIV_MUX 0xd8
|
||||
#define QSERDES_V10_COM_BIAS_EN_CLKBUFLR_EN 0xdc
|
||||
#define QSERDES_V10_COM_CLK_ENABLE1 0xe0
|
||||
#define QSERDES_V10_COM_SYS_CLK_CTRL 0xe4
|
||||
#define QSERDES_V10_COM_SYSCLK_BUF_ENABLE 0xe8
|
||||
#define QSERDES_V10_COM_PLL_IVCO 0xf4
|
||||
#define QSERDES_V10_COM_PLL_IVCO_MODE1 0xf8
|
||||
#define QSERDES_V10_COM_CMN_IETRIM 0xfc
|
||||
#define QSERDES_V10_COM_CMN_IPTRIM 0x100
|
||||
#define QSERDES_V10_COM_SYSCLK_EN_SEL 0x110
|
||||
#define QSERDES_V10_COM_RESETSM_CNTRL 0x118
|
||||
#define QSERDES_V10_COM_LOCK_CMP_EN 0x120
|
||||
#define QSERDES_V10_COM_LOCK_CMP_CFG 0x124
|
||||
#define QSERDES_V10_COM_VCO_TUNE_CTRL 0x13c
|
||||
#define QSERDES_V10_COM_VCO_TUNE_MAP 0x140
|
||||
#define QSERDES_V10_COM_VCO_TUNE_INITVAL2 0x148
|
||||
#define QSERDES_V10_COM_VCO_TUNE_MAXVAL2 0x158
|
||||
#define QSERDES_V10_COM_CLK_SELECT 0x164
|
||||
#define QSERDES_V10_COM_CORE_CLK_EN 0x170
|
||||
#define QSERDES_V10_COM_CMN_CONFIG_1 0x174
|
||||
#define QSERDES_V10_COM_SVS_MODE_CLK_SEL 0x17c
|
||||
#define QSERDES_V10_COM_CMN_MISC_1 0x184
|
||||
#define QSERDES_V10_COM_CMN_MODE 0x188
|
||||
#define QSERDES_V10_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
|
||||
#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
|
||||
#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
|
||||
#define QSERDES_V10_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
|
||||
#define QSERDES_V10_COM_ADDITIONAL_MISC 0x1b4
|
||||
#define QSERDES_V10_COM_ADDITIONAL_MISC_2 0x1b8
|
||||
#define QSERDES_V10_COM_ADDITIONAL_MISC_3 0x1bc
|
||||
#define QSERDES_V10_COM_CMN_STATUS 0x2c8
|
||||
#define QSERDES_V10_COM_C_READY_STATUS 0x2f0
|
||||
|
||||
#endif
|
||||
55
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h
Normal file
55
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_COM_V10_60_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_COM_V10_60_H_
|
||||
|
||||
/* Only for QMP V10_60 PHY - QSERDES COM registers */
|
||||
#define QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE1 0x00
|
||||
#define QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE1 0x04
|
||||
#define QSERDES_V10_60_COM_CP_CTRL_MODE1 0x10
|
||||
#define QSERDES_V10_60_COM_PLL_RCTRL_MODE1 0x14
|
||||
#define QSERDES_V10_60_COM_PLL_CCTRL_MODE1 0x18
|
||||
#define QSERDES_V10_60_COM_CORECLK_DIV_MODE1 0x1c
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP1_MODE1 0x20
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP2_MODE1 0x24
|
||||
#define QSERDES_V10_60_COM_DEC_START_MODE1 0x28
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START1_MODE1 0x30
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START2_MODE1 0x34
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START3_MODE1 0x38
|
||||
#define QSERDES_V10_60_COM_HSCLK_SEL_1 0x3c
|
||||
#define QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE0 0x60
|
||||
#define QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE0 0x64
|
||||
#define QSERDES_V10_60_COM_CP_CTRL_MODE0 0x70
|
||||
#define QSERDES_V10_60_COM_PLL_RCTRL_MODE0 0x74
|
||||
#define QSERDES_V10_60_COM_PLL_CCTRL_MODE0 0x78
|
||||
#define QSERDES_V10_60_COM_CORECLK_DIV_MODE0 0x7c
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP1_MODE0 0x80
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP2_MODE0 0x84
|
||||
#define QSERDES_V10_60_COM_DEC_START_MODE0 0x88
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START1_MODE0 0x90
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START2_MODE0 0x94
|
||||
#define QSERDES_V10_60_COM_DIV_FRAC_START3_MODE0 0x98
|
||||
#define QSERDES_V10_60_COM_HSCLK_HS_SWITCH_SEL_1 0x9c
|
||||
#define QSERDES_V10_60_COM_BG_TIMER 0xbc
|
||||
#define QSERDES_V10_60_COM_SSC_PER1 0xcc
|
||||
#define QSERDES_V10_60_COM_SSC_PER2 0xd0
|
||||
#define QSERDES_V10_60_COM_BIAS_EN_CLKBUFLR_EN 0xdc
|
||||
#define QSERDES_V10_60_COM_CLK_ENABLE1 0xe0
|
||||
#define QSERDES_V10_60_COM_SYS_CLK_CTRL 0xe4
|
||||
#define QSERDES_V10_60_COM_PLL_IVCO 0xf4
|
||||
#define QSERDES_V10_60_COM_SYSCLK_EN_SEL 0x110
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP_EN 0x120
|
||||
#define QSERDES_V10_60_COM_LOCK_CMP_CFG 0x124
|
||||
#define QSERDES_V10_60_COM_VCO_TUNE_MAP 0x140
|
||||
#define QSERDES_V10_60_COM_CLK_SELECT 0x164
|
||||
#define QSERDES_V10_60_COM_CORE_CLK_EN 0x170
|
||||
#define QSERDES_V10_60_COM_CMN_CONFIG_1 0x174
|
||||
#define QSERDES_V10_60_COM_CMN_MISC1 0x184
|
||||
#define QSERDES_V10_60_COM_CMN_MODE 0x188
|
||||
#define QSERDES_V10_60_COM_VCO_DC_LEVEL_CTRL 0x198
|
||||
#define QSERDES_V10_60_COM_PLL_SPARE_FOR_ECO 0x2b4
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2026, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_COM_V8_H_
|
||||
@@ -71,5 +71,16 @@
|
||||
#define QSERDES_V8_COM_ADDITIONAL_MISC 0x1b4
|
||||
#define QSERDES_V8_COM_CMN_STATUS 0x2c8
|
||||
#define QSERDES_V8_COM_C_READY_STATUS 0x2f0
|
||||
#define QSERDES_V8_COM_PLL_IVCO_MODE1 0xf8
|
||||
#define QSERDES_V8_COM_CMN_IETRIM 0xfc
|
||||
#define QSERDES_V8_COM_CMN_IPTRIM 0x100
|
||||
#define QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c
|
||||
#define QSERDES_V8_COM_ADAPTIVE_ANALOG_CONFIG 0x268
|
||||
#define QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE0 0x26c
|
||||
#define QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x270
|
||||
#define QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x274
|
||||
#define QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE1 0x278
|
||||
#define QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x27c
|
||||
#define QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x280
|
||||
|
||||
#endif
|
||||
|
||||
37
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
Normal file
37
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2026, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_UFS_V8_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_TXRX_UFS_V8_H_
|
||||
|
||||
#define QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_TX (0x34)
|
||||
#define QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_RX (0x38)
|
||||
#define QSERDES_UFS_V8_TX_LANE_MODE_1 (0x80)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE2 (0x1bc)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE4 (0x1c4)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_SO_GAIN_RATE4 (0x1dc)
|
||||
#define QSERDES_UFS_V8_RX_EQ_OFFSET_ADAPTOR_CNTRL1 (0x2c8)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_PI_CONTROLS (0x1e4)
|
||||
#define QSERDES_UFS_V8_RX_OFFSET_ADAPTOR_CNTRL3 (0x2d0)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4 (0x120)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_FO_GAIN_RATE4 (0xd4)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_SO_GAIN_RATE4 (0xec)
|
||||
#define QSERDES_UFS_V8_RX_VGA_CAL_MAN_VAL (0x288)
|
||||
#define QSERDES_UFS_V8_RX_EQU_ADAPTOR_CNTRL4 (0x2b0)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE_0_1_B4 (0x324)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE4_SA_B7 (0x3b4)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE4_SA_B9 (0x3bc)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE4_SB_B7 (0x3e0)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE4_SB_B9 (0x3e8)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE5_SA_B7 (0x40c)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE5_SA_B9 (0x414)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE5_SB_B7 (0x438)
|
||||
#define QSERDES_UFS_V8_RX_MODE_RATE5_SB_B9 (0x440)
|
||||
#define QSERDES_UFS_V8_RX_UCDR_SO_SATURATION (0xf4)
|
||||
#define QSERDES_UFS_V8_RX_TERM_BW_CTRL0 (0x1ac)
|
||||
#define QSERDES_UFS_V8_RX_DLL0_FTUNE_CTRL (0x498)
|
||||
#define QSERDES_UFS_V8_RX_SIGDET_CAL_TRIM (0x4d0)
|
||||
|
||||
#endif
|
||||
91
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
Normal file
91
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V10_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_TXRX_V10_H_
|
||||
|
||||
/* Only for QMP V10 PHY - QSERDES TX/RX registers */
|
||||
|
||||
/* TX registers */
|
||||
#define QSERDES_V10_TX_CLKBUF_ENABLE 0x08
|
||||
#define QSERDES_V10_TX_TX_EMP_POST1_LVL 0x0c
|
||||
#define QSERDES_V10_TX_TX_DRV_LVL 0x14
|
||||
#define QSERDES_V10_TX_RESET_TSYNC_EN 0x1c
|
||||
#define QSERDES_V10_TX_PRE_STALL_LDO_BOOST_EN 0x20
|
||||
#define QSERDES_V10_TX_TX_BAND 0x24
|
||||
#define QSERDES_V10_TX_INTERFACE_SELECT 0x2c
|
||||
#define QSERDES_V10_TX_RES_CODE_LANE_TX 0x34
|
||||
#define QSERDES_V10_TX_RES_CODE_LANE_RX 0x38
|
||||
#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX 0x3c
|
||||
#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX 0x40
|
||||
#define QSERDES_V10_TX_TRANSCEIVER_BIAS_EN 0x54
|
||||
#define QSERDES_V10_TX_HIGHZ_DRVR_EN 0x58
|
||||
#define QSERDES_V10_TX_TX_POL_INV 0x5c
|
||||
#define QSERDES_V10_TX_PARRATE_REC_DETECT_IDLE_EN 0x60
|
||||
#define QSERDES_V10_TX_BIST_PATTERN7 0x7c
|
||||
#define QSERDES_V10_TX_LANE_MODE_1 0x84
|
||||
#define QSERDES_V10_TX_LANE_MODE_2 0x88
|
||||
#define QSERDES_V10_TX_LANE_MODE_3 0x8c
|
||||
#define QSERDES_V10_TX_LANE_MODE_4 0x90
|
||||
#define QSERDES_V10_TX_LANE_MODE_5 0x94
|
||||
#define QSERDES_V10_TX_RCV_DETECT_LVL_2 0xa4
|
||||
#define QSERDES_V10_TX_TRAN_DRVR_EMP_EN 0xc0
|
||||
#define QSERDES_V10_TX_TX_INTERFACE_MODE 0xc4
|
||||
#define QSERDES_V10_TX_VMODE_CTRL1 0xc8
|
||||
#define QSERDES_V10_TX_PI_QEC_CTRL 0xe4
|
||||
|
||||
/* RX registers */
|
||||
#define QSERDES_V10_RX_UCDR_FO_GAIN 0x08
|
||||
#define QSERDES_V10_RX_UCDR_SO_GAIN 0x14
|
||||
#define QSERDES_V10_RX_UCDR_FASTLOCK_FO_GAIN 0x30
|
||||
#define QSERDES_V10_RX_UCDR_SO_SATURATION_AND_ENABLE 0x34
|
||||
#define QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_LOW 0x3c
|
||||
#define QSERDES_V10_RX_UCDR_FASTLOCK_COUNT_HIGH 0x40
|
||||
#define QSERDES_V10_RX_UCDR_PI_CONTROLS 0x44
|
||||
#define QSERDES_V10_RX_UCDR_SB2_THRESH1 0x4c
|
||||
#define QSERDES_V10_RX_UCDR_SB2_THRESH2 0x50
|
||||
#define QSERDES_V10_RX_UCDR_SB2_GAIN1 0x54
|
||||
#define QSERDES_V10_RX_UCDR_SB2_GAIN2 0x58
|
||||
#define QSERDES_V10_RX_AUX_DATA_TCOARSE_TFINE 0x60
|
||||
#define QSERDES_V10_RX_TX_ADAPT_PRE_THRESH1 0xc4
|
||||
#define QSERDES_V10_RX_TX_ADAPT_PRE_THRESH2 0xc8
|
||||
#define QSERDES_V10_RX_TX_ADAPT_POST_THRESH 0xcc
|
||||
#define QSERDES_V10_RX_VGA_CAL_CNTRL1 0xd4
|
||||
#define QSERDES_V10_RX_VGA_CAL_CNTRL2 0xd8
|
||||
#define QSERDES_V10_RX_GM_CAL 0xdc
|
||||
#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL2 0xec
|
||||
#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL3 0xf0
|
||||
#define QSERDES_V10_RX_RX_EQU_ADAPTOR_CNTRL4 0xf4
|
||||
#define QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW 0xf8
|
||||
#define QSERDES_V10_RX_RX_IDAC_TSETTLE_HIGH 0xfc
|
||||
#define QSERDES_V10_RX_RX_IDAC_ENABLES 0x100
|
||||
#define QSERDES_V10_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x104
|
||||
#define QSERDES_V10_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
|
||||
#define QSERDES_V10_RX_SIGDET_ENABLES 0x118
|
||||
#define QSERDES_V10_RX_SIGDET_CNTRL 0x11c
|
||||
#define QSERDES_V10_RX_SIGDET_DEGLITCH_CNTRL 0x124
|
||||
#define QSERDES_V10_RX_RX_MODE_00_LOW 0x15c
|
||||
#define QSERDES_V10_RX_RX_MODE_00_HIGH 0x160
|
||||
#define QSERDES_V10_RX_RX_MODE_00_HIGH2 0x164
|
||||
#define QSERDES_V10_RX_RX_MODE_00_HIGH3 0x168
|
||||
#define QSERDES_V10_RX_RX_MODE_00_HIGH4 0x16c
|
||||
#define QSERDES_V10_RX_RX_MODE_01_LOW 0x170
|
||||
#define QSERDES_V10_RX_RX_MODE_01_HIGH 0x174
|
||||
#define QSERDES_V10_RX_RX_MODE_01_HIGH2 0x178
|
||||
#define QSERDES_V10_RX_RX_MODE_01_HIGH3 0x17c
|
||||
#define QSERDES_V10_RX_RX_MODE_01_HIGH4 0x180
|
||||
#define QSERDES_V10_RX_RX_MODE_10_LOW 0x184
|
||||
#define QSERDES_V10_RX_RX_MODE_10_HIGH 0x188
|
||||
#define QSERDES_V10_RX_RX_MODE_10_HIGH2 0x18c
|
||||
#define QSERDES_V10_RX_RX_MODE_10_HIGH3 0x190
|
||||
#define QSERDES_V10_RX_RX_MODE_10_HIGH4 0x194
|
||||
#define QSERDES_V10_RX_DFE_EN_TIMER 0x1a0
|
||||
#define QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET 0x1a4
|
||||
#define QSERDES_V10_RX_DCC_CTRL1 0x1a8
|
||||
#define QSERDES_V10_RX_VTH_CODE 0x1b0
|
||||
#define QSERDES_V10_RX_SIGDET_CAL_CTRL1 0x1e4
|
||||
#define QSERDES_V10_RX_SIGDET_CAL_TRIM 0x1f8
|
||||
|
||||
#endif
|
||||
109
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h
Normal file
109
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V10_60_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_TXRX_V10_60_H_
|
||||
|
||||
#define QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_TX 0x034
|
||||
#define QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_RX 0x038
|
||||
#define QSERDES_V10_60_TXRX_LANE_MODE_1 0x080
|
||||
#define QSERDES_V10_60_TXRX_LANE_MODE_2 0x084
|
||||
#define QSERDES_V10_60_TXRX_LANE_MODE_3 0x088
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE1 0x0c8
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE2 0x0cc
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE3 0x0d0
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE4 0x0d4
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE1 0x0e0
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE2 0x0e4
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE3 0x0e8
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE4 0x0ec
|
||||
#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL1 0x12c
|
||||
#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL2 0x130
|
||||
#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL3 0x134
|
||||
#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL4 0x138
|
||||
#define QSERDES_V10_60_TXRX_SVS_MODE_CTRL 0x19c
|
||||
#define QSERDES_V10_60_TXRX_RXCLK_DIV2_CTRL 0x1a0
|
||||
#define QSERDES_V10_60_TXRX_RX_BAND_CTRL0 0x1a4
|
||||
#define QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL0 0x1ac
|
||||
#define QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL1 0x1b0
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE1 0x1b8
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE2 0x1bc
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE3 0x1c0
|
||||
#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE4 0x1c4
|
||||
#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE1 0x1d0
|
||||
#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE2 0x1d4
|
||||
#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE3 0x1d8
|
||||
#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE4 0x1dc
|
||||
#define QSERDES_V10_60_TXRX_UCDR_PI_CONTROLS 0x1e4
|
||||
#define QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE3 0x200
|
||||
#define QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE4 0x204
|
||||
#define QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_LSB 0x218
|
||||
#define QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_MSB 0x21c
|
||||
#define QSERDES_V10_60_TXRX_VGA_CAL_CNTRL1 0x280
|
||||
#define QSERDES_V10_60_TXRX_VGA_CAL_MAN_VAL 0x288
|
||||
#define QSERDES_V10_60_TXRX_GM_CAL 0x29c
|
||||
#define QSERDES_V10_60_TXRX_RX_EQU_ADAPTOR_CNTRL6 0x2b8
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_ENABLES 0x2d4
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_CNTRL 0x2d8
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_LVL 0x2dc
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_DEGLITCH_CNTRL 0x2e0
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B0 0x314
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B1 0x318
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B2 0x31c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B3 0x320
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B4 0x324
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B5 0x328
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B6 0x32c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B7 0x330
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B8 0x334
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B9 0x338
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B10 0x33c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B0 0x340
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B1 0x344
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B2 0x348
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B3 0x34c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B4 0x350
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B5 0x354
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B6 0x358
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B7 0x35c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B8 0x360
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B9 0x364
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B10 0x368
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B0 0x36c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B1 0x370
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B2 0x374
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B3 0x378
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B4 0x37c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B5 0x380
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B6 0x384
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B7 0x388
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B8 0x38c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B9 0x390
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B10 0x394
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B0 0x398
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B1 0x39c
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B2 0x3a0
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B3 0x3a4
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B4 0x3a8
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B5 0x3ac
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B6 0x3b0
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B7 0x3b4
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B8 0x3b8
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B9 0x3bc
|
||||
#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B10 0x3c0
|
||||
#define QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE32 0x478
|
||||
#define QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE45 0x47c
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL1 0x4c8
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL2 0x4cc
|
||||
#define QSERDES_V10_60_TXRX_SIGDET_CAL_TRIM 0x4d0
|
||||
#define QSERDES_V10_60_TXRX_TX_BAND0 0x4e8
|
||||
#define QSERDES_V10_60_TXRX_TX_BAND1 0x4ec
|
||||
#define QSERDES_V10_60_TXRX_SEL_10B_8B 0x4f4
|
||||
#define QSERDES_V10_60_TXRX_SEL_20B_10B 0x4f8
|
||||
#define QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE3 0x53c
|
||||
#define QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE4 0x540
|
||||
#define QSERDES_V10_60_TXRX_PHPRE_CTRL 0x5e8
|
||||
|
||||
#endif
|
||||
@@ -29,9 +29,11 @@
|
||||
#include "phy-qcom-qmp-pcs-ufs-v4.h"
|
||||
#include "phy-qcom-qmp-pcs-ufs-v5.h"
|
||||
#include "phy-qcom-qmp-pcs-ufs-v6.h"
|
||||
#include "phy-qcom-qmp-pcs-ufs-v7.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-ufs-v7.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-ufs-v8.h"
|
||||
|
||||
/* QPHY_PCS_READY_STATUS bit */
|
||||
#define PCS_READY BIT(0)
|
||||
@@ -84,6 +86,13 @@ static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const unsigned int ufsphy_v7_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_START_CTRL] = QPHY_V7_PCS_UFS_PHY_START,
|
||||
[QPHY_PCS_READY_STATUS] = QPHY_V7_PCS_UFS_READY_STATUS,
|
||||
[QPHY_SW_RESET] = QPHY_V7_PCS_UFS_SW_RESET,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_UFS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl milos_ufsphy_serdes[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
|
||||
@@ -1307,6 +1316,11 @@ static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
|
||||
{ .supply = "vdda-pll", .init_load_uA = 18300 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data hawi_ufsphy_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 324000 },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 27000 },
|
||||
};
|
||||
|
||||
static const struct qmp_ufs_offsets qmp_ufs_offsets = {
|
||||
.serdes = 0,
|
||||
.pcs = 0xc00,
|
||||
@@ -1325,6 +1339,15 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
|
||||
.rx2 = 0x1a00,
|
||||
};
|
||||
|
||||
static const struct qmp_ufs_offsets qmp_ufs_offsets_v7 = {
|
||||
.serdes = 0,
|
||||
.pcs = 0x0400,
|
||||
.tx = 0x2000,
|
||||
.rx = 0x2000,
|
||||
.tx2 = 0x3000,
|
||||
.rx2 = 0x3000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg milos_ufsphy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
@@ -1845,6 +1868,119 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
|
||||
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_ufsphy_serdes[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0xd9),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO_MODE1, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_IETRIM, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_IPTRIM, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_CTRL, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADAPTIVE_ANALOG_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x92),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x4c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE1, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x99),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xbe),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_ufsphy_tx[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_LANE_MODE_1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x17),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_ufsphy_rx[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE2, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE4, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_SO_GAIN_RATE4, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_PI_CONTROLS, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_VGA_CAL_MAN_VAL, 0x8e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE_0_1_B4, 0xb8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SA_B7, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SA_B9, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SB_B7, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SB_B9, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SA_B7, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SA_B9, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SB_B7, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SB_B9, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_SO_SATURATION, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_TERM_BW_CTRL0, 0xfa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_DLL0_FTUNE_CTRL, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_SIGDET_CAL_TRIM, 0x77),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_ufsphy_pcs[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_PCS_CTRL1, 0x42),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl hawi_ufsphy_g5_pcs[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_PLL_CNTL, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
|
||||
QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg hawi_ufsphy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_ufs_offsets_v7,
|
||||
.max_supported_gear = UFS_HS_G5,
|
||||
|
||||
.tbls = {
|
||||
.serdes = hawi_ufsphy_serdes,
|
||||
.serdes_num = ARRAY_SIZE(hawi_ufsphy_serdes),
|
||||
.tx = hawi_ufsphy_tx,
|
||||
.tx_num = ARRAY_SIZE(hawi_ufsphy_tx),
|
||||
.rx = hawi_ufsphy_rx,
|
||||
.rx_num = ARRAY_SIZE(hawi_ufsphy_rx),
|
||||
.pcs = hawi_ufsphy_pcs,
|
||||
.pcs_num = ARRAY_SIZE(hawi_ufsphy_pcs),
|
||||
},
|
||||
|
||||
.tbls_hs_overlay[0] = {
|
||||
.pcs = hawi_ufsphy_g5_pcs,
|
||||
.pcs_num = ARRAY_SIZE(hawi_ufsphy_g5_pcs),
|
||||
.max_gear = UFS_HS_G5,
|
||||
},
|
||||
|
||||
.vreg_list = hawi_ufsphy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(hawi_ufsphy_vreg_l),
|
||||
.regs = ufsphy_v7_regs_layout,
|
||||
};
|
||||
|
||||
static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
||||
{
|
||||
void __iomem *serdes = qmp->serdes;
|
||||
@@ -2259,6 +2395,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id qmp_ufs_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,hawi-qmp-ufs-phy",
|
||||
.data = &hawi_ufsphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,milos-qmp-ufs-phy",
|
||||
.data = &milos_ufsphy_cfg,
|
||||
}, {
|
||||
|
||||
@@ -542,6 +542,8 @@ struct qmp_usb {
|
||||
|
||||
enum phy_mode mode;
|
||||
|
||||
bool phy_initialized;
|
||||
|
||||
struct phy *phy;
|
||||
|
||||
struct clk_fixed_rate pipe_clk_fixed;
|
||||
@@ -895,6 +897,7 @@ static int qmp_usb_legacy_power_off(struct phy *phy)
|
||||
|
||||
static int qmp_usb_legacy_enable(struct phy *phy)
|
||||
{
|
||||
struct qmp_usb *qmp = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = qmp_usb_legacy_init(phy);
|
||||
@@ -904,14 +907,19 @@ static int qmp_usb_legacy_enable(struct phy *phy)
|
||||
ret = qmp_usb_legacy_power_on(phy);
|
||||
if (ret)
|
||||
qmp_usb_legacy_exit(phy);
|
||||
else
|
||||
qmp->phy_initialized = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_usb_legacy_disable(struct phy *phy)
|
||||
{
|
||||
struct qmp_usb *qmp = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
qmp->phy_initialized = false;
|
||||
|
||||
ret = qmp_usb_legacy_power_off(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -988,7 +996,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
|
||||
|
||||
dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
|
||||
|
||||
if (!qmp->phy->init_count) {
|
||||
if (!qmp->phy_initialized) {
|
||||
dev_vdbg(dev, "PHY not initialized, bailing out\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1009,7 +1017,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_resume(struct device *dev)
|
||||
|
||||
dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
|
||||
|
||||
if (!qmp->phy->init_count) {
|
||||
if (!qmp->phy_initialized) {
|
||||
dev_vdbg(dev, "PHY not initialized, bailing out\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1277,10 +1285,16 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
|
||||
/*
|
||||
* Enable runtime PM before creating the PHY, phy_create() only enables
|
||||
* it on the PHY device if already enabled on the parent. Hold a usage
|
||||
* reference so callbacks cannot run before qmp->phy is assigned.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
/*
|
||||
* Prevent runtime pm from being ON by default. Users can enable
|
||||
* it using power/control in sysfs.
|
||||
@@ -1289,23 +1303,31 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
|
||||
|
||||
ret = phy_pipe_clk_register(qmp, np);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
|
||||
qmp->phy = devm_phy_create(dev, np, &qmp_usb_legacy_phy_ops);
|
||||
if (IS_ERR(qmp->phy)) {
|
||||
ret = PTR_ERR(qmp->phy);
|
||||
dev_err(dev, "failed to create PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
phy_set_drvdata(qmp->phy, qmp);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
return 0;
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put_noidle(dev);
|
||||
err_node_put:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
|
||||
@@ -1434,6 +1434,8 @@ struct qmp_usb {
|
||||
|
||||
enum phy_mode mode;
|
||||
|
||||
bool phy_initialized;
|
||||
|
||||
struct phy *phy;
|
||||
|
||||
struct clk_fixed_rate pipe_clk_fixed;
|
||||
@@ -2009,6 +2011,7 @@ static int qmp_usb_power_off(struct phy *phy)
|
||||
|
||||
static int qmp_usb_enable(struct phy *phy)
|
||||
{
|
||||
struct qmp_usb *qmp = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = qmp_usb_init(phy);
|
||||
@@ -2018,14 +2021,19 @@ static int qmp_usb_enable(struct phy *phy)
|
||||
ret = qmp_usb_power_on(phy);
|
||||
if (ret)
|
||||
qmp_usb_exit(phy);
|
||||
else
|
||||
qmp->phy_initialized = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qmp_usb_disable(struct phy *phy)
|
||||
{
|
||||
struct qmp_usb *qmp = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
qmp->phy_initialized = false;
|
||||
|
||||
ret = qmp_usb_power_off(phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2101,7 +2109,7 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev)
|
||||
|
||||
dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
|
||||
|
||||
if (!qmp->phy->init_count) {
|
||||
if (!qmp->phy_initialized) {
|
||||
dev_vdbg(dev, "PHY not initialized, bailing out\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -2121,7 +2129,7 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev)
|
||||
|
||||
dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
|
||||
|
||||
if (!qmp->phy->init_count) {
|
||||
if (!qmp->phy_initialized) {
|
||||
dev_vdbg(dev, "PHY not initialized, bailing out\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -2411,10 +2419,16 @@ static int qmp_usb_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
|
||||
/*
|
||||
* Enable runtime PM before creating the PHY, phy_create() only enables
|
||||
* it on the PHY device if already enabled on the parent. Hold a usage
|
||||
* reference so callbacks cannot run before qmp->phy is assigned.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
/*
|
||||
* Prevent runtime pm from being ON by default. Users can enable
|
||||
* it using power/control in sysfs.
|
||||
@@ -2423,23 +2437,31 @@ static int qmp_usb_probe(struct platform_device *pdev)
|
||||
|
||||
ret = phy_pipe_clk_register(qmp, np);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
|
||||
qmp->phy = devm_phy_create(dev, np, &qmp_usb_phy_ops);
|
||||
if (IS_ERR(qmp->phy)) {
|
||||
ret = PTR_ERR(qmp->phy);
|
||||
dev_err(dev, "failed to create PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
phy_set_drvdata(qmp->phy, qmp);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
return 0;
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put_noidle(dev);
|
||||
err_node_put:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
|
||||
@@ -512,10 +512,14 @@ static const char * const usb3phy_reset_l[] = {
|
||||
"phy_phy", "phy",
|
||||
};
|
||||
|
||||
static const char * const usb3dpphy_reset_l[] = {
|
||||
static const char * const qcs615_usb3dpphy_reset_l[] = {
|
||||
"phy_phy", "dp_phy",
|
||||
};
|
||||
|
||||
static const char * const shikra_usb3dpphy_reset_l[] = {
|
||||
"phy_phy", "dp_phy", "phy",
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 68600 },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 14200 },
|
||||
@@ -680,8 +684,48 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
|
||||
.configure_dp_phy = qcs615_qmp_configure_dp_phy,
|
||||
.calibrate_dp_phy = qcs615_qmp_calibrate_dp_phy,
|
||||
|
||||
.reset_list = usb3dpphy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(usb3dpphy_reset_l),
|
||||
.reset_list = qcs615_usb3dpphy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(qcs615_usb3dpphy_reset_l),
|
||||
.vreg_list = qmp_phy_qcs615_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg shikra_usb3dp_phy_cfg = {
|
||||
.offsets = &qmp_usbc_usb3dp_offsets_qcs615,
|
||||
|
||||
.serdes_tbl = qcm2290_usb3_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
|
||||
.tx_tbl = qcm2290_usb3_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
|
||||
.rx_tbl = qcm2290_usb3_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
|
||||
.pcs_tbl = qcm2290_usb3_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
|
||||
|
||||
.regs = qmp_v3_usb3phy_regs_layout_qcm2290,
|
||||
|
||||
.dp_serdes_tbl = qcs615_dp_serdes_tbl,
|
||||
.dp_serdes_tbl_num = ARRAY_SIZE(qcs615_dp_serdes_tbl),
|
||||
.dp_tx_tbl = qcs615_dp_tx_tbl,
|
||||
.dp_tx_tbl_num = ARRAY_SIZE(qcs615_dp_tx_tbl),
|
||||
|
||||
.serdes_tbl_rbr = qcs615_dp_serdes_tbl_rbr,
|
||||
.serdes_tbl_rbr_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_rbr),
|
||||
.serdes_tbl_hbr = qcs615_dp_serdes_tbl_hbr,
|
||||
.serdes_tbl_hbr_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_hbr),
|
||||
.serdes_tbl_hbr2 = qcs615_dp_serdes_tbl_hbr2,
|
||||
.serdes_tbl_hbr2_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_hbr2),
|
||||
|
||||
.swing_tbl = &qcs615_dp_voltage_swing_hbr2_rbr,
|
||||
.pre_emphasis_tbl = &qcs615_dp_pre_emphasis_hbr2_rbr,
|
||||
|
||||
.dp_aux_init = qcs615_qmp_dp_aux_init,
|
||||
.configure_dp_tx = qcs615_qmp_configure_dp_tx,
|
||||
.configure_dp_phy = qcs615_qmp_configure_dp_phy,
|
||||
.calibrate_dp_phy = qcs615_qmp_calibrate_dp_phy,
|
||||
|
||||
.reset_list = shikra_usb3dpphy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(shikra_usb3dpphy_reset_l),
|
||||
.vreg_list = qmp_phy_qcs615_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l),
|
||||
};
|
||||
@@ -1959,10 +2003,16 @@ static int qmp_usbc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
|
||||
/*
|
||||
* Enable runtime PM before creating the PHYs, phy_create() only enables
|
||||
* it on the PHY devices if already enabled on the parent. Hold a usage
|
||||
* reference so callbacks cannot run until the PHY is ready.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
/*
|
||||
* Prevent runtime pm from being ON by default. Users can enable
|
||||
* it using power/control in sysfs.
|
||||
@@ -1971,13 +2021,13 @@ static int qmp_usbc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = qmp_usbc_register_clocks(qmp, np);
|
||||
if (ret)
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
|
||||
qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
|
||||
if (IS_ERR(qmp->usb_phy)) {
|
||||
ret = PTR_ERR(qmp->usb_phy);
|
||||
dev_err(dev, "failed to create PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
phy_set_drvdata(qmp->usb_phy, qmp);
|
||||
@@ -1987,17 +2037,25 @@ static int qmp_usbc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(qmp->dp_phy)) {
|
||||
ret = PTR_ERR(qmp->dp_phy);
|
||||
dev_err(dev, "failed to create PHY: %d\n", ret);
|
||||
goto err_node_put;
|
||||
goto err_pm_put;
|
||||
}
|
||||
phy_set_drvdata(qmp->dp_phy, qmp);
|
||||
}
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
return 0;
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put_noidle(dev);
|
||||
err_node_put:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
@@ -2019,6 +2077,9 @@ static const struct of_device_id qmp_usbc_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sdm660-qmp-usb3-phy",
|
||||
.data = &sdm660_usb3phy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,shikra-qmp-usb3-dp-phy",
|
||||
.data = &shikra_usb3dp_phy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm6115-qmp-usb3-phy",
|
||||
.data = &qcm2290_usb3phy_cfg,
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v8.h"
|
||||
#include "phy-qcom-qmp-qserdes-lalb-v8.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-com-v10.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v10.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-com-v10_60.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v10_60.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-pll.h"
|
||||
|
||||
#include "phy-qcom-qmp-pcs-v2.h"
|
||||
@@ -62,6 +68,10 @@
|
||||
|
||||
#include "phy-qcom-qmp-pcs-v8_50.h"
|
||||
|
||||
#include "phy-qcom-qmp-pcs-v10.h"
|
||||
|
||||
#include "phy-qcom-qmp-pcs-v10_60.h"
|
||||
|
||||
/* QPHY_SW_RESET bit */
|
||||
#define SW_RESET BIT(0)
|
||||
/* QPHY_POWER_DOWN_CONTROL */
|
||||
|
||||
@@ -381,6 +381,17 @@ static const struct qusb2_phy_cfg sdm660_phy_cfg = {
|
||||
.autoresume_en = BIT(3),
|
||||
};
|
||||
|
||||
static const struct qusb2_phy_cfg shikra_phy_cfg = {
|
||||
.tbl = qcs615_init_tbl,
|
||||
.tbl_num = ARRAY_SIZE(qcs615_init_tbl),
|
||||
.regs = msm8996_regs_layout,
|
||||
|
||||
.has_pll_test = true,
|
||||
.se_clk_scheme_default = true,
|
||||
.disable_ctrl = CLAMP_N_EN | FREEZIO_N | POWER_DOWN,
|
||||
.mask_core_ready = PLL_LOCKED,
|
||||
};
|
||||
|
||||
static const struct qusb2_phy_cfg sm6115_phy_cfg = {
|
||||
.tbl = sm6115_init_tbl,
|
||||
.tbl_num = ARRAY_SIZE(sm6115_init_tbl),
|
||||
@@ -958,6 +969,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sdm660-qusb2-phy",
|
||||
.data = &sdm660_phy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,shikra-qusb2-phy",
|
||||
.data = &shikra_phy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm4250-qusb2-phy",
|
||||
.data = &sm6115_phy_cfg,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "phy-qcom-qmp-pcs-sgmii.h"
|
||||
#include "phy-qcom-qmp-qserdes-com-v5.h"
|
||||
@@ -26,7 +27,15 @@
|
||||
#define QSERDES_PCS_SGMIIPHY_READY BIT(7)
|
||||
#define QSERDES_COM_C_PLL_LOCKED BIT(1)
|
||||
|
||||
static const struct regulator_bulk_data qcom_dwmac_sgmii_phy_vregs[] = {
|
||||
{ .supply = "vdda-0p9", .init_load_uA = 46000 },
|
||||
{ .supply = "vdda-1p2", .init_load_uA = 15000 },
|
||||
};
|
||||
|
||||
#define QCOM_SGMII_NUM_SUPPLIES ARRAY_SIZE(qcom_dwmac_sgmii_phy_vregs)
|
||||
|
||||
struct qcom_dwmac_sgmii_phy_data {
|
||||
struct regulator_bulk_data *vregs;
|
||||
struct regmap *regmap;
|
||||
struct clk *refclk;
|
||||
phy_interface_t interface;
|
||||
@@ -273,13 +282,24 @@ static int qcom_dwmac_sgmii_phy_power_on(struct phy *phy)
|
||||
struct qcom_dwmac_sgmii_phy_data *data = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(data->refclk);
|
||||
if (ret < 0)
|
||||
ret = regulator_bulk_enable(QCOM_SGMII_NUM_SUPPLIES, data->vregs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(data->refclk);
|
||||
if (ret)
|
||||
goto err_disable_regulators;
|
||||
|
||||
ret = qcom_dwmac_sgmii_phy_calibrate(phy);
|
||||
if (ret < 0)
|
||||
clk_disable_unprepare(data->refclk);
|
||||
if (ret)
|
||||
goto err_disable_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(data->refclk);
|
||||
err_disable_regulators:
|
||||
regulator_bulk_disable(QCOM_SGMII_NUM_SUPPLIES, data->vregs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -296,6 +316,8 @@ static int qcom_dwmac_sgmii_phy_power_off(struct phy *phy)
|
||||
|
||||
clk_disable_unprepare(data->refclk);
|
||||
|
||||
regulator_bulk_disable(QCOM_SGMII_NUM_SUPPLIES, data->vregs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -357,6 +379,7 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
|
||||
struct phy_provider *provider;
|
||||
void __iomem *base;
|
||||
struct phy *phy;
|
||||
int ret;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
@@ -381,6 +404,12 @@ static int qcom_dwmac_sgmii_phy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(data->refclk))
|
||||
return PTR_ERR(data->refclk);
|
||||
|
||||
ret = devm_regulator_bulk_get_const(dev, QCOM_SGMII_NUM_SUPPLIES,
|
||||
qcom_dwmac_sgmii_phy_vregs,
|
||||
&data->vregs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider))
|
||||
return PTR_ERR(provider);
|
||||
|
||||
@@ -599,8 +599,18 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to get regulator supplies\n");
|
||||
|
||||
/*
|
||||
* Enable runtime PM before creating the PHY, phy_create() only enables
|
||||
* it on the PHY device if already enabled on the parent. Hold a usage
|
||||
* reference so callbacks cannot run before the PHY is ready.
|
||||
*/
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Prevent runtime pm from being ON by default. Users can enable
|
||||
* it using power/control in sysfs.
|
||||
@@ -611,6 +621,7 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(generic_phy)) {
|
||||
ret = PTR_ERR(generic_phy);
|
||||
dev_err(dev, "failed to create phy, %d\n", ret);
|
||||
pm_runtime_put_noidle(dev);
|
||||
return ret;
|
||||
}
|
||||
hsphy->phy = generic_phy;
|
||||
@@ -620,12 +631,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
|
||||
qcom_snps_hsphy_read_override_param_seq(dev);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (!IS_ERR(phy_provider))
|
||||
dev_dbg(dev, "Registered Qcom-SNPS HS phy\n");
|
||||
else
|
||||
pm_runtime_disable(dev);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return PTR_ERR(phy_provider);
|
||||
}
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
dev_dbg(dev, "Registered Qcom-SNPS HS phy\n");
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver qcom_snps_hsphy_driver = {
|
||||
|
||||
@@ -405,7 +405,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
data->gen2_phy_ops);
|
||||
if (IS_ERR(phy->phy)) {
|
||||
dev_err(dev, "Failed to create PHY\n");
|
||||
of_node_put(np);
|
||||
return PTR_ERR(phy->phy);
|
||||
}
|
||||
phy_set_drvdata(phy->phy, phy);
|
||||
|
||||
@@ -721,6 +721,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
|
||||
.compatible = "renesas,usb2-phy-r9a08g045",
|
||||
.data = &rz_g3s_phy_usb2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,usb2-phy-r9a08g046",
|
||||
.data = &rz_g3s_phy_usb2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,usb2-phy-r9a09g057",
|
||||
.data = &rz_v2h_phy_usb2_data,
|
||||
@@ -898,18 +902,29 @@ static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_ge
|
||||
int ret;
|
||||
|
||||
channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
|
||||
if (IS_ERR(channel->vbus))
|
||||
return PTR_ERR(channel->vbus);
|
||||
if (IS_ERR(channel->vbus)) {
|
||||
ret = PTR_ERR(channel->vbus);
|
||||
/* If vbus-regulator node was present vbus regulator should be available */
|
||||
if (channel->otg_internal_reg)
|
||||
return ret;
|
||||
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
|
||||
if (!enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = regulator_enable(channel->vbus);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (enable) {
|
||||
ret = regulator_enable(channel->vbus);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action,
|
||||
channel->vbus);
|
||||
if (regulator_is_enabled(channel->vbus))
|
||||
return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action,
|
||||
channel->vbus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel)
|
||||
|
||||
@@ -69,6 +69,10 @@
|
||||
#define RK1808_CSIDPHY_CLK_CALIB_EN 0x168
|
||||
#define RK3568_CSIDPHY_CLK_CALIB_EN 0x168
|
||||
|
||||
#define CSIDPHY_LANE_CLK_3_PHASE 0x38
|
||||
#define CSIDPHY_CLK_PHASE_MASK GENMASK(6, 4)
|
||||
#define CSIDPHY_CLK_PHASE_DEFAULT 3
|
||||
|
||||
#define RESETS_MAX 2
|
||||
|
||||
/*
|
||||
@@ -151,6 +155,7 @@ struct rockchip_inno_csidphy {
|
||||
const struct dphy_drv_data *drv_data;
|
||||
struct phy_configure_opts_mipi_dphy config;
|
||||
u8 hsfreq;
|
||||
int clk_phase;
|
||||
};
|
||||
|
||||
static inline void write_grf_reg(struct rockchip_inno_csidphy *priv,
|
||||
@@ -170,7 +175,7 @@ static const struct hsfreq_range rk1808_mipidphy_hsfreq_ranges[] = {
|
||||
{ 299, 0x06}, { 399, 0x08}, { 499, 0x0b}, { 599, 0x0e},
|
||||
{ 699, 0x10}, { 799, 0x12}, { 999, 0x16}, {1199, 0x1e},
|
||||
{1399, 0x23}, {1599, 0x2d}, {1799, 0x32}, {1999, 0x37},
|
||||
{2199, 0x3c}, {2399, 0x41}, {2499, 0x46}
|
||||
{2199, 0x3c}, {2399, 0x41}, {2500, 0x46}
|
||||
};
|
||||
|
||||
static const struct hsfreq_range rk3326_mipidphy_hsfreq_ranges[] = {
|
||||
@@ -304,6 +309,13 @@ static int rockchip_inno_csidphy_power_on(struct phy *phy)
|
||||
rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq,
|
||||
CSIDPHY_LANE_THS_SETTLE(i));
|
||||
|
||||
if (priv->clk_phase >= 0) {
|
||||
val = readl(priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE);
|
||||
val &= ~CSIDPHY_CLK_PHASE_MASK;
|
||||
val |= FIELD_PREP(CSIDPHY_CLK_PHASE_MASK, priv->clk_phase);
|
||||
writel(val, priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE);
|
||||
}
|
||||
|
||||
write_grf_reg(priv, GRF_DPHY_CSIPHY_CLKLANE_EN, 0x1);
|
||||
write_grf_reg(priv, GRF_DPHY_CSIPHY_DATALANE_EN,
|
||||
GENMASK(priv->config.lanes - 1, 0));
|
||||
@@ -449,6 +461,7 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct phy *phy;
|
||||
u32 phase;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@@ -464,6 +477,18 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv->clk_phase = -1;
|
||||
if (device_property_read_u32(dev, "rockchip,clk-lane-phase",
|
||||
&phase) == 0) {
|
||||
if (phase > 7) {
|
||||
dev_warn(dev,
|
||||
"invalid rockchip,clk-lane-phase %u, using default %u\n",
|
||||
phase, CSIDPHY_CLK_PHASE_DEFAULT);
|
||||
phase = CSIDPHY_CLK_PHASE_DEFAULT;
|
||||
}
|
||||
priv->clk_phase = phase;
|
||||
}
|
||||
|
||||
priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"rockchip,grf");
|
||||
if (IS_ERR(priv->grf)) {
|
||||
|
||||
@@ -245,6 +245,7 @@ struct inno_hdmi_phy {
|
||||
struct clk *phyclk;
|
||||
unsigned long pixclock;
|
||||
unsigned long tmdsclock;
|
||||
unsigned long opts_tmds_char_rate;
|
||||
};
|
||||
|
||||
struct pre_pll_config {
|
||||
@@ -554,19 +555,10 @@ static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
|
||||
static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
|
||||
unsigned long rate)
|
||||
{
|
||||
int bus_width = phy_get_bus_width(inno->phy);
|
||||
if (inno->opts_tmds_char_rate)
|
||||
return inno->opts_tmds_char_rate;
|
||||
|
||||
switch (bus_width) {
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 10:
|
||||
case 12:
|
||||
case 16:
|
||||
return (u64)rate * bus_width / 8;
|
||||
default:
|
||||
return rate;
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
static irqreturn_t inno_hdmi_phy_rk3328_hardirq(int irq, void *dev_id)
|
||||
@@ -602,6 +594,57 @@ static irqreturn_t inno_hdmi_phy_rk3328_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* phy_validate() is expected to be called from encoder atomic_check(), before
|
||||
* the hdmiphy pixel clock is known. Without knowing the actual pixel clock, we
|
||||
* cannot do full validation of the configuration. Instead, we do a simple check
|
||||
* that the pre-pll table contains an entry for the requested TMDS char rate.
|
||||
*/
|
||||
static int inno_hdmi_phy_validate(struct phy *phy, enum phy_mode mode,
|
||||
int submode, union phy_configure_opts *opts)
|
||||
{
|
||||
const struct pre_pll_config *cfg = pre_pll_cfg_table;
|
||||
unsigned long tmdsclock;
|
||||
|
||||
if (!(mode == PHY_MODE_HDMI && submode == PHY_HDMI_MODE_TMDS))
|
||||
return -EINVAL;
|
||||
|
||||
if (!opts)
|
||||
return -EINVAL;
|
||||
|
||||
if (!opts->hdmi.tmds_char_rate || opts->hdmi.tmds_char_rate > 594000000)
|
||||
return -EINVAL;
|
||||
|
||||
tmdsclock = opts->hdmi.tmds_char_rate;
|
||||
for (; cfg->pixclock != 0; cfg++)
|
||||
if (cfg->tmdsclock == tmdsclock)
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* phy_configure() is expected to be called from encoder atomic_set_mode(),
|
||||
* before the hdmiphy pixel clock is known. Store the requested TMDS character
|
||||
* rate, so that it can be used later in power_on() and/or set_rate() when the
|
||||
* pixel clock is known.
|
||||
*/
|
||||
static int inno_hdmi_phy_configure(struct phy *phy,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = inno_hdmi_phy_validate(phy, phy_get_mode(phy),
|
||||
PHY_HDMI_MODE_TMDS, opts);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
inno->opts_tmds_char_rate = opts->hdmi.tmds_char_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inno_hdmi_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
|
||||
@@ -670,6 +713,8 @@ static const struct phy_ops inno_hdmi_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.power_on = inno_hdmi_phy_power_on,
|
||||
.power_off = inno_hdmi_phy_power_off,
|
||||
.configure = inno_hdmi_phy_configure,
|
||||
.validate = inno_hdmi_phy_validate,
|
||||
};
|
||||
|
||||
static const
|
||||
@@ -1392,7 +1437,7 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
phy_set_drvdata(inno->phy, inno);
|
||||
phy_set_bus_width(inno->phy, 8);
|
||||
phy_set_mode_ext(inno->phy, PHY_MODE_HDMI, PHY_HDMI_MODE_TMDS);
|
||||
|
||||
if (inno->plat_data->ops->init) {
|
||||
ret = inno->plat_data->ops->init(inno);
|
||||
|
||||
@@ -1526,7 +1526,7 @@ static const struct regmap_config samsung_mipi_dcphy_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0x10000,
|
||||
.max_register = 0xfffc,
|
||||
};
|
||||
|
||||
static struct phy *samsung_mipi_dcphy_xlate(struct device *dev,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
|
||||
* Copyright (c) 2024 Collabora Ltd.
|
||||
* Copyright (c) 2024-2026 Collabora Ltd.
|
||||
*
|
||||
* Author: Algea Cao <algea.cao@rock-chips.com>
|
||||
* Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hw_bitfield.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@@ -52,6 +53,12 @@
|
||||
/* CMN_REG(001e) */
|
||||
#define LCPLL_PI_EN_MASK BIT(5)
|
||||
#define LCPLL_100M_CLK_EN_MASK BIT(0)
|
||||
/* CMN_REG(0022) */
|
||||
#define ANA_LCPLL_PMS_PDIV_MASK GENMASK(7, 4)
|
||||
#define ANA_LCPLL_PMS_REFDIV_MASK GENMASK(3, 0)
|
||||
/* CMN_REG(0023) */
|
||||
#define LCPLL_PMS_SDIV_RBR_MASK GENMASK(7, 4)
|
||||
#define LCPLL_PMS_SDIV_HBR_MASK GENMASK(3, 0)
|
||||
/* CMN_REG(0025) */
|
||||
#define LCPLL_PMS_IQDIV_RSTN_MASK BIT(4)
|
||||
/* CMN_REG(0028) */
|
||||
@@ -413,7 +420,7 @@ struct rk_hdptx_phy {
|
||||
|
||||
/* clk provider */
|
||||
struct clk_hw hw;
|
||||
bool restrict_rate_change;
|
||||
bool pll_config_dirty;
|
||||
|
||||
atomic_t usage_count;
|
||||
|
||||
@@ -949,7 +956,9 @@ static void rk_hdptx_pre_power_up(struct rk_hdptx_phy *hdptx)
|
||||
reset_control_assert(hdptx->rsts[RST_CMN].rstc);
|
||||
reset_control_assert(hdptx->rsts[RST_INIT].rstc);
|
||||
|
||||
val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
|
||||
val = (FIELD_PREP_WM16(HDPTX_I_PLL_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 0));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
}
|
||||
|
||||
@@ -960,8 +969,8 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
|
||||
|
||||
reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
|
||||
|
||||
val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
|
||||
HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
|
||||
val = (FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 1) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 1));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
|
||||
/* 3 lanes FRL mode */
|
||||
@@ -990,16 +999,15 @@ static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx)
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
|
||||
HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
|
||||
val = (FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 1) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 1));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
|
||||
usleep_range(10, 15);
|
||||
reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
|
||||
|
||||
usleep_range(10, 15);
|
||||
val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(HDPTX_I_PLL_EN, 1));
|
||||
|
||||
usleep_range(10, 15);
|
||||
reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
|
||||
@@ -1037,7 +1045,9 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
|
||||
reset_control_assert(hdptx->rsts[RST_CMN].rstc);
|
||||
reset_control_assert(hdptx->rsts[RST_INIT].rstc);
|
||||
|
||||
val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
|
||||
val = (FIELD_PREP_WM16(HDPTX_I_PLL_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 0));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
|
||||
}
|
||||
|
||||
@@ -1135,7 +1145,7 @@ static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
|
||||
rk_hdptx_pre_power_up(hdptx);
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(LC_REF_CLK_SEL, 0));
|
||||
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_cmn_init_seq);
|
||||
@@ -1153,9 +1163,11 @@ static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv);
|
||||
regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc);
|
||||
regmap_write(hdptx->regmap, CMN_REG(0022),
|
||||
(cfg->pms_pdiv << 4) | cfg->pms_refdiv);
|
||||
FIELD_PREP(ANA_LCPLL_PMS_PDIV_MASK, cfg->pms_pdiv) |
|
||||
FIELD_PREP(ANA_LCPLL_PMS_REFDIV_MASK, cfg->pms_refdiv));
|
||||
regmap_write(hdptx->regmap, CMN_REG(0023),
|
||||
(cfg->pms_sdiv << 4) | cfg->pms_sdiv);
|
||||
FIELD_PREP(LCPLL_PMS_SDIV_RBR_MASK, cfg->pms_sdiv) |
|
||||
FIELD_PREP(LCPLL_PMS_SDIV_HBR_MASK, cfg->pms_sdiv));
|
||||
regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno);
|
||||
regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign);
|
||||
regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num);
|
||||
@@ -1178,8 +1190,7 @@ static int rk_hdptx_frl_lcpll_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
rk_hdptx_pre_power_up(hdptx);
|
||||
|
||||
/* ROPLL input reference clock from LCPLL (cascade mode) */
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
(LC_REF_CLK_SEL << 16) | LC_REF_CLK_SEL);
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(LC_REF_CLK_SEL, 1));
|
||||
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_ropll_cmn_init_seq);
|
||||
@@ -1218,7 +1229,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
|
||||
rk_hdptx_pre_power_up(hdptx);
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(LC_REF_CLK_SEL, 0));
|
||||
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
|
||||
@@ -1226,8 +1237,10 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
|
||||
regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
|
||||
regmap_write(hdptx->regmap, CMN_REG(0059),
|
||||
(cfg->pms_pdiv << 4) | cfg->pms_refdiv);
|
||||
regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);
|
||||
FIELD_PREP(ANA_ROPLL_PMS_PDIV_MASK, cfg->pms_pdiv) |
|
||||
FIELD_PREP(ANA_ROPLL_PMS_REFDIV_MASK, cfg->pms_refdiv));
|
||||
regmap_write(hdptx->regmap, CMN_REG(005a),
|
||||
FIELD_PREP(ROPLL_PMS_SDIV_RBR_MASK, cfg->pms_sdiv));
|
||||
|
||||
regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
|
||||
FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
|
||||
@@ -1260,13 +1273,19 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
|
||||
static int rk_hdptx_pll_cmn_config(struct rk_hdptx_phy *hdptx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (hdptx->hdmi_cfg.rate <= HDMI20_MAX_RATE)
|
||||
return rk_hdptx_tmds_ropll_cmn_config(hdptx);
|
||||
ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
|
||||
else if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE)
|
||||
ret = rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx);
|
||||
else
|
||||
ret = rk_hdptx_frl_lcpll_cmn_config(hdptx);
|
||||
|
||||
if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE)
|
||||
return rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx);
|
||||
if (!ret)
|
||||
hdptx->pll_config_dirty = false;
|
||||
|
||||
return rk_hdptx_frl_lcpll_cmn_config(hdptx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_hdptx_frl_lcpll_mode_config(struct rk_hdptx_phy *hdptx)
|
||||
@@ -1330,11 +1349,9 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
|
||||
FIELD_PREP(LN_TX_DRV_EI_EN_MASK, 0));
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x0));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x0));
|
||||
FIELD_PREP_WM16(HDPTX_I_PLL_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 0) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 0));
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
|
||||
@@ -1347,25 +1364,22 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);
|
||||
if (ret)
|
||||
goto dec_usage;
|
||||
|
||||
if (status & HDPTX_O_PLL_LOCK_DONE)
|
||||
dev_warn(hdptx->dev, "PLL locked by unknown consumer!\n");
|
||||
if (ret) {
|
||||
atomic_dec(&hdptx->usage_count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mode == PHY_MODE_DP) {
|
||||
rk_hdptx_dp_reset(hdptx);
|
||||
} else {
|
||||
ret = rk_hdptx_pll_cmn_config(hdptx);
|
||||
if (ret)
|
||||
goto dec_usage;
|
||||
/*
|
||||
* Ignore PLL config errors at this point as pll_config_dirty
|
||||
* was not reset and, therefore, operation will be retried.
|
||||
*/
|
||||
rk_hdptx_pll_cmn_config(hdptx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
dec_usage:
|
||||
atomic_dec(&hdptx->usage_count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
|
||||
@@ -1613,9 +1627,8 @@ static int rk_hdptx_dp_aux_init(struct rk_hdptx_phy *hdptx)
|
||||
FIELD_PREP(OVRD_SB_VREG_EN_MASK, 0x1));
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_BGR_EN << 16 | FIELD_PREP(HDPTX_I_BGR_EN, 0x1));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_BIAS_EN << 16 | FIELD_PREP(HDPTX_I_BIAS_EN, 0x1));
|
||||
FIELD_PREP_WM16(HDPTX_I_BGR_EN, 1) |
|
||||
FIELD_PREP_WM16(HDPTX_I_BIAS_EN, 1));
|
||||
usleep_range(20, 25);
|
||||
|
||||
reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
|
||||
@@ -1656,29 +1669,13 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
enum phy_mode mode = phy_get_mode(phy);
|
||||
int ret, lane;
|
||||
|
||||
if (mode != PHY_MODE_DP) {
|
||||
if (!hdptx->hdmi_cfg.rate && hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) {
|
||||
/*
|
||||
* FIXME: Temporary workaround to setup TMDS char rate
|
||||
* from the RK DW HDMI QP bridge driver.
|
||||
* Will be removed as soon the switch to the HDMI PHY
|
||||
* configuration API has been completed on both ends.
|
||||
*/
|
||||
hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
|
||||
hdptx->hdmi_cfg.rate *= 100;
|
||||
}
|
||||
|
||||
dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
|
||||
hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
|
||||
}
|
||||
|
||||
ret = rk_hdptx_phy_consumer_get(hdptx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mode == PHY_MODE_DP) {
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x1));
|
||||
FIELD_PREP_WM16(HDPTX_MODE_SEL, 1));
|
||||
|
||||
for (lane = 0; lane < 4; lane++) {
|
||||
regmap_update_bits(hdptx->regmap, LANE_REG(031e) + 0x400 * lane,
|
||||
@@ -1697,21 +1694,27 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
rk_hdptx_dp_pll_init(hdptx);
|
||||
|
||||
ret = rk_hdptx_dp_aux_init(hdptx);
|
||||
if (ret)
|
||||
rk_hdptx_phy_consumer_put(hdptx, true);
|
||||
} else {
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
|
||||
dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
|
||||
hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
|
||||
|
||||
if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
|
||||
ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
|
||||
else
|
||||
ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
|
||||
if (hdptx->pll_config_dirty)
|
||||
ret = rk_hdptx_pll_cmn_config(hdptx);
|
||||
|
||||
if (ret)
|
||||
rk_hdptx_phy_consumer_put(hdptx, true);
|
||||
if (!ret) {
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
FIELD_PREP_WM16(HDPTX_MODE_SEL, 0));
|
||||
|
||||
if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
|
||||
ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
|
||||
else
|
||||
ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
rk_hdptx_phy_consumer_put(hdptx, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1835,8 +1838,7 @@ static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
|
||||
u32 bw, status;
|
||||
int ret;
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x0));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(HDPTX_I_PLL_EN, 0));
|
||||
|
||||
switch (dp->link_rate) {
|
||||
case 1620:
|
||||
@@ -1892,8 +1894,7 @@ static int rk_hdptx_phy_set_rate(struct rk_hdptx_phy *hdptx,
|
||||
regmap_update_bits(hdptx->regmap, CMN_REG(0095), DP_TX_LINK_BW_MASK,
|
||||
FIELD_PREP(DP_TX_LINK_BW_MASK, bw));
|
||||
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0,
|
||||
HDPTX_I_PLL_EN << 16 | FIELD_PREP(HDPTX_I_PLL_EN, 0x1));
|
||||
regmap_write(hdptx->grf, GRF_HDPTX_CON0, FIELD_PREP_WM16(HDPTX_I_PLL_EN, 1));
|
||||
|
||||
ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS,
|
||||
status, FIELD_GET(HDPTX_O_PLL_LOCK_DONE, status),
|
||||
@@ -2080,8 +2081,10 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt
|
||||
if (ret) {
|
||||
dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
|
||||
} else {
|
||||
hdptx->restrict_rate_change = true;
|
||||
dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
|
||||
hdptx->pll_config_dirty = true;
|
||||
|
||||
dev_dbg(hdptx->dev, "%s %s rate=%llu bpc=%u\n", __func__,
|
||||
hdptx->hdmi_cfg.mode ? "FRL" : "TMDS",
|
||||
hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
|
||||
}
|
||||
|
||||
@@ -2168,7 +2171,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
struct lcpll_config lcpll_hw;
|
||||
struct ropll_config ropll_hw;
|
||||
u64 fout, sdm;
|
||||
u32 mode, val;
|
||||
u32 mode, bpc, val;
|
||||
int ret, i;
|
||||
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
|
||||
@@ -2184,7 +2187,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0023), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
lcpll_hw.pms_sdiv = val & 0xf;
|
||||
lcpll_hw.pms_sdiv = FIELD_GET(LCPLL_PMS_SDIV_HBR_MASK, val);
|
||||
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(002B), &val);
|
||||
if (ret)
|
||||
@@ -2204,18 +2207,33 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(002D), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
lcpll_hw.sdc_n = (val & LCPLL_SDC_N_MASK) >> 1;
|
||||
lcpll_hw.sdc_n = FIELD_GET(LCPLL_SDC_N_MASK, val);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
|
||||
const struct lcpll_config *cfg = &rk_hdptx_frl_lcpll_cfg[i];
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
if (cfg->pms_mdiv == lcpll_hw.pms_mdiv &&
|
||||
cfg->pms_sdiv == lcpll_hw.pms_sdiv &&
|
||||
cfg->sdm_num_sign == lcpll_hw.sdm_num_sign &&
|
||||
cfg->sdm_num == lcpll_hw.sdm_num &&
|
||||
cfg->sdm_deno == lcpll_hw.sdm_deno &&
|
||||
cfg->sdc_n == lcpll_hw.sdc_n)
|
||||
return cfg->rate;
|
||||
if (val & LC_REF_CLK_SEL) {
|
||||
if (lcpll_hw.pms_mdiv == 0x6b &&
|
||||
lcpll_hw.sdm_num_sign == 0x01 &&
|
||||
lcpll_hw.sdm_num == 0x02 &&
|
||||
lcpll_hw.sdm_deno == 0x09 &&
|
||||
lcpll_hw.sdc_n == FIELD_GET(LCPLL_SDC_N_MASK, 0x02))
|
||||
return FRL_8G4L_RATE;
|
||||
} else {
|
||||
const struct lcpll_config *cfg;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
|
||||
cfg = &rk_hdptx_frl_lcpll_cfg[i];
|
||||
|
||||
if (cfg->pms_mdiv == lcpll_hw.pms_mdiv &&
|
||||
cfg->pms_sdiv == lcpll_hw.pms_sdiv &&
|
||||
cfg->sdm_num_sign == lcpll_hw.sdm_num_sign &&
|
||||
cfg->sdm_num == lcpll_hw.sdm_num &&
|
||||
cfg->sdm_deno == lcpll_hw.sdm_deno &&
|
||||
cfg->sdc_n == lcpll_hw.sdc_n)
|
||||
return cfg->rate;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(hdptx->dev, "%s no FRL match found\n", __func__);
|
||||
@@ -2230,12 +2248,12 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK;
|
||||
ropll_hw.sdm_en = FIELD_GET(ROPLL_SDM_EN_MASK, val);
|
||||
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK;
|
||||
ropll_hw.sdm_num_sign = FIELD_GET(ROPLL_SDM_NUM_SIGN_RBR_MASK, val);
|
||||
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val);
|
||||
if (ret)
|
||||
@@ -2250,7 +2268,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3;
|
||||
ropll_hw.sdc_n = FIELD_GET(ROPLL_SDC_N_RBR_MASK, val) + 3;
|
||||
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val);
|
||||
if (ret)
|
||||
@@ -2265,22 +2283,43 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
|
||||
ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val);
|
||||
if (ret)
|
||||
return 0;
|
||||
ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1;
|
||||
ropll_hw.pms_sdiv = FIELD_GET(PLL_PCG_POSTDIV_SEL_MASK, val) + 1;
|
||||
bpc = (FIELD_GET(PLL_PCG_CLK_SEL_MASK, val) << 1) + 8;
|
||||
|
||||
fout = PLL_REF_CLK * ropll_hw.pms_mdiv;
|
||||
if (ropll_hw.sdm_en) {
|
||||
sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno *
|
||||
ropll_hw.pms_mdiv * ropll_hw.sdm_num,
|
||||
16 * ropll_hw.sdm_deno *
|
||||
(ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num));
|
||||
val = 16U * ropll_hw.sdm_deno *
|
||||
(ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num);
|
||||
if (!val) {
|
||||
/*
|
||||
* The PLL config currently stored in hardware can't be
|
||||
* translated into a rate. The next .set_rate() should
|
||||
* program a valid configuration and help with recovery.
|
||||
*/
|
||||
dev_dbg(hdptx->dev, "Invalid ROPLL hw state: deno == 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno *
|
||||
ropll_hw.pms_mdiv * ropll_hw.sdm_num, val);
|
||||
|
||||
if (ropll_hw.sdm_num_sign) {
|
||||
if (sdm > fout) {
|
||||
/*
|
||||
* Similarly to the case above, it is expected
|
||||
* the next .set_rate() will help with recovery.
|
||||
*/
|
||||
dev_dbg(hdptx->dev, "Invalid ROPLL hw state: sdm > fout\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ropll_hw.sdm_num_sign)
|
||||
fout = fout - sdm;
|
||||
else
|
||||
} else {
|
||||
fout = fout + sdm;
|
||||
}
|
||||
}
|
||||
|
||||
return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
|
||||
return DIV_ROUND_CLOSEST_ULL(fout * 2 * 8, ropll_hw.pms_sdiv * 10 * bpc);
|
||||
}
|
||||
|
||||
static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
||||
@@ -2288,19 +2327,13 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
u32 status;
|
||||
u64 rate;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
|
||||
if (ret || !(status & HDPTX_I_PLL_EN))
|
||||
return 0;
|
||||
|
||||
rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
|
||||
|
||||
if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
|
||||
return rate;
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
|
||||
return rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
|
||||
@@ -2308,31 +2341,18 @@ static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
|
||||
if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
|
||||
return hdptx->hdmi_cfg.rate;
|
||||
|
||||
/*
|
||||
* FIXME: Temporarily allow altering TMDS char rate via CCF.
|
||||
* To be dropped as soon as the RK DW HDMI QP bridge driver
|
||||
* switches to make use of phy_configure().
|
||||
* For uncommitted PLL configuration, invalidate the current clock rate
|
||||
* to ensure rk_hdptx_phy_clk_set_rate() will be always invoked.
|
||||
* Otherwise, restrict the rate according to the PHY link setup.
|
||||
*/
|
||||
if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.rate) {
|
||||
struct phy_configure_opts_hdmi hdmi = {
|
||||
.tmds_char_rate = req->rate,
|
||||
};
|
||||
|
||||
int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi, &hdptx->hdmi_cfg);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The TMDS char rate shall be adjusted via phy_configure() only,
|
||||
* hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
|
||||
* a different rate argument.
|
||||
*/
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8, hdptx->hdmi_cfg.bpc);
|
||||
if (hdptx->pll_config_dirty)
|
||||
req->rate = 0;
|
||||
else if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
|
||||
req->rate = hdptx->hdmi_cfg.rate;
|
||||
else
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8,
|
||||
hdptx->hdmi_cfg.bpc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2341,17 +2361,6 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
unsigned long long link_rate = rate;
|
||||
|
||||
if (hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL)
|
||||
link_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
|
||||
|
||||
/* Revert any unlikely link rate change since determine_rate() */
|
||||
if (hdptx->hdmi_cfg.rate != link_rate) {
|
||||
dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
|
||||
link_rate, hdptx->hdmi_cfg.rate);
|
||||
hdptx->hdmi_cfg.rate = link_rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* The link rate would be normally programmed in HW during
|
||||
|
||||
@@ -23,3 +23,19 @@ config PHY_SPACEMIT_K1_USB2
|
||||
help
|
||||
Enable this to support K1 USB 2.0 PHY driver. This driver takes care of
|
||||
enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
|
||||
|
||||
config PHY_SPACEMIT_K3_COMMON_OPS
|
||||
tristate
|
||||
select MFD_SYSCON
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_SPACEMIT_K3_COMBO_PHY
|
||||
tristate "SpacemiT K3 USB3/PCIe PHY support"
|
||||
depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
|
||||
depends on COMMON_CLK
|
||||
select PHY_SPACEMIT_K3_COMMON_OPS
|
||||
help
|
||||
Enable this to support K3 USB3/PCIe combo PHY driver. This
|
||||
driver takes care of enabling and clock setup and will be used
|
||||
by K3 dwc3 driver.
|
||||
If unsure, say N.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-k1-pcie.o
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K3_COMBO_PHY) += phy-k3-combo.o
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K3_COMMON_OPS) += phy-k3-common.o
|
||||
|
||||
252
drivers/phy/spacemit/phy-k3-combo.c
Normal file
252
drivers/phy/spacemit/phy-k3-combo.c
Normal file
@@ -0,0 +1,252 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* phy-k3-combo.c - SpacemiT K3 PCIe/USB3 Combo PHY Driver
|
||||
*
|
||||
* Copyright (c) 2025 SpacemiT Technology Co. Ltd
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/phy/phy.h>
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
#include "phy-k3-common.h"
|
||||
|
||||
/*
|
||||
* The PCIE/USB Subsystem on SpacemiT K3 have 3 single lane PIPE3 PHYs
|
||||
* (PHY2/3/4) shared by PCIE PortC/D and USB3 PortB/C/D.
|
||||
*
|
||||
* PMUA_PCIE_SUBSYS_MGMT[4:0]
|
||||
*
|
||||
* bit4 = 0 : PCIe A X8 mode, all 8 lanes dedicated to PCIe Port A
|
||||
* 1 : PHY lanes shared between PCIe or USB according to [3:0]
|
||||
*
|
||||
* All PHY matrix combinations according to [4:0]:
|
||||
*
|
||||
* 0x0X : PCIe-A X8
|
||||
* 0x10 : PCIe-C x2 (PHY2+PHY3) + PCIe-D x1 (PHY4)
|
||||
* 0x11 : PCIe-C x2 (PHY2+PHY3) + USB-D (PHY4)
|
||||
* 0x12 : PCIe-C x1 (PHY2) + USB-C (PHY3)
|
||||
* 0x13 : PCIe-C x1 (PHY2) + USB-C (PHY3) + USB-D (PHY4)
|
||||
* 0x14 : PCIe-C x1 (PHY3) + USB-B (PHY2)
|
||||
* 0x15 : PCIe-C x1 (PHY3) + USB-B (PHY2) + USB-D (PHY4)
|
||||
* 0x16 : USB-B (PHY2) + USB-C (PHY3) + PCIe D x1 (PHY4)
|
||||
* 0x17 : USB-B (PHY2) + USB-C (PHY3) + USB-D (PHY4)
|
||||
*
|
||||
* So any USB Port B/C/D operation requires PCIe A X8 mode to be disabled.
|
||||
*/
|
||||
#define PMUA_PCIE_SUBSYS_MGMT 0x1d8
|
||||
#define PU_MATRIX_CONF_MASK GENMASK(4, 0)
|
||||
|
||||
#define COMBPHY_MAX_SUBPHYS 6
|
||||
|
||||
struct k3_combo_phy {
|
||||
struct device *dev;
|
||||
struct k3_lane_group groups[COMBPHY_MAX_SUBPHYS];
|
||||
void __iomem *base;
|
||||
struct regmap *apb_spare;
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group0 = {
|
||||
.lanes = 2,
|
||||
.config = 0xff,
|
||||
.mask = 0x00,
|
||||
.offsets = {
|
||||
0x0, 0x400
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group1 = {
|
||||
.lanes = 2,
|
||||
.config = 0xff,
|
||||
.mask = 0x00,
|
||||
.offsets = {
|
||||
0x100000, 0x100400
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group2 = {
|
||||
.lanes = 1,
|
||||
.config = 0x14,
|
||||
.mask = 0x14,
|
||||
.offsets = {
|
||||
0x200000
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group3 = {
|
||||
.lanes = 1,
|
||||
.config = 0x12,
|
||||
.mask = 0x12,
|
||||
.offsets = {
|
||||
0x300000
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group4 = {
|
||||
.lanes = 1,
|
||||
.config = 0x11,
|
||||
.mask = 0x11,
|
||||
.offsets = {
|
||||
0x400000
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data k3_combphy_lane_group5 = {
|
||||
.lanes = 1,
|
||||
.config = 0xff,
|
||||
.mask = 0x00,
|
||||
.offsets = {
|
||||
0x500000
|
||||
},
|
||||
};
|
||||
|
||||
static const struct k3_phy_lane_group_data *k3_combphy_lane_datas[] = {
|
||||
&k3_combphy_lane_group0,
|
||||
&k3_combphy_lane_group1,
|
||||
&k3_combphy_lane_group2,
|
||||
&k3_combphy_lane_group3,
|
||||
&k3_combphy_lane_group4,
|
||||
&k3_combphy_lane_group5,
|
||||
};
|
||||
|
||||
static int k3_combo_phy_init_lanes(struct k3_combo_phy *phy, unsigned int config)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(k3_combphy_lane_datas); i++) {
|
||||
const struct k3_phy_lane_group_data *data = k3_combphy_lane_datas[i];
|
||||
struct k3_lane_group *lg = &phy->groups[i];
|
||||
const struct phy_ops *ops;
|
||||
bool is_usb;
|
||||
|
||||
is_usb = (data->mask & config) == data->config;
|
||||
if (is_usb)
|
||||
ops = &k3_usb3_phy_ops;
|
||||
else
|
||||
ops = &k3_pcie_phy_ops;
|
||||
|
||||
dev_dbg(phy->dev, "phy %d is %s\n", i, is_usb ? "usb" : "pcie");
|
||||
|
||||
lg->phy = devm_phy_create(phy->dev, NULL, ops);
|
||||
if (IS_ERR(lg->phy))
|
||||
return PTR_ERR(lg->phy);
|
||||
|
||||
lg->is_pcie = !is_usb;
|
||||
lg->data = data;
|
||||
lg->base = phy->base;
|
||||
phy_set_drvdata(lg->phy, lg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int k3_combo_phy_update_config(struct regmap *apmu, unsigned int config)
|
||||
{
|
||||
if (config & ~PU_MATRIX_CONF_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return regmap_update_bits(apmu, PMUA_PCIE_SUBSYS_MGMT, PU_MATRIX_CONF_MASK, config);
|
||||
}
|
||||
|
||||
static struct phy *k3_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
|
||||
{
|
||||
struct k3_combo_phy *phy = dev_get_drvdata(dev);
|
||||
struct k3_lane_group *lg;
|
||||
|
||||
if (args->args_count != 2) {
|
||||
dev_err(dev, "Invalid number of arguments\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (args->args[0] >= ARRAY_SIZE(k3_combphy_lane_datas)) {
|
||||
dev_err(dev, "Invalid PHY id\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
lg = &phy->groups[args->args[0]];
|
||||
|
||||
if ((lg->is_pcie && args->args[1] != PHY_TYPE_PCIE) ||
|
||||
(!lg->is_pcie && args->args[1] != PHY_TYPE_USB3)) {
|
||||
dev_err(dev, "Invalid PHY mode\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return lg->phy;
|
||||
}
|
||||
|
||||
static int k3_combo_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct phy_provider *provider;
|
||||
struct k3_combo_phy *phy;
|
||||
struct regmap *apmu;
|
||||
u32 config = 0;
|
||||
int ret;
|
||||
|
||||
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->base))
|
||||
return PTR_ERR(phy->base);
|
||||
|
||||
phy->apb_spare = syscon_regmap_lookup_by_phandle(node, "spacemit,apb-spare");
|
||||
if (IS_ERR(phy->apb_spare))
|
||||
return dev_err_probe(dev, PTR_ERR(phy->apb_spare),
|
||||
"Failed to find APB SPARE syscon");
|
||||
|
||||
apmu = syscon_regmap_lookup_by_phandle_args(node, "spacemit,apmu", 1, &config);
|
||||
if (IS_ERR(apmu))
|
||||
return dev_err_probe(dev, PTR_ERR(apmu),
|
||||
"Failed to find APMU syscon");
|
||||
|
||||
ret = k3_combo_phy_update_config(apmu, config);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to set lane configuration");
|
||||
|
||||
phy->dev = dev;
|
||||
platform_set_drvdata(pdev, phy);
|
||||
|
||||
ret = k3_phy_calibrate(phy->apb_spare);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to calibrate phy");
|
||||
|
||||
ret = k3_combo_phy_init_lanes(phy, config);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to init lanes");
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, k3_combo_phy_xlate);
|
||||
if (IS_ERR(provider))
|
||||
return dev_err_probe(dev, PTR_ERR(provider),
|
||||
"Failed to register provider\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id k3_combo_phy_of_match[] = {
|
||||
{ .compatible = "spacemit,k3-combo-phy" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, k3_combo_phy_of_match);
|
||||
|
||||
static struct platform_driver k3_combo_phy_driver = {
|
||||
.probe = k3_combo_phy_probe,
|
||||
.driver = {
|
||||
.name = "spacemit,k3-combo-phy",
|
||||
.of_match_table = k3_combo_phy_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(k3_combo_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("SpacemiT K3 USB3/PCIe combo PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
391
drivers/phy/spacemit/phy-k3-common.c
Normal file
391
drivers/phy/spacemit/phy-k3-common.c
Normal file
@@ -0,0 +1,391 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
#include "phy-k3-common.h"
|
||||
|
||||
/* PHY Registers */
|
||||
#define PHY_VERSION 0x0
|
||||
|
||||
#define PHY_RESET_CFG 0x04
|
||||
|
||||
#define PHY_RESET_RXBUF_RST BIT(0)
|
||||
#define PHY_RESET_SOFT_RST_PCS BIT(1)
|
||||
#define PHY_RESET_SOFT_RST_AHB BIT(2)
|
||||
#define PHY_RESET_EN_SD_AFTER_LOCK BIT(6)
|
||||
|
||||
#define PHY_CLK_CFG 0x08
|
||||
|
||||
#define PHY_CLK_PLL_READY BIT(0)
|
||||
#define PHY_CLK_TXCLK_INV BIT(2)
|
||||
#define PHY_CLK_RXCLK_EN BIT(3)
|
||||
#define PHY_CLK_TXCLK_EN BIT(4)
|
||||
#define PHY_CLK_PCLK_EN BIT(5)
|
||||
#define PHY_CLK_PIPE_PCLK_EN BIT(6)
|
||||
#define PHY_CLK_REFCLK_FREQ GENMASK(10, 7)
|
||||
#define PHY_CLK_REFCLK_24M 2
|
||||
#define PHY_CLK_SW_INIT_DONE BIT(11)
|
||||
#define PHY_CLK_PU_SSC_OUT BIT(23)
|
||||
|
||||
#define PHY_MODE_CFG 0x0C
|
||||
|
||||
#define PHY_MODE_PCIE_INT_EN BIT(0)
|
||||
#define PHY_MODE_LFPS_TPERIOD GENMASK(9, 8)
|
||||
#define PHY_MODE_LFPS_TPERIOD_USB 3
|
||||
|
||||
#define PHY_PU_SEL 0x40
|
||||
|
||||
#define PHY_PU_CFG_STATUS BIT(9)
|
||||
#define PHY_PU_OVRD_STATUS BIT(10)
|
||||
|
||||
#define PHY_PU_CK_REG 0x54
|
||||
|
||||
#define PHY_PU_REFCLK_100 BIT(25)
|
||||
|
||||
#define PHY_PLL_REG1 0x58
|
||||
|
||||
#define PHY_PLL_FREF_SEL GENMASK(15, 13)
|
||||
#define PHY_PLL_FREF_24M 0x1
|
||||
#define PHY_PLL_SSC_DEP_SEL GENMASK(27, 24)
|
||||
#define PHY_PLL_SSC_5000PPM 0xa
|
||||
#define PHY_PLL_SSC_MODE GENMASK(29, 28)
|
||||
#define PHY_PLL_SSC_MODE_CENTER_SPREAD 0
|
||||
#define PHY_PLL_SSC_MODE_UP_SPREAD 1
|
||||
#define PHY_PLL_SSC_MODE_DOWN_SPREAD 2
|
||||
#define PHY_PLL_SSC_MODE_DOWN_SPREAD1 3
|
||||
|
||||
#define PHY_PLL_REG2 0x5c
|
||||
|
||||
#define PHY_PLL_SEL_REF100 BIT(21)
|
||||
|
||||
/* PHY RX Register Definitions */
|
||||
#define PHY_RX_REG_A 0x60
|
||||
|
||||
#define PHY_RX_REG0_MASK GENMASK(7, 0)
|
||||
#define PHY_RX_REG1_MASK GENMASK(15, 8)
|
||||
#define PHY_RX_REG2_MASK GENMASK(23, 16)
|
||||
#define PHY_RX_REG3_MASK GENMASK(31, 24)
|
||||
|
||||
#define PHY_RX_REG0_RLOAD BIT(4)
|
||||
#define PHY_RX_REG1_RTERM GENMASK(11, 8)
|
||||
#define PHY_RX_REG1_RC_CALI GENMASK(15, 12)
|
||||
#define PHY_RX_REG2_CSEL GENMASK(19, 16)
|
||||
#define PHY_RX_REG2_FORCE_CSEL BIT(20)
|
||||
#define PHY_RX_REG2_PSEL GENMASK(23, 21)
|
||||
#define PHY_RX_REG3_I_LOAD GENMASK(26, 24)
|
||||
#define PHY_RX_REG3_SEL_CBOOST_CODE BIT(27)
|
||||
#define PHY_RX_REG3_ADJ_BIAS GENMASK(29, 28)
|
||||
#define PHY_RX_REG3_RDEG1 GENMASK(31, 30)
|
||||
|
||||
#define PHY_RX_REG_B 0x64
|
||||
|
||||
#define PHY_RX_REG4_MASK GENMASK(7, 0)
|
||||
#define PHY_RX_REG5_MASK GENMASK(15, 8)
|
||||
#define PHY_RX_REG6_MASK GENMASK(23, 16)
|
||||
|
||||
#define PHY_RX_REGB_MASK GENMASK(23, 0)
|
||||
|
||||
#define PHY_RX_REG4_RDEG2 GENMASK(2, 1)
|
||||
#define PHY_RX_REG4_ENVOS BIT(4)
|
||||
#define PHY_RX_REG4_RTERM_SEL BIT(5)
|
||||
#define PHY_RX_REG4_MANUAL_CFG BIT(7)
|
||||
#define PHY_RX_REG5_RCELL_VCM GENMASK(11, 8)
|
||||
#define PHY_RX_REG5_RCELL_BIAS GENMASK(15, 12)
|
||||
#define PHY_RX_REG6_H1_REG GENMASK(19, 16)
|
||||
#define PHY_RX_REG6_ADAPT_GAIN GENMASK(21, 20)
|
||||
#define PHY_RX_REG6_BYPASS_ADPT BIT(22)
|
||||
|
||||
#define PHY_ADPT_CFG0 0x140
|
||||
#define PHY_ADPT_AFE_RST_OVRD_EN BIT(1)
|
||||
#define PHY_ADPT_AFE_RST_OVRD_VAL BIT(4)
|
||||
|
||||
#define PHY_RXEQ_TIME 0xb4
|
||||
#define PHY_RXEQ_TIME_OVRD_POST_C_SOC BIT(21)
|
||||
#define PHY_RXEQ_TIME_CFG_AMP_SOC GENMASK(23, 22)
|
||||
#define PHY_RXEQ_TIME_AMP_SOC_650M 0
|
||||
#define PHY_RXEQ_TIME_AMP_SOC_800M 1
|
||||
#define PHY_RXEQ_TIME_AMP_SOC_870M 2
|
||||
#define PHY_RXEQ_TIME_AMP_SOC_900M 3
|
||||
#define PHY_RXEQ_TIME_OVRD_AMP_SOC BIT(24)
|
||||
|
||||
#define PCIE_PU_ADDR_CLK_CFG 0x0008
|
||||
#define PHY_CLK_PLL_READY BIT(0)
|
||||
#define PCIE_INITAL_TIMER GENMASK(6, 3)
|
||||
#define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7)
|
||||
#define CFG_SW_PHY_INIT_DONE BIT(11)
|
||||
|
||||
/* Lane RX/TX configuration (per‑lane, at lane_base) */
|
||||
#define PCIE_RX_REG1 0x050
|
||||
#define PCIE_RX_REFCLK_MODE GENMASK(1, 0)
|
||||
#define PCIE_RX_REFCLK_MODE_DRIVER 1
|
||||
#define PCIE_RX_SEL_TRI_CODE BIT(2)
|
||||
#define PCIE_RX_LEGACY GENMASK(15, 8)
|
||||
#define PCIE_RX_LEGACY_DEFAULT 0x65
|
||||
|
||||
#define PCIE_TX_REG1 0x064
|
||||
|
||||
#define PCIE_PLL_TIMEOUT 500000
|
||||
#define PCIE_POLL_DELAY 500
|
||||
|
||||
static int k3_usb3phy_init_single(struct k3_lane_group *lg, void __iomem *base)
|
||||
{
|
||||
struct phy *phy = lg->phy;
|
||||
u32 val, tmp;
|
||||
int ret;
|
||||
|
||||
/* Do not wait CDR lock before sampling data */
|
||||
val = readl(base + PHY_RESET_CFG);
|
||||
val = u32_replace_bits(val, 0, PHY_RESET_EN_SD_AFTER_LOCK);
|
||||
writel(val, base + PHY_RESET_CFG);
|
||||
|
||||
/* Power down 100MHz refclk buffer */
|
||||
val = readl(base + PHY_PU_CK_REG);
|
||||
val = u32_replace_bits(val, 0, PHY_PU_REFCLK_100);
|
||||
writel(val, base + PHY_PU_CK_REG);
|
||||
|
||||
/* Program PLL REG1 configure the SSC */
|
||||
val = FIELD_PREP(PHY_PLL_SSC_MODE, PHY_PLL_SSC_MODE_DOWN_SPREAD1) |
|
||||
FIELD_PREP(PHY_PLL_SSC_DEP_SEL, PHY_PLL_SSC_5000PPM) |
|
||||
FIELD_PREP(PHY_PLL_FREF_SEL, PHY_PLL_FREF_24M);
|
||||
writel(val, base + PHY_PLL_REG1);
|
||||
|
||||
/* Un-select 100MHz PLL reference */
|
||||
val = readl(base + PHY_PLL_REG2);
|
||||
val = u32_replace_bits(val, 0, PHY_PLL_SEL_REF100);
|
||||
writel(val, base + PHY_PLL_REG2);
|
||||
|
||||
/* USB LFPS period configuration */
|
||||
val = readl(base + PHY_MODE_CFG);
|
||||
val = u32_replace_bits(val, PHY_MODE_LFPS_TPERIOD_USB, PHY_MODE_LFPS_TPERIOD);
|
||||
writel(val, base + PHY_MODE_CFG);
|
||||
|
||||
/* Force AFE adaptation reset */
|
||||
val = readl(base + PHY_ADPT_CFG0);
|
||||
val |= PHY_ADPT_AFE_RST_OVRD_EN | PHY_ADPT_AFE_RST_OVRD_VAL;
|
||||
writel(val, base + PHY_ADPT_CFG0);
|
||||
|
||||
/* Override driver amplitude value to 900m */
|
||||
val = readl(base + PHY_RXEQ_TIME);
|
||||
val |= PHY_RXEQ_TIME_OVRD_AMP_SOC;
|
||||
val = u32_replace_bits(val, PHY_RXEQ_TIME_AMP_SOC_900M, PHY_RXEQ_TIME_CFG_AMP_SOC);
|
||||
writel(val, base + PHY_RXEQ_TIME);
|
||||
|
||||
/* Configure RX parameters */
|
||||
val = PHY_RX_REG0_RLOAD |
|
||||
FIELD_PREP(PHY_RX_REG1_RTERM, 0x8) |
|
||||
FIELD_PREP(PHY_RX_REG1_RC_CALI, 0x7) |
|
||||
FIELD_PREP(PHY_RX_REG2_CSEL, 0x8) |
|
||||
PHY_RX_REG2_FORCE_CSEL |
|
||||
FIELD_PREP(PHY_RX_REG2_PSEL, 0x4) |
|
||||
FIELD_PREP(PHY_RX_REG3_I_LOAD, 0x7) |
|
||||
PHY_RX_REG3_SEL_CBOOST_CODE |
|
||||
FIELD_PREP(PHY_RX_REG3_ADJ_BIAS, 0x1) |
|
||||
FIELD_PREP(PHY_RX_REG3_RDEG1, 0x3);
|
||||
writel(val, base + PHY_RX_REG_A);
|
||||
|
||||
val = readl(base + PHY_RX_REG_B);
|
||||
tmp = FIELD_PREP(PHY_RX_REG4_RDEG2, 0x2) |
|
||||
PHY_RX_REG4_ENVOS | PHY_RX_REG4_RTERM_SEL | PHY_RX_REG4_MANUAL_CFG |
|
||||
FIELD_PREP(PHY_RX_REG5_RCELL_VCM, 0x8) |
|
||||
FIELD_PREP(PHY_RX_REG5_RCELL_BIAS, 0x8) |
|
||||
FIELD_PREP(PHY_RX_REG6_H1_REG, 0x8) |
|
||||
FIELD_PREP(PHY_RX_REG6_ADAPT_GAIN, 0x2);
|
||||
val = u32_replace_bits(val, tmp, PHY_RX_REGB_MASK);
|
||||
writel(val, base + PHY_RX_REG_B);
|
||||
|
||||
/*
|
||||
* Inform PHY that all PLL-related configuration is done.
|
||||
* PLL will not start locking until PHY_CLK_SW_INIT_DONE is set.
|
||||
*/
|
||||
val = PHY_CLK_SW_INIT_DONE | PHY_CLK_PU_SSC_OUT |
|
||||
FIELD_PREP(PHY_CLK_REFCLK_FREQ, PHY_CLK_REFCLK_24M) |
|
||||
PHY_CLK_RXCLK_EN | PHY_CLK_TXCLK_EN |
|
||||
PHY_CLK_PCLK_EN | PHY_CLK_PIPE_PCLK_EN;
|
||||
writel(val, base + PHY_CLK_CFG);
|
||||
|
||||
ret = readl_poll_timeout(base + PHY_CLK_CFG, val,
|
||||
(val & PHY_CLK_PLL_READY),
|
||||
PCIE_POLL_DELAY, PCIE_PLL_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "PHY PLL polling timeout\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int k3_usb3phy_init(struct phy *phy)
|
||||
{
|
||||
struct k3_lane_group *lg = phy_get_drvdata(phy);
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < lg->data->lanes; i++) {
|
||||
ret = k3_usb3phy_init_single(lg, lg->base + lg->data->offsets[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct phy_ops k3_usb3_phy_ops = {
|
||||
.init = k3_usb3phy_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(k3_usb3_phy_ops);
|
||||
|
||||
static int k3_pcie_phy_init(struct phy *phy)
|
||||
{
|
||||
struct k3_lane_group *lg = phy_get_drvdata(phy);
|
||||
void __iomem *phy_base = lg->base + lg->data->offsets[0];
|
||||
u32 val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
val = readl(phy_base + PHY_PLL_REG1);
|
||||
val = u32_replace_bits(val, 0x2, GENMASK(15, 12));
|
||||
writel(val, phy_base + PHY_PLL_REG1);
|
||||
|
||||
val = readl(phy_base + PHY_PLL_REG2);
|
||||
val = u32_replace_bits(val, 0, BIT(21));
|
||||
writel(val, phy_base + PHY_PLL_REG2);
|
||||
|
||||
for (i = 0; i < lg->data->lanes; i++) {
|
||||
void __iomem *lane_base = lg->base + lg->data->offsets[i];
|
||||
|
||||
val = readl(lane_base + PCIE_RX_REG1);
|
||||
val = u32_replace_bits(val, 0, 0x3);
|
||||
writel(val, lane_base + PCIE_RX_REG1);
|
||||
}
|
||||
|
||||
val = readl(phy_base + PHY_PLL_REG2);
|
||||
val |= BIT(20);
|
||||
writel(val, phy_base + PHY_PLL_REG2);
|
||||
|
||||
/* The write is needed as clock requires renegotiation */
|
||||
val = FIELD_PREP(PCIE_RX_REFCLK_MODE, PCIE_RX_REFCLK_MODE_DRIVER) |
|
||||
PCIE_RX_SEL_TRI_CODE |
|
||||
FIELD_PREP(PCIE_RX_LEGACY, PCIE_RX_LEGACY_DEFAULT);
|
||||
writel(val, phy_base + PCIE_RX_REG1);
|
||||
|
||||
/* pll_reg1 of lane0, disable SSC: pll[27:24] = 0 */
|
||||
val = readl(phy_base + PHY_PLL_REG1);
|
||||
val = u32_replace_bits(val, 0, GENMASK(27, 24));
|
||||
writel(val, phy_base + PHY_PLL_REG1);
|
||||
|
||||
for (i = 0; i < lg->data->lanes; i++) {
|
||||
void __iomem *lane_base = lg->base + lg->data->offsets[i];
|
||||
|
||||
/* set cfg_tx_send_dummy_data to be 1'b1 for disable dash data */
|
||||
val = readl(lane_base + PHY_PU_SEL);
|
||||
val = u32_replace_bits(val, 1, BIT(13));
|
||||
writel(val, lane_base + PHY_PU_SEL);
|
||||
|
||||
/* disable en_sample_data_after_cdr_locked */
|
||||
val = readl(lane_base + PHY_RESET_CFG);
|
||||
val = u32_replace_bits(val, 0, BIT(6));
|
||||
writel(val, lane_base + PHY_RESET_CFG);
|
||||
|
||||
/* Dynamic Lock */
|
||||
val = readl(lane_base + PHY_MODE_CFG);
|
||||
val = u32_replace_bits(val, 1, BIT(2));
|
||||
writel(val, lane_base + PHY_MODE_CFG);
|
||||
|
||||
val = FIELD_PREP(PHY_RX_REG0_MASK, 0x10) |
|
||||
FIELD_PREP(PHY_RX_REG1_MASK, 0x78) |
|
||||
FIELD_PREP(PHY_RX_REG2_MASK, 0x98) |
|
||||
FIELD_PREP(PHY_RX_REG3_MASK, 0xdf);
|
||||
writel(val, lane_base + PHY_RX_REG_A);
|
||||
|
||||
val = readl(lane_base + PHY_RX_REG_B);
|
||||
val &= ~PHY_RX_REGB_MASK;
|
||||
val |= FIELD_PREP(PHY_RX_REG4_MASK, 0xb4) |
|
||||
FIELD_PREP(PHY_RX_REG5_MASK, 0x88) |
|
||||
FIELD_PREP(PHY_RX_REG6_MASK, 0x28);
|
||||
writel(val, lane_base + PHY_RX_REG_B);
|
||||
|
||||
/* Set init done */
|
||||
val = readl(lane_base + PCIE_PU_ADDR_CLK_CFG);
|
||||
val = u32_replace_bits(val, 1, CFG_SW_PHY_INIT_DONE);
|
||||
writel(val, lane_base + PCIE_PU_ADDR_CLK_CFG);
|
||||
}
|
||||
|
||||
ret = readl_poll_timeout(phy_base + PCIE_PU_ADDR_CLK_CFG, val,
|
||||
(val & PHY_CLK_PLL_READY), PCIE_POLL_DELAY,
|
||||
PCIE_PLL_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(&lg->phy->dev, "PHY PLL lock timeout\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct phy_ops k3_pcie_phy_ops = {
|
||||
.init = k3_pcie_phy_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(k3_pcie_phy_ops);
|
||||
|
||||
/* PHY rcal init requires APB_SPARE regmap access */
|
||||
|
||||
#define APB_SPARE_PU_CAL 0x178
|
||||
#define PU_CAL BIT(17)
|
||||
|
||||
#define APB_SPARE_RCAL_HSIO 0x17c
|
||||
#define APB_SPARE_PU_CAL_DONE BIT(8)
|
||||
#define RCAL_OVRD_PTRIM GENMASK(23, 20)
|
||||
#define RCAL_OVRD_NTRIM GENMASK(27, 24)
|
||||
#define RCAL_OVRD_PTRIM_EN BIT(28)
|
||||
#define RCAL_OVRD_NTRIM_EN BIT(29)
|
||||
#define RCAL_OVRD_STABLE_VAL BIT(30)
|
||||
#define RCAL_OVRD_STABLE_EN BIT(31)
|
||||
|
||||
#define RCAL_OVRD_TRIM_EN (RCAL_OVRD_NTRIM_EN | RCAL_OVRD_PTRIM_EN)
|
||||
#define RCAL_OVRD_TRIM_MASK (RCAL_OVRD_NTRIM | RCAL_OVRD_PTRIM)
|
||||
|
||||
#define PU_CAL_TIMEOUT 2000000
|
||||
|
||||
static DEFINE_MUTEX(calibrate_lock);
|
||||
|
||||
int k3_phy_calibrate(struct regmap *apb_spare)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&calibrate_lock);
|
||||
|
||||
regmap_read(apb_spare, APB_SPARE_RCAL_HSIO, &val);
|
||||
if (val & APB_SPARE_PU_CAL_DONE)
|
||||
return 0;
|
||||
|
||||
regmap_update_bits(apb_spare, APB_SPARE_PU_CAL, PU_CAL,
|
||||
PU_CAL);
|
||||
|
||||
ret = regmap_read_poll_timeout(apb_spare, APB_SPARE_RCAL_HSIO,
|
||||
val, (val & APB_SPARE_PU_CAL_DONE), PCIE_POLL_DELAY,
|
||||
PU_CAL_TIMEOUT);
|
||||
|
||||
if (ret)
|
||||
regmap_update_bits(apb_spare, APB_SPARE_RCAL_HSIO,
|
||||
RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL |
|
||||
RCAL_OVRD_TRIM_MASK | RCAL_OVRD_STABLE_EN,
|
||||
RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL |
|
||||
FIELD_PREP(RCAL_OVRD_NTRIM, 0x6) |
|
||||
FIELD_PREP(RCAL_OVRD_PTRIM, 0xa) |
|
||||
RCAL_OVRD_STABLE_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(k3_phy_calibrate);
|
||||
|
||||
MODULE_DESCRIPTION("SpacemiT K3 PHY common ops");
|
||||
MODULE_LICENSE("GPL");
|
||||
27
drivers/phy/spacemit/phy-k3-common.h
Normal file
27
drivers/phy/spacemit/phy-k3-common.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _PHY_K3_COMMON_H
|
||||
#define _PHY_K3_COMMON_H
|
||||
|
||||
#include <linux/phy/phy.h>
|
||||
|
||||
struct k3_phy_lane_group_data {
|
||||
u32 lanes;
|
||||
u8 config;
|
||||
u8 mask;
|
||||
u32 offsets[] __counted_by(lanes);
|
||||
};
|
||||
|
||||
struct k3_lane_group {
|
||||
const struct k3_phy_lane_group_data *data;
|
||||
void __iomem *base;
|
||||
struct phy *phy;
|
||||
bool is_pcie;
|
||||
};
|
||||
|
||||
extern const struct phy_ops k3_pcie_phy_ops;
|
||||
extern const struct phy_ops k3_usb3_phy_ops;
|
||||
|
||||
int k3_phy_calibrate(struct regmap *apb_spare);
|
||||
|
||||
#endif
|
||||
@@ -150,6 +150,7 @@ static int stf_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct stf_dphy *dphy;
|
||||
int ret;
|
||||
|
||||
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
if (!dphy)
|
||||
@@ -190,7 +191,9 @@ static int stf_dphy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(dphy->phy);
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = devm_pm_runtime_enable(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phy_set_drvdata(dphy->phy, dphy);
|
||||
phy_provider = devm_of_phy_provider_register(&pdev->dev,
|
||||
|
||||
@@ -392,6 +392,7 @@ static int stf_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct stf_dphy *dphy;
|
||||
int ret;
|
||||
|
||||
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
if (!dphy)
|
||||
@@ -406,7 +407,9 @@ static int stf_dphy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(dphy->topsys))
|
||||
return PTR_ERR(dphy->topsys);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = devm_pm_runtime_enable(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dphy->txesc_clk = devm_clk_get(&pdev->dev, "txesc");
|
||||
if (IS_ERR(dphy->txesc_clk))
|
||||
|
||||
@@ -116,11 +116,11 @@ static int sp_uphy_init(struct phy *phy)
|
||||
|
||||
ret = clk_prepare_enable(usbphy->phy_clk);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(usbphy->rstc);
|
||||
if (ret)
|
||||
goto err_reset;
|
||||
goto err_clk;
|
||||
|
||||
/* Default value modification */
|
||||
writel(HIGH_MASK_BITS | 0x4002, usbphy->moon4_regs + UPHY_CONTROL0);
|
||||
@@ -129,7 +129,7 @@ static int sp_uphy_init(struct phy *phy)
|
||||
/* disconnect voltage */
|
||||
ret = update_disc_vol(usbphy);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_reset;
|
||||
|
||||
/* board uphy 0 internal register modification for tid certification */
|
||||
val = readl(usbphy->phy_regs + CONFIG9);
|
||||
|
||||
Reference in New Issue
Block a user