mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-30 04:47:43 -04:00
Merge tag 'phy-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
Pull phy updates from Vinod Koul:
"Core:
- Add suuport for "rx-polarity" and "tx-polarity" device tree
properties and phy common properties to manage this
New Support:
- Qualcomm Glymur PCIe Gen4 2-lanes PCIe phy, DP and edp phy, USB UNI
PHY and SMB2370 eUSB2 repeater. SC8280xp QMP UFS PHY, Kaanapali
PCIe phy and QMP PHY, QCS615 QMP USB3+DP PHY and driver support for
that.
- SpacemiT PCIe/combo PHY and K1 USB2 PHY driver.
- HDMI 2.1 FRL configuration support and driver enabling for rockchip
samsung-hdptx driver
- TI TCAN1046 phy
- Renesas RZ/V2H(P) and RZ/V2N usb3
- Mediatek MT8188 hdmi-phy
- Google Tensor SoC USB PHY driver
- Apple Type-C PHY
Updates:
- Subsystem conversion for clock round_rate() to determine_rate()
- TI USB3 DT schema conversion
- Samsung ExynosAutov920 usb3, combo hsphy and ssphy support"
* tag 'phy-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (143 commits)
phy: ti: phy-j721e-wiz: convert from divider_round_rate() to divider_determine_rate()
dt-bindings: phy: ti,control-phy-otghs: convert to DT schema
dt-bindings: phy: ti,phy-usb3: convert to DT schema
phy: tegra: xusb: Remove unused powered_on variable
phy: renesas: rcar-gen3-usb2: add regulator dependency
phy: GOOGLE_USB: add TYPEC dependency
phy: enter drivers/phy/Makefile even without CONFIG_GENERIC_PHY
phy: renesas: rcar-gen3-usb2: Use mux-state for phyrst management
phy: renesas: rcar-gen3-usb2: Add regulator for OTG VBUS control
phy: renesas: rcar-gen3-usb2: Use devm_pm_runtime_enable()
phy: renesas: rcar-gen3-usb2: Factor out VBUS control logic
dt-bindings: phy: renesas,usb2-phy: Document RZ/G3E SoC
dt-bindings: phy: renesas,usb2-phy: Document mux-states property
dt-bindings: phy: renesas,usb2-phy: Document USB VBUS regulator
phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support
phy: rockchip: samsung-hdptx: Extend rk_hdptx_phy_verify_hdmi_config() helper
phy: rockchip: samsung-hdptx: Switch to driver specific HDMI config
phy: rockchip: samsung-hdptx: Drop hw_rate driver data
phy: rockchip: samsung-hdptx: Compute clk rate from PLL config
phy: rockchip: samsung-hdptx: Cleanup *_cmn_init_seq lists
...
This commit is contained in:
222
Documentation/devicetree/bindings/phy/apple,atcphy.yaml
Normal file
222
Documentation/devicetree/bindings/phy/apple,atcphy.yaml
Normal file
@@ -0,0 +1,222 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/apple,atcphy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Apple Type-C PHY (ATCPHY)
|
||||
|
||||
maintainers:
|
||||
- Sven Peter <sven@kernel.org>
|
||||
|
||||
description: >
|
||||
The Apple Type-C PHY (ATCPHY) is a combined PHY for USB 2.0, USB 3.x,
|
||||
USB4/Thunderbolt, and DisplayPort connectivity via Type-C ports found in
|
||||
Apple Silicon SoCs.
|
||||
|
||||
The PHY handles muxing between these different protocols and also provides the
|
||||
reset controller for the attached DWC3 USB controller.
|
||||
|
||||
It is designed for USB4 operation and does not handle individual differential
|
||||
pairs as distinct DisplayPort lanes. Any reference to lane in this binding
|
||||
hence refers to two differential pairs (RX and TX) as used in USB terminology.
|
||||
|
||||
In order to correctly setup these lanes for the various modes calibration
|
||||
values copied from Apple's firmware and converted to the format described
|
||||
below by our bootloader m1n1 are required. Without these only USB2 operation
|
||||
is possible.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/usb/usb-switch.yaml#
|
||||
|
||||
$defs:
|
||||
apple,tunable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
items:
|
||||
items:
|
||||
- description: Register offset
|
||||
- description: Mask to be applied to the register value
|
||||
- description: Bits to be set after applying the mask
|
||||
description: >
|
||||
List of (register offset, mask, value) tuples copied from Apple's Device
|
||||
Tree by our bootloader m1n1 and used to configure the PHY. These values
|
||||
even vary for a single product/device and likely contain calibration
|
||||
values determined by Apple at manufacturing time.
|
||||
Unless otherwise noted these tunables are always applied to the core
|
||||
register region.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- apple,t6000-atcphy
|
||||
- apple,t6020-atcphy
|
||||
- apple,t8112-atcphy
|
||||
- const: apple,t8103-atcphy
|
||||
- const: apple,t8103-atcphy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Common controls for all PHYs (USB2/3/4, DisplayPort, TBT)
|
||||
- description: DisplayPort Alternate Mode PHY specific controls
|
||||
- description: Type-C PHY AXI to Apple Fabric interconnect controls
|
||||
- description: USB2 PHY specific controls
|
||||
- description: USB3 PIPE interface controls
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: lpdptx
|
||||
- const: axi2af
|
||||
- const: usb2phy
|
||||
- const: pipehandler
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
|
||||
"#reset-cells":
|
||||
const: 0
|
||||
|
||||
mode-switch: true
|
||||
orientation-switch: true
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Outgoing connection to the SS port of the Type-C connector.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Incoming endpoint from the USB3 controller.
|
||||
|
||||
port@2:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Incoming endpoint from the DisplayPort controller.
|
||||
|
||||
port@3:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Incoming endpoint from the USB4/Thunderbolt controller.
|
||||
|
||||
apple,tunable-common-a:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: >
|
||||
Common tunables required for all modes, applied before tunable-axi2af.
|
||||
|
||||
apple,tunable-axi2af:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: >
|
||||
AXI to Apple Fabric tunables, required for all modes. Unlike all other
|
||||
tunables these are applied to the axi2af region.
|
||||
|
||||
apple,tunable-common-b:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: >
|
||||
Common tunables required for all modes, applied after tunable-axi2af.
|
||||
|
||||
apple,tunable-lane0-usb:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: USB3 tunables for lane 0.
|
||||
|
||||
apple,tunable-lane1-usb:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: USB3 tunables for lane 1.
|
||||
|
||||
apple,tunable-lane0-cio:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: USB4/Thunderbolt ("Converged IO") tunables for lane 0.
|
||||
|
||||
apple,tunable-lane1-cio:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: USB4/Thunderbolt ("Converged IO") tunables for lane 1.
|
||||
|
||||
apple,tunable-lane0-dp:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: >
|
||||
DisplayPort tunables for lane 0.
|
||||
|
||||
Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
|
||||
and not to an individual DisplayPort differential lane.
|
||||
|
||||
apple,tunable-lane1-dp:
|
||||
$ref: "#/$defs/apple,tunable"
|
||||
description: >
|
||||
DisplayPort tunables for lane 1.
|
||||
|
||||
Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
|
||||
and not to an individual DisplayPort differential lane.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
- "#reset-cells"
|
||||
- orientation-switch
|
||||
- mode-switch
|
||||
- power-domains
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@83000000 {
|
||||
compatible = "apple,t8103-atcphy";
|
||||
reg = <0x83000000 0x4c000>,
|
||||
<0x83050000 0x8000>,
|
||||
<0x80000000 0x4000>,
|
||||
<0x82a90000 0x4000>,
|
||||
<0x82a84000 0x4000>;
|
||||
reg-names = "core", "lpdptx", "axi2af", "usb2phy",
|
||||
"pipehandler";
|
||||
|
||||
#phy-cells = <1>;
|
||||
#reset-cells = <0>;
|
||||
|
||||
orientation-switch;
|
||||
mode-switch;
|
||||
power-domains = <&ps_atc0_usb>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&typec_connector_ss>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&dwc3_ss_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&dcp_dp_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&acio_tbt_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -20,6 +20,32 @@ properties:
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^phy@[0-7]$":
|
||||
type: object
|
||||
description: SerDes lane (single RX/TX differential pair)
|
||||
|
||||
properties:
|
||||
reg:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description: Lane index as seen in register map
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -32,9 +58,52 @@ examples:
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
serdes_1: phy@1ea0000 {
|
||||
|
||||
serdes@1ea0000 {
|
||||
compatible = "fsl,lynx-28g";
|
||||
reg = <0x0 0x1ea0000 0x0 0x1e30>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#phy-cells = <1>;
|
||||
|
||||
phy@0 {
|
||||
reg = <0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@1 {
|
||||
reg = <1>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@2 {
|
||||
reg = <2>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@3 {
|
||||
reg = <3>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@4 {
|
||||
reg = <4>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@5 {
|
||||
reg = <5>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@6 {
|
||||
reg = <6>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@7 {
|
||||
reg = <7>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
133
Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml
Normal file
133
Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml
Normal file
@@ -0,0 +1,133 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2025, Google LLC
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/google,lga-usb-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Google Tensor Series G5 (Laguna) USB PHY
|
||||
|
||||
maintainers:
|
||||
- Roy Luo <royluo@google.com>
|
||||
|
||||
description:
|
||||
Describes the USB PHY interfaces integrated with the DWC3 USB controller on
|
||||
Google Tensor SoCs, starting with the G5 generation (laguna).
|
||||
Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
|
||||
and USB3.2/DisplayPort combo PHY IP.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: google,lga-usb-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: USB3.2/DisplayPort combo PHY core registers.
|
||||
- description: USB3.2/DisplayPort combo PHY Type-C Assist registers.
|
||||
- description: eUSB 2.0 PHY core registers.
|
||||
- description: Top-level wrapper registers for the integrated PHYs.
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: usb3_core
|
||||
- const: usb3_tca
|
||||
- const: usb2_core
|
||||
- const: usbdp_top
|
||||
|
||||
"#phy-cells":
|
||||
description: |
|
||||
The phandle's argument in the PHY specifier selects one of the three
|
||||
following PHY interfaces.
|
||||
- 0 for USB high-speed.
|
||||
- 1 for USB super-speed.
|
||||
- 2 for DisplayPort.
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: USB2 PHY clock.
|
||||
- description: USB2 PHY APB clock.
|
||||
- description: USB3.2/DisplayPort combo PHY clock.
|
||||
- description: USB3.2/DisplayPort combo PHY firmware clock.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: usb2
|
||||
- const: usb2_apb
|
||||
- const: usb3
|
||||
- const: usb3_fw
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: USB2 PHY reset.
|
||||
- description: USB2 PHY APB reset.
|
||||
- description: USB3.2/DisplayPort combo PHY reset.
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: usb2
|
||||
- const: usb2_apb
|
||||
- const: usb3
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
orientation-switch:
|
||||
type: boolean
|
||||
description:
|
||||
Indicates the PHY as a handler of USB Type-C orientation changes
|
||||
|
||||
google,usb-cfg-csr:
|
||||
description:
|
||||
A phandle to a syscon node used to access the USB configuration
|
||||
registers. These registers are the top-level wrapper of the USB
|
||||
subsystem and provide control and status for the integrated USB
|
||||
controller and USB PHY.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle to the syscon node.
|
||||
- description: USB2 PHY configuration register offset.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- orientation-switch
|
||||
- google,usb-cfg-csr
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
usb-phy@c410000 {
|
||||
compatible = "google,lga-usb-phy";
|
||||
reg = <0 0x0c410000 0 0x20000>,
|
||||
<0 0x0c430000 0 0x1000>,
|
||||
<0 0x0c440000 0 0x10000>,
|
||||
<0 0x0c637000 0 0xa0>;
|
||||
reg-names = "usb3_core", "usb3_tca", "usb2_core", "usbdp_top";
|
||||
#phy-cells = <1>;
|
||||
clocks = <&hsion_usb2_phy_clk>, <&hsion_u2phy_apb_clk>,
|
||||
<&hsion_usb3_phy_clk>, <&hsion_usb3_phy_fw_clk>;
|
||||
clock-names = "usb2", "usb2_apb", "usb3", "usb3_fw";
|
||||
resets = <&hsion_resets_usb2_phy>,
|
||||
<&hsion_resets_u2phy_apb>,
|
||||
<&hsion_resets_usb3_phy>;
|
||||
reset-names = "usb2", "usb2_apb", "usb3";
|
||||
power-domains = <&hsio_n_usb_pd>;
|
||||
orientation-switch;
|
||||
google,usb-cfg-csr = <&usb_cfg_csr 0x14>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,glymur-dp-phy
|
||||
- qcom,sa8775p-edp-phy
|
||||
- qcom,sc7280-edp-phy
|
||||
- qcom,sc8180x-edp-phy
|
||||
@@ -37,12 +38,15 @@ properties:
|
||||
- description: PLL register block
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg_ahb
|
||||
- const: ref
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
@@ -64,6 +68,30 @@ required:
|
||||
- "#clock-cells"
|
||||
- "#phy-cells"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-dp-phy
|
||||
- qcom,x1e80100-dp-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -15,9 +15,13 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sm8750-m31-eusb2-phy
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,glymur-m31-eusb2-phy
|
||||
- qcom,kaanapali-m31-eusb2-phy
|
||||
- const: qcom,sm8750-m31-eusb2-phy
|
||||
- const: qcom,sm8750-m31-eusb2-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
|
||||
|
||||
maintainers:
|
||||
- Xiangxu Yin <xiangxu.yin@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for both USB3
|
||||
and DisplayPort over USB-C. While it enables mode switching between USB3 and
|
||||
DisplayPort, but does not support combo mode.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qcs615-qmp-usb3-dp-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: ref
|
||||
- const: cfg_ahb
|
||||
- const: pipe
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy_phy
|
||||
- const: dp_phy
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
description:
|
||||
See include/dt-bindings/phy/phy-qcom-qmp.h
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description:
|
||||
See include/dt-bindings/phy/phy-qcom-qmp.h
|
||||
|
||||
qcom,tcsr-reg:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle to TCSR hardware block
|
||||
- description: offset of the VLS CLAMP register
|
||||
- description: offset of the PHY mode register
|
||||
description: Clamp and PHY mode register present in the TCSR
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- "#clock-cells"
|
||||
- "#phy-cells"
|
||||
- qcom,tcsr-reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,qcs615-gcc.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
||||
phy@88e8000 {
|
||||
compatible = "qcom,qcs615-qmp-usb3-dp-phy";
|
||||
reg = <0x88e8000 0x2000>;
|
||||
|
||||
clocks = <&gcc GCC_USB2_SEC_PHY_AUX_CLK>,
|
||||
<&gcc GCC_USB3_SEC_CLKREF_CLK>,
|
||||
<&gcc GCC_AHB2PHY_WEST_CLK>,
|
||||
<&gcc GCC_USB2_SEC_PHY_PIPE_CLK>;
|
||||
clock-names = "aux",
|
||||
"ref",
|
||||
"cfg_ahb",
|
||||
"pipe";
|
||||
|
||||
resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>,
|
||||
<&gcc GCC_USB3_DP_PHY_SEC_BCR>;
|
||||
reset-names = "phy_phy",
|
||||
"dp_phy";
|
||||
|
||||
vdda-phy-supply = <&vreg_l5a>;
|
||||
vdda-pll-supply = <&vreg_l12a>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <1>;
|
||||
|
||||
qcom,tcsr-reg = <&tcsr 0xbff0 0xb24c>;
|
||||
};
|
||||
@@ -16,7 +16,9 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,kaanapali-qmp-gen3x2-pcie-phy
|
||||
- qcom,qcs615-qmp-gen3x1-pcie-phy
|
||||
- qcom,qcs8300-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x2-pcie-phy
|
||||
@@ -146,6 +148,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,kaanapali-qmp-gen3x2-pcie-phy
|
||||
- qcom,qcs615-qmp-gen3x1-pcie-phy
|
||||
- qcom,sar2130p-qmp-gen3x2-pcie-phy
|
||||
- qcom,sc8180x-qmp-pcie-phy
|
||||
@@ -178,6 +181,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,qcs8300-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x2-pcie-phy
|
||||
@@ -202,7 +206,9 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-gen4x2-pcie-phy
|
||||
- qcom,glymur-qmp-gen5x4-pcie-phy
|
||||
- qcom,kaanapali-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8550-qmp-gen4x2-pcie-phy
|
||||
- qcom,sm8650-qmp-gen4x2-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen3x2-pcie-phy
|
||||
|
||||
@@ -20,6 +20,10 @@ properties:
|
||||
- enum:
|
||||
- qcom,qcs615-qmp-ufs-phy
|
||||
- const: qcom,sm6115-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,x1e80100-qmp-ufs-phy
|
||||
- const: qcom,sm8550-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs8300-qmp-ufs-phy
|
||||
@@ -29,6 +33,7 @@ properties:
|
||||
- qcom,kaanapali-qmp-ufs-phy
|
||||
- const: qcom,sm8750-qmp-ufs-phy
|
||||
- enum:
|
||||
- qcom,milos-qmp-ufs-phy
|
||||
- qcom,msm8996-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sa8775p-qmp-ufs-phy
|
||||
@@ -98,6 +103,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,milos-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sa8775p-qmp-ufs-phy
|
||||
- qcom,sc7180-qmp-ufs-phy
|
||||
|
||||
@@ -16,6 +16,7 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-uni-phy
|
||||
- qcom,ipq5424-qmp-usb3-phy
|
||||
- qcom,ipq6018-qmp-usb3-phy
|
||||
- qcom,ipq8074-qmp-usb3-phy
|
||||
@@ -61,6 +62,8 @@ properties:
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
refgen-supply: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
@@ -113,6 +116,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-uni-phy
|
||||
- qcom,qcs8300-qmp-usb3-uni-phy
|
||||
- qcom,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
@@ -156,6 +160,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
@@ -164,6 +169,19 @@ allOf:
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-uni-phy
|
||||
then:
|
||||
required:
|
||||
- refgen-supply
|
||||
else:
|
||||
properties:
|
||||
refgen-supply: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -15,22 +15,28 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc7180-qmp-usb3-dp-phy
|
||||
- qcom,sc7280-qmp-usb3-dp-phy
|
||||
- qcom,sc8180x-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sdm845-qmp-usb3-dp-phy
|
||||
- qcom,sm6350-qmp-usb3-dp-phy
|
||||
- qcom,sm8150-qmp-usb3-dp-phy
|
||||
- qcom,sm8250-qmp-usb3-dp-phy
|
||||
- qcom,sm8350-qmp-usb3-dp-phy
|
||||
- qcom,sm8450-qmp-usb3-dp-phy
|
||||
- qcom,sm8550-qmp-usb3-dp-phy
|
||||
- qcom,sm8650-qmp-usb3-dp-phy
|
||||
- qcom,sm8750-qmp-usb3-dp-phy
|
||||
- qcom,x1e80100-qmp-usb3-dp-phy
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,kaanapali-qmp-usb3-dp-phy
|
||||
- const: qcom,sm8750-qmp-usb3-dp-phy
|
||||
- enum:
|
||||
- qcom,glymur-qmp-usb3-dp-phy
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc7180-qmp-usb3-dp-phy
|
||||
- qcom,sc7280-qmp-usb3-dp-phy
|
||||
- qcom,sc8180x-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sdm845-qmp-usb3-dp-phy
|
||||
- qcom,sm6350-qmp-usb3-dp-phy
|
||||
- qcom,sm8150-qmp-usb3-dp-phy
|
||||
- qcom,sm8250-qmp-usb3-dp-phy
|
||||
- qcom,sm8350-qmp-usb3-dp-phy
|
||||
- qcom,sm8450-qmp-usb3-dp-phy
|
||||
- qcom,sm8550-qmp-usb3-dp-phy
|
||||
- qcom,sm8650-qmp-usb3-dp-phy
|
||||
- qcom,sm8750-qmp-usb3-dp-phy
|
||||
- qcom,x1e80100-qmp-usb3-dp-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -63,6 +69,8 @@ properties:
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
refgen-supply: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
description:
|
||||
@@ -194,14 +202,16 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sm6350-qmp-usb3-dp-phy
|
||||
- qcom,sm8550-qmp-usb3-dp-phy
|
||||
- qcom,sm8650-qmp-usb3-dp-phy
|
||||
- qcom,sm8750-qmp-usb3-dp-phy
|
||||
- qcom,x1e80100-qmp-usb3-dp-phy
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-dp-phy
|
||||
- qcom,sar2130p-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sm6350-qmp-usb3-dp-phy
|
||||
- qcom,sm8550-qmp-usb3-dp-phy
|
||||
- qcom,sm8650-qmp-usb3-dp-phy
|
||||
- qcom,sm8750-qmp-usb3-dp-phy
|
||||
- qcom,x1e80100-qmp-usb3-dp-phy
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
@@ -209,6 +219,18 @@ allOf:
|
||||
properties:
|
||||
power-domains: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-qmp-usb3-dp-phy
|
||||
then:
|
||||
required:
|
||||
- refgen-supply
|
||||
else:
|
||||
properties:
|
||||
refgen-supply: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -24,6 +24,7 @@ properties:
|
||||
- qcom,pm8550b-eusb2-repeater
|
||||
- qcom,pmiv0104-eusb2-repeater
|
||||
- qcom,smb2360-eusb2-repeater
|
||||
- qcom,smb2370-eusb2-repeater
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -59,6 +60,14 @@ properties:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
|
||||
qcom,squelch-detector-bp:
|
||||
description:
|
||||
This adjusts the voltage level for the threshold used to detect valid
|
||||
high-speed data.
|
||||
minimum: -6000
|
||||
maximum: 1000
|
||||
multipleOf: 1000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -11,7 +11,14 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a09g047-usb3-phy
|
||||
oneOf:
|
||||
- const: renesas,r9a09g047-usb3-phy # RZ/G3E
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r9a09g056-usb3-phy # RZ/V2N
|
||||
- renesas,r9a09g057-usb3-phy # RZ/V2H(P)
|
||||
- const: renesas,r9a09g047-usb3-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -41,7 +41,9 @@ properties:
|
||||
- const: renesas,rzg2l-usb2-phy
|
||||
|
||||
- items:
|
||||
- const: renesas,usb2-phy-r9a09g056 # RZ/V2N
|
||||
- enum:
|
||||
- renesas,usb2-phy-r9a09g047 # RZ/G3E
|
||||
- renesas,usb2-phy-r9a09g056 # RZ/V2N
|
||||
- const: renesas,usb2-phy-r9a09g057
|
||||
|
||||
- const: renesas,usb2-phy-r9a09g077 # RZ/T2H
|
||||
@@ -89,6 +91,12 @@ properties:
|
||||
Phandle to a regulator that provides power to the VBUS. This regulator
|
||||
will be managed during the PHY power on/off sequence.
|
||||
|
||||
vbus-regulator:
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
description: USB VBUS internal regulator
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
|
||||
renesas,no-otg-pins:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: |
|
||||
@@ -96,6 +104,11 @@ properties:
|
||||
|
||||
dr_mode: true
|
||||
|
||||
mux-states:
|
||||
description:
|
||||
phandle to a mux controller node that select the source for USB VBUS.
|
||||
maxItems: 1
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
@@ -36,6 +36,9 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
samsung,pmu-syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
|
||||
@@ -34,6 +34,9 @@ properties:
|
||||
- samsung,exynos7870-usbdrd-phy
|
||||
- samsung,exynos850-usbdrd-phy
|
||||
- samsung,exynos990-usbdrd-phy
|
||||
- samsung,exynosautov920-usb31drd-combo-ssphy
|
||||
- samsung,exynosautov920-usbdrd-combo-hsphy
|
||||
- samsung,exynosautov920-usbdrd-phy
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
@@ -51,6 +54,9 @@ properties:
|
||||
settings register. For Exynos5420 this is given as 'sclk_usbphy30'
|
||||
in the CMU. It's not needed for Exynos2200.
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
|
||||
@@ -110,6 +116,15 @@ properties:
|
||||
vddh-usbdp-supply:
|
||||
description: VDDh power supply for the USB DP phy.
|
||||
|
||||
dvdd-supply:
|
||||
description: 0.75V power supply for the USB phy.
|
||||
|
||||
vdd18-supply:
|
||||
description: 1.8V power supply for the USB phy.
|
||||
|
||||
vdd33-supply:
|
||||
description: 3.3V power supply for the USB phy.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
@@ -221,6 +236,9 @@ allOf:
|
||||
- samsung,exynos7870-usbdrd-phy
|
||||
- samsung,exynos850-usbdrd-phy
|
||||
- samsung,exynos990-usbdrd-phy
|
||||
- samsung,exynosautov920-usb31drd-combo-ssphy
|
||||
- samsung,exynosautov920-usbdrd-combo-hsphy
|
||||
- samsung,exynosautov920-usbdrd-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
@@ -238,6 +256,39 @@ allOf:
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynosautov920-usb31drd-combo-ssphy
|
||||
- samsung,exynosautov920-usbdrd-combo-hsphy
|
||||
- samsung,exynosautov920-usbdrd-phy
|
||||
then:
|
||||
required:
|
||||
- dvdd-supply
|
||||
- vdd18-supply
|
||||
|
||||
else:
|
||||
properties:
|
||||
dvdd-supply: false
|
||||
vdd18-supply: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynosautov920-usbdrd-combo-hsphy
|
||||
- samsung,exynosautov920-usbdrd-phy
|
||||
then:
|
||||
required:
|
||||
- vdd33-supply
|
||||
|
||||
else:
|
||||
properties:
|
||||
vdd33-supply: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
114
Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
Normal file
114
Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
Normal file
@@ -0,0 +1,114 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SpacemiT K1 PCIe/USB3 Combo PHY
|
||||
|
||||
maintainers:
|
||||
- Alex Elder <elder@riscstar.com>
|
||||
|
||||
description: >
|
||||
Of the three PHYs on the SpacemiT K1 SoC capable of being used for
|
||||
PCIe, one is a combo PHY that can also be configured for use by a
|
||||
USB 3 controller. Using PCIe or USB 3 is a board design decision.
|
||||
|
||||
The combo PHY is also the only PCIe PHY that is able to determine
|
||||
PCIe calibration values to use, and this must be determined before
|
||||
the other two PCIe PHYs can be used. This calibration must be
|
||||
performed with the combo PHY in PCIe mode, and is this is done
|
||||
when the combo PHY is probed.
|
||||
|
||||
The combo PHY uses an external oscillator as a reference clock.
|
||||
During normal operation, the PCIe or USB port driver is responsible
|
||||
for ensuring all other clocks needed by a PHY are enabled, and all
|
||||
resets affecting the PHY are deasserted. However, for the combo
|
||||
PHY to perform calibration independent of whether it's later used
|
||||
for PCIe or USB, all PCIe mode clocks and resets must be defined.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: spacemit,k1-combo-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PHY control registers
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External oscillator used by the PHY PLL
|
||||
- description: DWC PCIe Data Bus Interface (DBI) clock
|
||||
- description: DWC PCIe application AXI-bus Master interface clock
|
||||
- description: DWC PCIe application AXI-bus slave interface clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: refclk
|
||||
- const: dbi
|
||||
- const: mstr
|
||||
- const: slv
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: PHY reset; remains deasserted after initialization
|
||||
- description: DWC PCIe Data Bus Interface (DBI) reset
|
||||
- description: DWC PCIe application AXI-bus Master interface reset
|
||||
- description: DWC PCIe application AXI-bus slave interface reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: dbi
|
||||
- const: mstr
|
||||
- const: slv
|
||||
|
||||
spacemit,apmu:
|
||||
description:
|
||||
A phandle that refers to the APMU system controller, whose
|
||||
regmap is used in setting the mode
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description:
|
||||
The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines
|
||||
whether the PHY operates in PCIe or USB3 mode.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- spacemit,apmu
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/spacemit,k1-syscon.h>
|
||||
phy@c0b10000 {
|
||||
compatible = "spacemit,k1-combo-phy";
|
||||
reg = <0xc0b10000 0x1000>;
|
||||
clocks = <&vctcxo_24m>,
|
||||
<&syscon_apmu CLK_PCIE0_DBI>,
|
||||
<&syscon_apmu CLK_PCIE0_MASTER>,
|
||||
<&syscon_apmu CLK_PCIE0_SLAVE>;
|
||||
clock-names = "refclk",
|
||||
"dbi",
|
||||
"mstr",
|
||||
"slv";
|
||||
resets = <&syscon_apmu RESET_PCIE0_GLOBAL>,
|
||||
<&syscon_apmu RESET_PCIE0_DBI>,
|
||||
<&syscon_apmu RESET_PCIE0_MASTER>,
|
||||
<&syscon_apmu RESET_PCIE0_SLAVE>;
|
||||
reset-names = "phy",
|
||||
"dbi",
|
||||
"mstr",
|
||||
"slv";
|
||||
spacemit,apmu = <&syscon_apmu>;
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/spacemit,k1-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SpacemiT K1 PCIe PHY
|
||||
|
||||
maintainers:
|
||||
- Alex Elder <elder@riscstar.com>
|
||||
|
||||
description: >
|
||||
Two PHYs on the SpacemiT K1 SoC used for only for PCIe. These
|
||||
PHYs must be configured using calibration values that are
|
||||
determined by a third "combo PHY". The combo PHY determines
|
||||
these calibration values during probe so they can be used for
|
||||
the two PCIe-only PHYs.
|
||||
|
||||
The PHY uses an external oscillator as a reference clock. During
|
||||
normal operation, the PCIe host driver is responsible for ensuring
|
||||
all other clocks needed by a PHY are enabled, and all resets
|
||||
affecting the PHY are deasserted.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: spacemit,k1-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PHY control registers
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: External oscillator used by the PHY PLL
|
||||
|
||||
clock-names:
|
||||
const: refclk
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: PHY reset; remains deasserted after initialization
|
||||
|
||||
reset-names:
|
||||
const: phy
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/spacemit,k1-syscon.h>
|
||||
phy@c0c10000 {
|
||||
compatible = "spacemit,k1-pcie-phy";
|
||||
reg = <0xc0c10000 0x1000>;
|
||||
clocks = <&vctcxo_24m>;
|
||||
clock-names = "refclk";
|
||||
resets = <&syscon_apmu RESET_PCIE1_GLOBAL>;
|
||||
reset-names = "phy";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
40
Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
Normal file
40
Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: SpacemiT K1 SoC USB 2.0 PHY
|
||||
|
||||
maintainers:
|
||||
- Ze Huang <huang.ze@linux.dev>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: spacemit,k1-usb2-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
usb-phy@c09c0000 {
|
||||
compatible = "spacemit,k1-usb2-phy";
|
||||
reg = <0xc09c0000 0x200>;
|
||||
clocks = <&syscon_apmu 15>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/ti,control-phy-otghs.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI OMAP Control PHY Module
|
||||
|
||||
maintainers:
|
||||
- Roger Quadros <rogerq@ti.com>
|
||||
|
||||
description:
|
||||
The TI OMAP Control PHY module is a hardware block within the system
|
||||
control module (SCM) of Texas Instruments OMAP SoCs. It provides
|
||||
centralized control over power, configuration, and auxiliary features
|
||||
for multiple on-chip PHYs. This module is essential for proper PHY
|
||||
operation in power-constrained embedded systems.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^phy@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- ti,control-phy-otghs
|
||||
- ti,control-phy-pcie
|
||||
- ti,control-phy-pipe3
|
||||
- ti,control-phy-usb2
|
||||
- ti,control-phy-usb2-am437
|
||||
- ti,control-phy-usb2-dra7
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
enum: [otghs_control, power, pcie_pcs, control_sma]
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,control-phy-otghs
|
||||
then:
|
||||
properties:
|
||||
reg-names:
|
||||
const: otghs_control
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,control-phy-pcie
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 3
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: power
|
||||
- const: pcie_pcs
|
||||
- const: control_sma
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,control-phy-usb2
|
||||
- ti,control-phy-usb2-dra7
|
||||
- ti,control-phy-usb2-am437
|
||||
- ti,control-phy-pipe3
|
||||
then:
|
||||
properties:
|
||||
reg-names:
|
||||
const: power
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- reg-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@4a00233c {
|
||||
compatible = "ti,control-phy-otghs";
|
||||
reg = <0x4a00233c 0x4>;
|
||||
reg-names = "otghs_control";
|
||||
};
|
||||
...
|
||||
138
Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
Normal file
138
Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml
Normal file
@@ -0,0 +1,138 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/ti,phy-usb3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI PIPE3 PHY Module
|
||||
|
||||
maintainers:
|
||||
- Roger Quadros <rogerq@ti.com>
|
||||
|
||||
description:
|
||||
The TI PIPE3 PHY is a high-speed SerDes (Serializer/Deserializer)
|
||||
transceiver integrated in OMAP5, DRA7xx/AM57xx, and similar SoCs.
|
||||
It supports multiple protocols (USB3, SATA, PCIe) using the PIPE3
|
||||
interface standard, which defines a common physical layer for
|
||||
high-speed serial interfaces.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^(pcie-phy|usb3-phy|phy)@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- ti,omap-usb3
|
||||
- ti,phy-pipe3-pcie
|
||||
- ti,phy-pipe3-sata
|
||||
- ti,phy-usb3
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: phy_rx
|
||||
- const: phy_tx
|
||||
- const: pll_ctrl
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 7
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 7
|
||||
items:
|
||||
enum: [wkupclk, sysclk, refclk, dpll_ref,
|
||||
dpll_ref_m2, phy-div, div-clk]
|
||||
|
||||
syscon-phy-power:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
items:
|
||||
items:
|
||||
- description: Phandle to the system control module
|
||||
- description: Register offset controlling PHY power
|
||||
|
||||
syscon-pllreset:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
items:
|
||||
items:
|
||||
- description: Phandle to the system control module
|
||||
- description: Register offset of CTRL_CORE_SMA_SW_0
|
||||
|
||||
syscon-pcs:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
maxItems: 1
|
||||
items:
|
||||
items:
|
||||
- description: Phandle to the system control module
|
||||
- description: Register offset for PCS delay programming
|
||||
|
||||
ctrl-module:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle of control module for PHY power on.
|
||||
deprecated: true
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,phy-pipe3-sata
|
||||
then:
|
||||
properties:
|
||||
syscon-pllreset: true
|
||||
else:
|
||||
properties:
|
||||
syscon-pllreset: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
/* TI PIPE3 USB3 PHY */
|
||||
usb3-phy@4a084400 {
|
||||
compatible = "ti,phy-usb3";
|
||||
reg = <0x4a084400 0x80>,
|
||||
<0x4a084800 0x64>,
|
||||
<0x4a084c00 0x40>;
|
||||
reg-names = "phy_rx", "phy_tx", "pll_ctrl";
|
||||
#phy-cells = <0>;
|
||||
clocks = <&usb_phy_cm_clk32k>,
|
||||
<&sys_clkin>,
|
||||
<&usb_otg_ss_refclk960m>;
|
||||
clock-names = "wkupclk", "sysclk", "refclk";
|
||||
ctrl-module = <&omap_control_usb>;
|
||||
};
|
||||
|
||||
- |
|
||||
/* TI PIPE3 SATA PHY */
|
||||
phy@4a096000 {
|
||||
compatible = "ti,phy-pipe3-sata";
|
||||
reg = <0x4a096000 0x80>, /* phy_rx */
|
||||
<0x4a096400 0x64>, /* phy_tx */
|
||||
<0x4a096800 0x40>; /* pll_ctrl */
|
||||
reg-names = "phy_rx", "phy_tx", "pll_ctrl";
|
||||
clocks = <&sys_clkin1>, <&sata_ref_clk>;
|
||||
clock-names = "sysclk", "refclk";
|
||||
syscon-pllreset = <&scm_conf 0x3fc>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
...
|
||||
@@ -20,6 +20,9 @@ properties:
|
||||
- microchip,ata6561
|
||||
- ti,tcan1051
|
||||
- const: ti,tcan1042
|
||||
- items:
|
||||
- const: ti,tcan1046
|
||||
- const: nxp,tja1048
|
||||
- enum:
|
||||
- ti,tcan1042
|
||||
- ti,tcan1043
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
TI PHY: DT DOCUMENTATION FOR PHYs in TI PLATFORMs
|
||||
|
||||
OMAP CONTROL PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of
|
||||
"ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4.
|
||||
"ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register
|
||||
e.g. USB2_PHY on OMAP5.
|
||||
"ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control
|
||||
e.g. USB3 PHY and SATA PHY on OMAP5.
|
||||
"ti,control-phy-pcie" - for pcie to support external clock for pcie and to
|
||||
set PCS delay value.
|
||||
e.g. PCIE PHY in DRA7x
|
||||
"ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on
|
||||
DRA7 platform.
|
||||
"ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on
|
||||
AM437 platform.
|
||||
- reg : register ranges as listed in the reg-names property
|
||||
- reg-names: "otghs_control" for control-phy-otghs
|
||||
"power", "pcie_pcs" and "control_sma" for control-phy-pcie
|
||||
"power" for all other types
|
||||
|
||||
omap_control_usb: omap-control-usb@4a002300 {
|
||||
compatible = "ti,control-phy-otghs";
|
||||
reg = <0x4a00233c 0x4>;
|
||||
reg-names = "otghs_control";
|
||||
};
|
||||
|
||||
TI PIPE3 PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "ti,phy-usb3", "ti,phy-pipe3-sata" or
|
||||
"ti,phy-pipe3-pcie. "ti,omap-usb3" is deprecated.
|
||||
- reg : Address and length of the register set for the device.
|
||||
- reg-names: The names of the register addresses corresponding to the registers
|
||||
filled in "reg".
|
||||
- #phy-cells: determine the number of cells that should be given in the
|
||||
phandle while referencing this phy.
|
||||
- clocks: a list of phandles and clock-specifier pairs, one for each entry in
|
||||
clock-names.
|
||||
- clock-names: should include:
|
||||
* "wkupclk" - wakeup clock.
|
||||
* "sysclk" - system clock.
|
||||
* "refclk" - reference clock.
|
||||
* "dpll_ref" - external dpll ref clk
|
||||
* "dpll_ref_m2" - external dpll ref clk
|
||||
* "phy-div" - divider for apll
|
||||
* "div-clk" - apll clock
|
||||
|
||||
Optional properties:
|
||||
- id: If there are multiple instance of the same type, in order to
|
||||
differentiate between each instance "id" can be used (e.g., multi-lane PCIe
|
||||
PHY). If "id" is not provided, it is set to default value of '1'.
|
||||
- syscon-pllreset: Handle to system control region that contains the
|
||||
CTRL_CORE_SMA_SW_0 register and register offset to the CTRL_CORE_SMA_SW_0
|
||||
register that contains the SATA_PLL_SOFT_RESET bit. Only valid for sata_phy.
|
||||
- syscon-pcs : phandle/offset pair. Phandle to the system control module and the
|
||||
register offset to write the PCS delay value.
|
||||
|
||||
Deprecated properties:
|
||||
- ctrl-module : phandle of the control module used by PHY driver to power on
|
||||
the PHY.
|
||||
|
||||
Recommended properties:
|
||||
- syscon-phy-power : phandle/offset pair. Phandle to the system control
|
||||
module and the register offset to power on/off the PHY.
|
||||
|
||||
This is usually a subnode of ocp2scp to which it is connected.
|
||||
|
||||
usb3phy@4a084400 {
|
||||
compatible = "ti,phy-usb3";
|
||||
reg = <0x4a084400 0x80>,
|
||||
<0x4a084800 0x64>,
|
||||
<0x4a084c00 0x40>;
|
||||
reg-names = "phy_rx", "phy_tx", "pll_ctrl";
|
||||
ctrl-module = <&omap_control_usb>;
|
||||
#phy-cells = <0>;
|
||||
clocks = <&usb_phy_cm_clk32k>,
|
||||
<&sys_clkin>,
|
||||
<&usb_otg_ss_refclk960m>;
|
||||
clock-names = "wkupclk",
|
||||
"sysclk",
|
||||
"refclk";
|
||||
};
|
||||
|
||||
sata_phy: phy@4a096000 {
|
||||
compatible = "ti,phy-pipe3-sata";
|
||||
reg = <0x4A096000 0x80>, /* phy_rx */
|
||||
<0x4A096400 0x64>, /* phy_tx */
|
||||
<0x4A096800 0x40>; /* pll_ctrl */
|
||||
reg-names = "phy_rx", "phy_tx", "pll_ctrl";
|
||||
ctrl-module = <&omap_control_sata>;
|
||||
clocks = <&sys_clkin1>, <&sata_ref_clk>;
|
||||
clock-names = "sysclk", "refclk";
|
||||
syscon-pllreset = <&scm_conf 0x3fc>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
@@ -2520,6 +2520,7 @@ F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
|
||||
F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
|
||||
F: Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml
|
||||
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
|
||||
F: Documentation/devicetree/bindings/phy/apple,atcphy.yaml
|
||||
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
|
||||
F: Documentation/devicetree/bindings/power/apple*
|
||||
F: Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml
|
||||
@@ -2548,6 +2549,7 @@ F: drivers/mfd/macsmc.c
|
||||
F: drivers/nvme/host/apple.c
|
||||
F: drivers/nvmem/apple-efuses.c
|
||||
F: drivers/nvmem/apple-spmi-nvmem.c
|
||||
F: drivers/phy/apple/
|
||||
F: drivers/pinctrl/pinctrl-apple-gpio.c
|
||||
F: drivers/power/reset/macsmc-reboot.c
|
||||
F: drivers/pwm/pwm-apple.c
|
||||
@@ -10858,10 +10860,12 @@ S: Maintained
|
||||
P: Documentation/process/maintainer-soc-clean-dts.rst
|
||||
C: irc://irc.oftc.net/pixel6-kernel-dev
|
||||
F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
|
||||
F: Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml
|
||||
F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml
|
||||
F: Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml
|
||||
F: arch/arm64/boot/dts/exynos/google/
|
||||
F: drivers/clk/samsung/clk-gs101.c
|
||||
F: drivers/phy/phy-google-usb.c
|
||||
F: drivers/soc/samsung/gs101-pmu.c
|
||||
F: drivers/phy/samsung/phy-gs101-ufs.c
|
||||
F: drivers/usb/dwc3/dwc3-google.c
|
||||
|
||||
@@ -10,7 +10,7 @@ obj-y += cache/
|
||||
obj-y += irqchip/
|
||||
obj-y += bus/
|
||||
|
||||
obj-$(CONFIG_GENERIC_PHY) += phy/
|
||||
obj-y += phy/
|
||||
|
||||
# GPIO must come after pinctrl as gpios may need to mux pins etc
|
||||
obj-$(CONFIG_PINCTRL) += pinctrl/
|
||||
|
||||
@@ -47,6 +47,17 @@ config GENERIC_PHY_MIPI_DPHY
|
||||
Provides a number of helpers a core functions for MIPI D-PHY
|
||||
drivers to us.
|
||||
|
||||
config PHY_GOOGLE_USB
|
||||
tristate "Google Tensor SoC USB PHY driver"
|
||||
select GENERIC_PHY
|
||||
depends on TYPEC
|
||||
help
|
||||
Enable support for the USB PHY on Google Tensor SoCs, starting with
|
||||
the G5 generation (Laguna). This driver provides the PHY interfaces
|
||||
to interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY,
|
||||
both of which are integrated with the DWC3 USB DRD controller.
|
||||
This driver currently supports USB high-speed.
|
||||
|
||||
config PHY_LPC18XX_USB_OTG
|
||||
tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
|
||||
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
|
||||
@@ -123,8 +134,21 @@ config PHY_NXP_PTN3222
|
||||
schemes. It supports all three USB 2.0 data rates: Low Speed, Full
|
||||
Speed and High Speed.
|
||||
|
||||
config PHY_SPACEMIT_K1_PCIE
|
||||
tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC"
|
||||
depends on ARCH_SPACEMIT || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
default ARCH_SPACEMIT
|
||||
help
|
||||
Enable support for the PCIe and USB 3 combo PHY and two
|
||||
PCIe-only PHYs used in the SpacemiT K1 SoC.
|
||||
|
||||
source "drivers/phy/allwinner/Kconfig"
|
||||
source "drivers/phy/amlogic/Kconfig"
|
||||
source "drivers/phy/apple/Kconfig"
|
||||
source "drivers/phy/broadcom/Kconfig"
|
||||
source "drivers/phy/cadence/Kconfig"
|
||||
source "drivers/phy/freescale/Kconfig"
|
||||
@@ -145,6 +169,7 @@ source "drivers/phy/rockchip/Kconfig"
|
||||
source "drivers/phy/samsung/Kconfig"
|
||||
source "drivers/phy/socionext/Kconfig"
|
||||
source "drivers/phy/sophgo/Kconfig"
|
||||
source "drivers/phy/spacemit/Kconfig"
|
||||
source "drivers/phy/st/Kconfig"
|
||||
source "drivers/phy/starfive/Kconfig"
|
||||
source "drivers/phy/sunplus/Kconfig"
|
||||
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_COMMON_PROPS_TEST) += phy-common-props-test.o
|
||||
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
|
||||
obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
|
||||
obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o
|
||||
obj-$(CONFIG_PHY_GOOGLE_USB) += phy-google-usb.o
|
||||
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
|
||||
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
|
||||
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
|
||||
@@ -15,8 +16,10 @@ obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snps-eusb2.o
|
||||
obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o
|
||||
obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
|
||||
obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
|
||||
obj-y += allwinner/ \
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o
|
||||
obj-$(CONFIG_GENERIC_PHY) += allwinner/ \
|
||||
amlogic/ \
|
||||
apple/ \
|
||||
broadcom/ \
|
||||
cadence/ \
|
||||
freescale/ \
|
||||
@@ -38,6 +41,7 @@ obj-y += allwinner/ \
|
||||
samsung/ \
|
||||
socionext/ \
|
||||
sophgo/ \
|
||||
spacemit/ \
|
||||
st/ \
|
||||
starfive/ \
|
||||
sunplus/ \
|
||||
|
||||
@@ -359,7 +359,7 @@ static int sun4i_usb_phy_init(struct phy *_phy)
|
||||
/* Force ISCR and cable state updates */
|
||||
data->id_det = -1;
|
||||
data->vbus_det = -1;
|
||||
queue_delayed_work(system_wq, &data->detect, 0);
|
||||
queue_delayed_work(system_percpu_wq, &data->detect, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -482,7 +482,7 @@ static int sun4i_usb_phy_power_on(struct phy *_phy)
|
||||
|
||||
/* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
|
||||
if (phy->index == 0 && sun4i_usb_phy0_poll(data))
|
||||
mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
|
||||
mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -503,7 +503,7 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
|
||||
* Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
|
||||
*/
|
||||
if (phy->index == 0 && !sun4i_usb_phy0_poll(data))
|
||||
mod_delayed_work(system_wq, &data->detect, POLL_TIME);
|
||||
mod_delayed_work(system_percpu_wq, &data->detect, POLL_TIME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -542,7 +542,7 @@ static int sun4i_usb_phy_set_mode(struct phy *_phy,
|
||||
|
||||
data->id_det = -1; /* Force reprocessing of id */
|
||||
data->force_session_end = true;
|
||||
queue_delayed_work(system_wq, &data->detect, 0);
|
||||
queue_delayed_work(system_percpu_wq, &data->detect, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -654,7 +654,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
|
||||
extcon_set_state_sync(data->extcon, EXTCON_USB, vbus_det);
|
||||
|
||||
if (sun4i_usb_phy0_poll(data))
|
||||
queue_delayed_work(system_wq, &data->detect, POLL_TIME);
|
||||
queue_delayed_work(system_percpu_wq, &data->detect, POLL_TIME);
|
||||
}
|
||||
|
||||
static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id)
|
||||
@@ -662,7 +662,7 @@ static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id)
|
||||
struct sun4i_usb_phy_data *data = dev_id;
|
||||
|
||||
/* vbus or id changed, let the pins settle and then scan them */
|
||||
mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
|
||||
mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -676,7 +676,7 @@ static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,
|
||||
|
||||
/* Properties on the vbus_power_supply changed, scan vbus_det */
|
||||
if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply)
|
||||
mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
|
||||
mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
13
drivers/phy/apple/Kconfig
Normal file
13
drivers/phy/apple/Kconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
config PHY_APPLE_ATC
|
||||
tristate "Apple Type-C PHY"
|
||||
depends on (ARM64 && ARCH_APPLE) || (COMPILE_TEST && !GENERIC_ATOMIC64)
|
||||
depends on TYPEC
|
||||
select GENERIC_PHY
|
||||
select APPLE_TUNABLE
|
||||
help
|
||||
Enable this to add support for the Apple Type-C PHY found in
|
||||
Apple Silicon M-series SoCs. This PHY supports USB2,
|
||||
USB3, USB4, Thunderbolt, and DisplayPort.
|
||||
|
||||
If M is selected the module will be called 'phy-apple-atc'.
|
||||
4
drivers/phy/apple/Makefile
Normal file
4
drivers/phy/apple/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
|
||||
obj-$(CONFIG_PHY_APPLE_ATC) += phy-apple-atc.o
|
||||
phy-apple-atc-y := atc.o
|
||||
2295
drivers/phy/apple/atc.c
Normal file
2295
drivers/phy/apple/atc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ enum cdns_torrent_phy_type {
|
||||
TYPE_USB,
|
||||
TYPE_USXGMII,
|
||||
TYPE_PCIE_ML,
|
||||
TYPE_XAUI,
|
||||
};
|
||||
|
||||
enum cdns_torrent_ref_clk {
|
||||
@@ -320,14 +321,14 @@ enum cdns_torrent_ssc_mode {
|
||||
/* Unique key id for vals table entry
|
||||
* REFCLK0_RATE | REFCLK1_RATE | LINK0_TYPE | LINK1_TYPE | SSC_TYPE
|
||||
*/
|
||||
#define REFCLK0_SHIFT 12
|
||||
#define REFCLK0_MASK GENMASK(14, 12)
|
||||
#define REFCLK1_SHIFT 9
|
||||
#define REFCLK1_MASK GENMASK(11, 9)
|
||||
#define LINK0_SHIFT 6
|
||||
#define LINK0_MASK GENMASK(8, 6)
|
||||
#define REFCLK0_SHIFT 15
|
||||
#define REFCLK0_MASK GENMASK(18, 15)
|
||||
#define REFCLK1_SHIFT 11
|
||||
#define REFCLK1_MASK GENMASK(14, 11)
|
||||
#define LINK0_SHIFT 7
|
||||
#define LINK0_MASK GENMASK(10, 7)
|
||||
#define LINK1_SHIFT 3
|
||||
#define LINK1_MASK GENMASK(5, 3)
|
||||
#define LINK1_MASK GENMASK(6, 3)
|
||||
#define SSC_SHIFT 0
|
||||
#define SSC_MASK GENMASK(2, 0)
|
||||
|
||||
@@ -397,6 +398,7 @@ struct cdns_torrent_refclk_driver {
|
||||
struct clk_hw hw;
|
||||
struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
|
||||
struct clk_init_data clk_data;
|
||||
u8 parent_index;
|
||||
};
|
||||
|
||||
#define to_cdns_torrent_refclk_driver(_hw) \
|
||||
@@ -708,6 +710,8 @@ static const char *cdns_torrent_get_phy_type(enum cdns_torrent_phy_type phy_type
|
||||
return "USB";
|
||||
case TYPE_USXGMII:
|
||||
return "USXGMII";
|
||||
case TYPE_XAUI:
|
||||
return "XAUI";
|
||||
default:
|
||||
return "None";
|
||||
}
|
||||
@@ -3020,6 +3024,9 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
||||
case PHY_TYPE_USXGMII:
|
||||
cdns_phy->phys[node].phy_type = TYPE_USXGMII;
|
||||
break;
|
||||
case PHY_TYPE_XAUI:
|
||||
cdns_phy->phys[node].phy_type = TYPE_XAUI;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Unsupported protocol\n");
|
||||
ret = -EINVAL;
|
||||
@@ -3326,11 +3333,29 @@ static const struct cdns_torrent_vals sgmii_qsgmii_xcvr_diag_ln_vals = {
|
||||
.num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs),
|
||||
};
|
||||
|
||||
static void cdns_torrent_refclk_driver_suspend(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
|
||||
struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
|
||||
|
||||
refclk_driver->parent_index = cdns_torrent_refclk_driver_get_parent(hw);
|
||||
}
|
||||
|
||||
static int cdns_torrent_refclk_driver_resume(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER];
|
||||
struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
|
||||
|
||||
return cdns_torrent_refclk_driver_set_parent(hw, refclk_driver->parent_index);
|
||||
}
|
||||
|
||||
static int cdns_torrent_phy_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
cdns_torrent_refclk_driver_suspend(cdns_phy);
|
||||
|
||||
reset_control_assert(cdns_phy->phy_rst);
|
||||
reset_control_assert(cdns_phy->apb_rst);
|
||||
for (i = 0; i < cdns_phy->nsubnodes; i++)
|
||||
@@ -3352,6 +3377,10 @@ static int cdns_torrent_phy_resume_noirq(struct device *dev)
|
||||
int node = cdns_phy->nsubnodes;
|
||||
int ret, i;
|
||||
|
||||
ret = cdns_torrent_refclk_driver_resume(cdns_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cdns_torrent_clk(cdns_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -3382,6 +3411,95 @@ static DEFINE_NOIRQ_DEV_PM_OPS(cdns_torrent_phy_pm_ops,
|
||||
cdns_torrent_phy_suspend_noirq,
|
||||
cdns_torrent_phy_resume_noirq);
|
||||
|
||||
/* PCIe and XAUI link configuration */
|
||||
static const struct cdns_reg_pairs pcie_xaui_link_cmn_regs[] = {
|
||||
{0x0003, PHY_PLL_CFG},
|
||||
{0x0600, CMN_PDIAG_PLL1_CLK_SEL_M0}
|
||||
};
|
||||
|
||||
static const struct cdns_reg_pairs xaui_pcie_xcvr_diag_ln_regs[] = {
|
||||
{0x0011, XCVR_DIAG_HSCLK_SEL},
|
||||
{0x0089, XCVR_DIAG_PLLDRC_CTRL}
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals pcie_xaui_link_cmn_vals = {
|
||||
.reg_pairs = pcie_xaui_link_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(pcie_xaui_link_cmn_regs),
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals xaui_pcie_xcvr_diag_ln_vals = {
|
||||
.reg_pairs = xaui_pcie_xcvr_diag_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(xaui_pcie_xcvr_diag_ln_regs),
|
||||
};
|
||||
|
||||
/* XAUI 100 MHz Ref clk, no SSC */
|
||||
static const struct cdns_reg_pairs xaui_100_no_ssc_cmn_regs[] = {
|
||||
{0x0004, CMN_PLL1_DSM_DIAG_M0},
|
||||
{0x0B17, CMN_PDIAG_PLL1_CP_PADJ_M0},
|
||||
{0x0E01, CMN_PDIAG_PLL1_CP_IADJ_M0},
|
||||
{0x0D05, CMN_PDIAG_PLL1_FILT_PADJ_M0},
|
||||
{0x003E, CMN_PLL1_INTDIV_M0},
|
||||
{0x8000, CMN_PLL1_FRACDIVL_M0},
|
||||
{0x0002, CMN_PLL1_FRACDIVH_M0},
|
||||
{0x002A, CMN_PLL1_HIGH_THR_M0},
|
||||
{0x3102, CMN_PDIAG_PLL1_CTRL_M0},
|
||||
{0x007F, CMN_TXPUCAL_TUNE},
|
||||
{0x007F, CMN_TXPDCAL_TUNE}
|
||||
};
|
||||
|
||||
static const struct cdns_reg_pairs xaui_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x00F3, TX_PSC_A0},
|
||||
{0x04A2, TX_PSC_A2},
|
||||
{0x04A2, TX_PSC_A3 },
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00}
|
||||
};
|
||||
|
||||
static const struct cdns_reg_pairs ti_xaui_100_no_ssc_tx_ln_regs[] = {
|
||||
{0x00F3, TX_PSC_A0},
|
||||
{0x04A2, TX_PSC_A2},
|
||||
{0x04A2, TX_PSC_A3 },
|
||||
{0x0000, TX_TXCC_CPOST_MULT_00},
|
||||
{0x4000, XCVR_DIAG_RXCLK_CTRL}
|
||||
};
|
||||
|
||||
static const struct cdns_reg_pairs xaui_100_no_ssc_rx_ln_regs[] = {
|
||||
{0x091D, RX_PSC_A0},
|
||||
{0x0900, RX_PSC_A2},
|
||||
{0x0100, RX_PSC_A3},
|
||||
{0x03C7, RX_REE_GCSM1_EQENM_PH1},
|
||||
{0x01C7, RX_REE_GCSM1_EQENM_PH2},
|
||||
{0x0000, RX_DIAG_DFE_CTRL},
|
||||
{0x0019, RX_REE_TAP1_CLIP},
|
||||
{0x0019, RX_REE_TAP2TON_CLIP},
|
||||
{0x0098, RX_DIAG_NQST_CTRL},
|
||||
{0x0C01, RX_DIAG_DFE_AMP_TUNE_2},
|
||||
{0x0000, RX_DIAG_DFE_AMP_TUNE_3},
|
||||
{0x0000, RX_DIAG_PI_CAP},
|
||||
{0x0031, RX_DIAG_PI_RATE},
|
||||
{0x0001, RX_DIAG_ACYA},
|
||||
{0x018C, RX_CDRLF_CNFG},
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals xaui_100_no_ssc_cmn_vals = {
|
||||
.reg_pairs = xaui_100_no_ssc_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(xaui_100_no_ssc_cmn_regs),
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals xaui_100_no_ssc_tx_ln_vals = {
|
||||
.reg_pairs = xaui_100_no_ssc_tx_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(xaui_100_no_ssc_tx_ln_regs),
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals ti_xaui_100_no_ssc_tx_ln_vals = {
|
||||
.reg_pairs = ti_xaui_100_no_ssc_tx_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ti_xaui_100_no_ssc_tx_ln_regs),
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals xaui_100_no_ssc_rx_ln_vals = {
|
||||
.reg_pairs = xaui_100_no_ssc_rx_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(xaui_100_no_ssc_rx_ln_regs),
|
||||
};
|
||||
|
||||
/* USB and DP link configuration */
|
||||
static const struct cdns_reg_pairs usb_dp_link_cmn_regs[] = {
|
||||
{0x0002, PHY_PLL_CFG},
|
||||
@@ -4853,6 +4971,7 @@ static const struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), &pcie_xaui_link_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_link_cmn_vals},
|
||||
|
||||
@@ -4879,6 +4998,8 @@ static const struct cdns_torrent_vals_entry link_cmn_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &pcie_usxgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_link_cmn_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_link_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &pcie_xaui_link_cmn_vals},
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
|
||||
@@ -4893,6 +5014,7 @@ static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_xcvr_diag_ln_vals},
|
||||
|
||||
@@ -4919,6 +5041,8 @@ static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = {
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &usxgmii_pcie_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_xcvr_diag_ln_vals},
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_xcvr_diag_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &xaui_pcie_xcvr_diag_ln_vals},
|
||||
};
|
||||
|
||||
static const struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = {
|
||||
@@ -4960,6 +5084,8 @@ static const struct cdns_torrent_vals_entry cmn_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
|
||||
@@ -5010,6 +5136,8 @@ static const struct cdns_torrent_vals_entry cmn_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5054,6 +5182,8 @@ static const struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
|
||||
@@ -5104,6 +5234,8 @@ static const struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5148,6 +5280,8 @@ static const struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals},
|
||||
@@ -5198,6 +5332,8 @@ static const struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5278,6 +5414,8 @@ static const struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
|
||||
@@ -5328,6 +5466,8 @@ static const struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5406,6 +5546,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals},
|
||||
@@ -5456,6 +5598,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5500,6 +5644,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL},
|
||||
@@ -5550,6 +5696,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
@@ -5594,6 +5742,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals},
|
||||
@@ -5644,6 +5794,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = {
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals},
|
||||
|
||||
{CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals},
|
||||
|
||||
/* Dual refclk */
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#define PHY_CTRL0_FSEL_MASK GENMASK(10, 5)
|
||||
#define PHY_CTRL0_FSEL_24M 0x2a
|
||||
#define PHY_CTRL0_FSEL_100M 0x27
|
||||
#define PHY_CTRL0_SSC_RANGE_MASK GENMASK(23, 21)
|
||||
#define PHY_CTRL0_SSC_RANGE_4003PPM 0x2
|
||||
#define PHY_CTRL0_SSC_RANGE_4492PPM 0x1
|
||||
#define PHY_CTRL0_SSC_RANGE_4980PPM 0x0
|
||||
|
||||
#define PHY_CTRL1 0x4
|
||||
#define PHY_CTRL1_RESET BIT(0)
|
||||
@@ -47,6 +51,7 @@
|
||||
#define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0)
|
||||
|
||||
#define PHY_CTRL6 0x18
|
||||
#define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29)
|
||||
#define PHY_CTRL6_ALT_CLK_EN BIT(1)
|
||||
#define PHY_CTRL6_ALT_CLK_SEL BIT(0)
|
||||
|
||||
@@ -587,6 +592,9 @@ static int imx8mp_usb_phy_init(struct phy *phy)
|
||||
|
||||
value = readl(imx_phy->base + PHY_CTRL0);
|
||||
value |= PHY_CTRL0_REF_SSP_EN;
|
||||
value &= ~PHY_CTRL0_SSC_RANGE_MASK;
|
||||
value |= FIELD_PREP(PHY_CTRL0_SSC_RANGE_MASK,
|
||||
PHY_CTRL0_SSC_RANGE_4003PPM);
|
||||
writel(value, imx_phy->base + PHY_CTRL0);
|
||||
|
||||
value = readl(imx_phy->base + PHY_CTRL2);
|
||||
@@ -610,6 +618,7 @@ static int imx8mp_usb_phy_init(struct phy *phy)
|
||||
static int imx8mq_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
ret = regulator_enable(imx_phy->vbus);
|
||||
@@ -626,12 +635,23 @@ static int imx8mq_phy_power_on(struct phy *phy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Disable rx term override */
|
||||
value = readl(imx_phy->base + PHY_CTRL6);
|
||||
value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL;
|
||||
writel(value, imx_phy->base + PHY_CTRL6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx8mq_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
|
||||
u32 value;
|
||||
|
||||
/* Override rx term to be 0 */
|
||||
value = readl(imx_phy->base + PHY_CTRL6);
|
||||
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);
|
||||
@@ -676,6 +696,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
if (!imx_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, imx_phy);
|
||||
|
||||
imx_phy->clk = devm_clk_get(dev, "phy");
|
||||
if (IS_ERR(imx_phy->clk)) {
|
||||
dev_err(dev, "failed to get imx8mq usb phy clock\n");
|
||||
@@ -730,6 +752,7 @@ static struct platform_driver imx8mq_usb_phy_driver = {
|
||||
.driver = {
|
||||
.name = "imx8mq-usb-phy",
|
||||
.of_match_table = imx8mq_usb_phy_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
}
|
||||
};
|
||||
module_platform_driver(imx8mq_usb_phy_driver);
|
||||
|
||||
@@ -251,7 +251,7 @@ static void imx_hsio_configure_clk_pad(struct phy *phy)
|
||||
struct imx_hsio_lane *lane = phy_get_drvdata(phy);
|
||||
struct imx_hsio_priv *priv = lane->priv;
|
||||
|
||||
if (strncmp(priv->refclk_pad, "output", 6) == 0) {
|
||||
if (priv->refclk_pad && strncmp(priv->refclk_pad, "output", 6) == 0) {
|
||||
pll = true;
|
||||
regmap_update_bits(priv->misc, HSIO_CTRL0,
|
||||
HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK,
|
||||
|
||||
@@ -286,11 +286,9 @@ static int mixel_lvds_phy_reset(struct device *dev)
|
||||
|
||||
regmap_write(priv->regmap, PHY_CTRL, CTRL_RESET_VAL);
|
||||
|
||||
ret = pm_runtime_put(dev);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "failed to put PM runtime: %d\n", ret);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct phy *mixel_lvds_phy_xlate(struct device *dev,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -570,17 +570,20 @@ const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_h
|
||||
return fract_div_phy;
|
||||
}
|
||||
|
||||
static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long *parent_rate)
|
||||
static int fsl_samsung_hdmi_phy_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
|
||||
const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate);
|
||||
const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy,
|
||||
req->rate);
|
||||
|
||||
if (target_settings == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk);
|
||||
return target_settings->pixclk;
|
||||
req->rate = target_settings->pixclk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
|
||||
@@ -599,7 +602,7 @@ static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
|
||||
|
||||
static const struct clk_ops phy_clk_ops = {
|
||||
.recalc_rate = phy_clk_recalc_rate,
|
||||
.round_rate = fsl_samsung_hdmi_phy_clk_round_rate,
|
||||
.determine_rate = fsl_samsung_hdmi_phy_clk_determine_rate,
|
||||
.set_rate = fsl_samsung_hdmi_phy_clk_set_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1);
|
||||
port->dr_mode = of_usb_get_dr_mode_by_phy(child, 0);
|
||||
if ((port->dr_mode != USB_DR_MODE_HOST) &&
|
||||
(port->dr_mode != USB_DR_MODE_PERIPHERAL)) {
|
||||
dev_err(&pdev->dev,
|
||||
|
||||
@@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
||||
usleep_range(80, 100);
|
||||
}
|
||||
|
||||
static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
return rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@@ -170,7 +170,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
|
||||
.prepare = mtk_hdmi_pll_prepare,
|
||||
.unprepare = mtk_hdmi_pll_unprepare,
|
||||
.set_rate = mtk_hdmi_pll_set_rate,
|
||||
.round_rate = mtk_hdmi_pll_round_rate,
|
||||
.determine_rate = mtk_hdmi_pll_determine_rate,
|
||||
.recalc_rate = mtk_hdmi_pll_recalc_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -118,18 +118,18 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
||||
usleep_range(100, 150);
|
||||
}
|
||||
|
||||
static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
|
||||
|
||||
hdmi_phy->pll_rate = rate;
|
||||
if (rate <= 74250000)
|
||||
*parent_rate = rate;
|
||||
hdmi_phy->pll_rate = req->rate;
|
||||
if (req->rate <= 74250000)
|
||||
req->best_parent_rate = req->rate;
|
||||
else
|
||||
*parent_rate = rate / 2;
|
||||
req->best_parent_rate = req->rate / 2;
|
||||
|
||||
return rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@@ -223,7 +223,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
|
||||
.prepare = mtk_hdmi_pll_prepare,
|
||||
.unprepare = mtk_hdmi_pll_unprepare,
|
||||
.set_rate = mtk_hdmi_pll_set_rate,
|
||||
.round_rate = mtk_hdmi_pll_round_rate,
|
||||
.determine_rate = mtk_hdmi_pll_determine_rate,
|
||||
.recalc_rate = mtk_hdmi_pll_recalc_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -418,13 +418,13 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate);
|
||||
}
|
||||
|
||||
static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
|
||||
|
||||
hdmi_phy->pll_rate = rate;
|
||||
return rate;
|
||||
hdmi_phy->pll_rate = req->rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
|
||||
@@ -439,7 +439,7 @@ static const struct clk_ops mtk_hdmi_pll_ops = {
|
||||
.prepare = mtk_hdmi_pll_prepare,
|
||||
.unprepare = mtk_hdmi_pll_unprepare,
|
||||
.set_rate = mtk_hdmi_pll_set_rate,
|
||||
.round_rate = mtk_hdmi_pll_round_rate,
|
||||
.determine_rate = mtk_hdmi_pll_determine_rate,
|
||||
.recalc_rate = mtk_hdmi_pll_recalc_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -237,16 +237,18 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
|
||||
mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK);
|
||||
}
|
||||
|
||||
static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
return clamp_val(rate, 50000000, 1250000000);
|
||||
req->rate = clamp_val(req->rate, 50000000, 1250000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops mtk_mipi_tx_pll_ops = {
|
||||
.prepare = mtk_mipi_tx_pll_prepare,
|
||||
.unprepare = mtk_mipi_tx_pll_unprepare,
|
||||
.round_rate = mtk_mipi_tx_pll_round_rate,
|
||||
.determine_rate = mtk_mipi_tx_pll_determine_rate,
|
||||
.set_rate = mtk_mipi_tx_pll_set_rate,
|
||||
.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
|
||||
};
|
||||
|
||||
@@ -97,16 +97,18 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
|
||||
mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
|
||||
}
|
||||
|
||||
static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
return clamp_val(rate, 125000000, 1600000000);
|
||||
req->rate = clamp_val(req->rate, 125000000, 1600000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops mtk_mipi_tx_pll_ops = {
|
||||
.enable = mtk_mipi_tx_pll_enable,
|
||||
.disable = mtk_mipi_tx_pll_disable,
|
||||
.round_rate = mtk_mipi_tx_pll_round_rate,
|
||||
.determine_rate = mtk_mipi_tx_pll_determine_rate,
|
||||
.set_rate = mtk_mipi_tx_pll_set_rate,
|
||||
.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
|
||||
};
|
||||
|
||||
@@ -353,7 +353,7 @@ static int mtk_xfi_tphy_power_on(struct phy *phy)
|
||||
* Disable and unprepare all clocks previously enabled.
|
||||
*
|
||||
* Return:
|
||||
* See clk_bulk_prepare_disable().
|
||||
* See clk_bulk_disable_unprepare().
|
||||
*/
|
||||
static int mtk_xfi_tphy_power_off(struct phy *phy)
|
||||
{
|
||||
|
||||
@@ -138,17 +138,14 @@ static struct phy *phy_find(struct device *dev, const char *con_id)
|
||||
static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct device_node *child;
|
||||
|
||||
list_for_each_entry(phy_provider, &phy_provider_list, list) {
|
||||
if (phy_provider->dev->of_node == node)
|
||||
return phy_provider;
|
||||
|
||||
for_each_child_of_node(phy_provider->children, child)
|
||||
if (child == node) {
|
||||
of_node_put(child);
|
||||
for_each_child_of_node_scoped(phy_provider->children, child)
|
||||
if (child == node)
|
||||
return phy_provider;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
@@ -190,15 +187,15 @@ int phy_pm_runtime_get_sync(struct phy *phy)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync);
|
||||
|
||||
int phy_pm_runtime_put(struct phy *phy)
|
||||
void phy_pm_runtime_put(struct phy *phy)
|
||||
{
|
||||
if (!phy)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (!pm_runtime_enabled(&phy->dev))
|
||||
return -ENOTSUPP;
|
||||
return;
|
||||
|
||||
return pm_runtime_put(&phy->dev);
|
||||
pm_runtime_put(&phy->dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phy_pm_runtime_put);
|
||||
|
||||
|
||||
296
drivers/phy/phy-google-usb.c
Normal file
296
drivers/phy/phy-google-usb.c
Normal file
@@ -0,0 +1,296 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* phy-google-usb.c - Google USB PHY driver
|
||||
*
|
||||
* Copyright (C) 2025, Google LLC
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/usb/typec_mux.h>
|
||||
|
||||
#define USBCS_USB2PHY_CFG19_OFFSET 0x0
|
||||
#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
|
||||
|
||||
#define USBCS_USB2PHY_CFG21_OFFSET 0x8
|
||||
#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
|
||||
#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
|
||||
#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
|
||||
|
||||
#define USBCS_PHY_CFG1_OFFSET 0x28
|
||||
#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
|
||||
|
||||
enum google_usb_phy_id {
|
||||
GOOGLE_USB2_PHY,
|
||||
GOOGLE_USB_PHY_NUM,
|
||||
};
|
||||
|
||||
struct google_usb_phy_instance {
|
||||
struct google_usb_phy *parent;
|
||||
unsigned int index;
|
||||
struct phy *phy;
|
||||
unsigned int num_clks;
|
||||
struct clk_bulk_data *clks;
|
||||
unsigned int num_rsts;
|
||||
struct reset_control_bulk_data *rsts;
|
||||
};
|
||||
|
||||
struct google_usb_phy {
|
||||
struct device *dev;
|
||||
struct regmap *usb_cfg_regmap;
|
||||
unsigned int usb2_cfg_offset;
|
||||
void __iomem *usbdp_top_base;
|
||||
struct google_usb_phy_instance *insts;
|
||||
/*
|
||||
* Protect phy registers from concurrent access, specifically via
|
||||
* google_usb_set_orientation callback.
|
||||
*/
|
||||
struct mutex phy_mutex;
|
||||
struct typec_switch_dev *sw;
|
||||
enum typec_orientation orientation;
|
||||
};
|
||||
|
||||
static void set_vbus_valid(struct google_usb_phy *gphy)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
|
||||
reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
|
||||
reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
|
||||
writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
|
||||
} else {
|
||||
reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
|
||||
reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
|
||||
writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
static int google_usb_set_orientation(struct typec_switch_dev *sw,
|
||||
enum typec_orientation orientation)
|
||||
{
|
||||
struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
|
||||
|
||||
dev_dbg(gphy->dev, "set orientation %d\n", orientation);
|
||||
|
||||
gphy->orientation = orientation;
|
||||
|
||||
if (pm_runtime_suspended(gphy->dev))
|
||||
return 0;
|
||||
|
||||
guard(mutex)(&gphy->phy_mutex);
|
||||
|
||||
set_vbus_valid(gphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int google_usb2_phy_init(struct phy *_phy)
|
||||
{
|
||||
struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
|
||||
struct google_usb_phy *gphy = inst->parent;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
dev_dbg(gphy->dev, "initializing usb2 phy\n");
|
||||
|
||||
guard(mutex)(&gphy->phy_mutex);
|
||||
|
||||
regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®);
|
||||
reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
|
||||
reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
|
||||
reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
|
||||
regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
|
||||
|
||||
regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, ®);
|
||||
reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
|
||||
reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);
|
||||
regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, reg);
|
||||
|
||||
set_vbus_valid(gphy);
|
||||
|
||||
ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
|
||||
if (ret) {
|
||||
clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®);
|
||||
reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
|
||||
regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int google_usb2_phy_exit(struct phy *_phy)
|
||||
{
|
||||
struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
|
||||
struct google_usb_phy *gphy = inst->parent;
|
||||
u32 reg;
|
||||
|
||||
dev_dbg(gphy->dev, "exiting usb2 phy\n");
|
||||
|
||||
guard(mutex)(&gphy->phy_mutex);
|
||||
|
||||
regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®);
|
||||
reg &= ~USBCS_USB2PHY_CFG21_PHY_ENABLE;
|
||||
regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
|
||||
|
||||
reset_control_bulk_assert(inst->num_rsts, inst->rsts);
|
||||
clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops google_usb2_phy_ops = {
|
||||
.init = google_usb2_phy_init,
|
||||
.exit = google_usb2_phy_exit,
|
||||
};
|
||||
|
||||
static struct phy *google_usb_phy_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
{
|
||||
struct google_usb_phy *gphy = dev_get_drvdata(dev);
|
||||
|
||||
if (args->args[0] >= GOOGLE_USB_PHY_NUM) {
|
||||
dev_err(dev, "invalid PHY index requested from DT\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
return gphy->insts[args->args[0]].phy;
|
||||
}
|
||||
|
||||
static int google_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct typec_switch_desc sw_desc = { };
|
||||
struct google_usb_phy_instance *inst;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct google_usb_phy *gphy;
|
||||
struct phy *phy;
|
||||
u32 args[1];
|
||||
int ret;
|
||||
|
||||
gphy = devm_kzalloc(dev, sizeof(*gphy), GFP_KERNEL);
|
||||
if (!gphy)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, gphy);
|
||||
gphy->dev = dev;
|
||||
|
||||
ret = devm_mutex_init(dev, &gphy->phy_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gphy->usb_cfg_regmap =
|
||||
syscon_regmap_lookup_by_phandle_args(dev->of_node,
|
||||
"google,usb-cfg-csr",
|
||||
ARRAY_SIZE(args), args);
|
||||
if (IS_ERR(gphy->usb_cfg_regmap)) {
|
||||
return dev_err_probe(dev, PTR_ERR(gphy->usb_cfg_regmap),
|
||||
"invalid usb cfg csr\n");
|
||||
}
|
||||
|
||||
gphy->usb2_cfg_offset = args[0];
|
||||
|
||||
gphy->usbdp_top_base = devm_platform_ioremap_resource_byname(pdev,
|
||||
"usbdp_top");
|
||||
if (IS_ERR(gphy->usbdp_top_base))
|
||||
return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base),
|
||||
"invalid usbdp top\n");
|
||||
|
||||
gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL);
|
||||
if (!gphy->insts)
|
||||
return -ENOMEM;
|
||||
|
||||
inst = &gphy->insts[GOOGLE_USB2_PHY];
|
||||
inst->parent = gphy;
|
||||
inst->index = GOOGLE_USB2_PHY;
|
||||
phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
|
||||
if (IS_ERR(phy))
|
||||
return dev_err_probe(dev, PTR_ERR(phy),
|
||||
"failed to create usb2 phy instance\n");
|
||||
inst->phy = phy;
|
||||
phy_set_drvdata(phy, inst);
|
||||
|
||||
inst->num_clks = 2;
|
||||
inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
|
||||
if (!inst->clks)
|
||||
return -ENOMEM;
|
||||
inst->clks[0].id = "usb2";
|
||||
inst->clks[1].id = "usb2_apb";
|
||||
ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to get u2 phy clks\n");
|
||||
|
||||
inst->num_rsts = 2;
|
||||
inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
|
||||
if (!inst->rsts)
|
||||
return -ENOMEM;
|
||||
inst->rsts[0].id = "usb2";
|
||||
inst->rsts[1].id = "usb2_apb";
|
||||
ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to get u2 phy resets\n");
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return dev_err_probe(dev, PTR_ERR(phy_provider),
|
||||
"failed to register phy provider\n");
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
sw_desc.fwnode = dev_fwnode(dev);
|
||||
sw_desc.drvdata = gphy;
|
||||
sw_desc.name = fwnode_get_name(dev_fwnode(dev));
|
||||
sw_desc.set = google_usb_set_orientation;
|
||||
|
||||
gphy->sw = typec_switch_register(dev, &sw_desc);
|
||||
if (IS_ERR(gphy->sw))
|
||||
return dev_err_probe(dev, PTR_ERR(gphy->sw),
|
||||
"failed to register typec switch\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void google_usb_phy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
typec_switch_unregister(gphy->sw);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id google_usb_phy_of_match[] = {
|
||||
{
|
||||
.compatible = "google,lga-usb-phy",
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
|
||||
|
||||
static struct platform_driver google_usb_phy = {
|
||||
.probe = google_usb_phy_probe,
|
||||
.remove = google_usb_phy_remove,
|
||||
.driver = {
|
||||
.name = "google-usb-phy",
|
||||
.of_match_table = google_usb_phy_of_match,
|
||||
}
|
||||
};
|
||||
|
||||
module_platform_driver(google_usb_phy);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Google USB phy driver");
|
||||
670
drivers/phy/phy-spacemit-k1-pcie.c
Normal file
670
drivers/phy/phy-spacemit-k1-pcie.c
Normal file
@@ -0,0 +1,670 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver
|
||||
*
|
||||
* Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
/*
|
||||
* Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver
|
||||
* supports their PHYs.
|
||||
*
|
||||
* The PHY for PCIe port A is different from the PHYs for ports B and C:
|
||||
* - It has one lane, while ports B and C have two
|
||||
* - It is a combo PHY can be used for PCIe or USB 3
|
||||
* - It can automatically calibrate PCIe TX and RX termination settings
|
||||
*
|
||||
* The PHY functionality for PCIe ports B and C is identical:
|
||||
* - They have two PCIe lanes (but can be restricted to 1 via device tree)
|
||||
* - They are used for PCIe only
|
||||
* - They are configured using TX and RX values computed for port A
|
||||
*
|
||||
* A given board is designed to use the combo PHY for either PCIe or USB 3.
|
||||
* Whether the combo PHY is configured for PCIe or USB 3 is specified in
|
||||
* device tree using a phandle plus an argument. The argument indicates
|
||||
* the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3).
|
||||
*
|
||||
* Each PHY has a reset that it gets and deasserts during initialization.
|
||||
* Each depends also on other clocks and resets provided by the controller
|
||||
* hardware (PCIe or USB) it is associated with. The controller drivers
|
||||
* are required to enable any clocks and de-assert any resets that affect
|
||||
* PHY operation. In addition each PHY implements an internal PLL, driven
|
||||
* by an external (24 MHz) oscillator.
|
||||
*
|
||||
* PCIe PHYs must be programmed with RX and TX calibration values. The
|
||||
* combo PHY is the only one that can determine these values. They are
|
||||
* determined by temporarily enabling the combo PHY in PCIe mode at probe
|
||||
* time (if necessary). This calibration only needs to be done once, and
|
||||
* when it has completed the TX and RX values are saved.
|
||||
*
|
||||
* To allow the combo PHY to be enabled for calibration, the resets and
|
||||
* clocks it uses in PCIe mode must be supplied.
|
||||
*/
|
||||
|
||||
struct k1_pcie_phy {
|
||||
struct device *dev; /* PHY provider device */
|
||||
struct phy *phy;
|
||||
void __iomem *regs;
|
||||
u32 pcie_lanes; /* Max (1 or 2) unless limited by DT */
|
||||
struct clk *pll;
|
||||
struct clk_hw pll_hw; /* Private PLL clock */
|
||||
|
||||
/* The remaining fields are only used for the combo PHY */
|
||||
u32 type; /* PHY_TYPE_PCIE or PHY_TYPE_USB3 */
|
||||
struct regmap *pmu; /* MMIO regmap (no errors) */
|
||||
};
|
||||
|
||||
#define CALIBRATION_TIMEOUT 500000 /* For combo PHY (usec) */
|
||||
#define PLL_TIMEOUT 500000 /* For PHY PLL lock (usec) */
|
||||
#define POLL_DELAY 500 /* Time between polls (usec) */
|
||||
|
||||
/* Selecting the combo PHY operating mode requires APMU regmap access */
|
||||
#define SYSCON_APMU "spacemit,apmu"
|
||||
|
||||
/* PMU space, for selecting between PCIe and USB 3 mode (combo PHY only) */
|
||||
|
||||
#define PMUA_USB_PHY_CTRL0 0x0110
|
||||
#define COMBO_PHY_SEL BIT(3) /* 0: PCIe; 1: USB 3 */
|
||||
|
||||
#define PCIE_CLK_RES_CTRL 0x03cc
|
||||
#define PCIE_APP_HOLD_PHY_RST BIT(30)
|
||||
|
||||
/* PHY register space */
|
||||
|
||||
/* Offset between lane 0 and lane 1 registers when there are two */
|
||||
#define PHY_LANE_OFFSET 0x0400
|
||||
|
||||
/* PHY PLL configuration */
|
||||
#define PCIE_PU_ADDR_CLK_CFG 0x0008
|
||||
#define PLL_READY BIT(0) /* read-only */
|
||||
#define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7)
|
||||
#define TIMER_ADJ_USB 0x2
|
||||
#define TIMER_ADJ_PCIE 0x6
|
||||
#define CFG_SW_PHY_INIT_DONE BIT(11) /* We set after PLL config */
|
||||
|
||||
#define PCIE_RC_DONE_STATUS 0x0018
|
||||
#define CFG_FORCE_RCV_RETRY BIT(10) /* Used for PCIe */
|
||||
|
||||
/* PCIe PHY lane calibration; assumes 24MHz input clock */
|
||||
#define PCIE_RC_CAL_REG2 0x0020
|
||||
#define RC_CAL_TOGGLE BIT(22)
|
||||
#define CLKSEL GENMASK(31, 29)
|
||||
#define CLKSEL_24M 0x3
|
||||
|
||||
/* Additional PHY PLL configuration (USB 3 and PCIe) */
|
||||
#define PCIE_PU_PLL_1 0x0048
|
||||
#define REF_100_WSSC BIT(12) /* 1: input is 100MHz, SSC */
|
||||
#define FREF_SEL GENMASK(15, 13)
|
||||
#define FREF_24M 0x1
|
||||
#define SSC_DEP_SEL GENMASK(19, 16)
|
||||
#define SSC_DEP_NONE 0x0
|
||||
#define SSC_DEP_5000PPM 0xa
|
||||
|
||||
/* PCIe PHY configuration */
|
||||
#define PCIE_PU_PLL_2 0x004c
|
||||
#define GEN_REF100 BIT(4) /* 1: generate 100MHz clk */
|
||||
|
||||
#define PCIE_RX_REG1 0x0050
|
||||
#define EN_RTERM BIT(3)
|
||||
#define AFE_RTERM_REG GENMASK(11, 8)
|
||||
|
||||
#define PCIE_RX_REG2 0x0054
|
||||
#define RX_RTERM_SEL BIT(5) /* 0: use AFE_RTERM_REG value */
|
||||
|
||||
#define PCIE_LTSSM_DIS_ENTRY 0x005c
|
||||
#define CFG_REFCLK_MODE GENMASK(9, 8)
|
||||
#define RFCLK_MODE_DRIVER 0x1
|
||||
#define OVRD_REFCLK_MODE BIT(10) /* 1: use CFG_RFCLK_MODE */
|
||||
|
||||
#define PCIE_TX_REG1 0x0064
|
||||
#define TX_RTERM_REG GENMASK(15, 12)
|
||||
#define TX_RTERM_SEL BIT(25) /* 1: use TX_RTERM_REG */
|
||||
|
||||
/* Zeroed for the combo PHY operating in USB mode */
|
||||
#define USB3_TEST_CTRL 0x0068
|
||||
|
||||
/* PHY calibration values, determined by the combo PHY at probe time */
|
||||
#define PCIE_RCAL_RESULT 0x0084 /* Port A PHY only */
|
||||
#define RTERM_VALUE_RX GENMASK(3, 0)
|
||||
#define RTERM_VALUE_TX GENMASK(7, 4)
|
||||
#define R_TUNE_DONE BIT(10)
|
||||
|
||||
static u32 k1_phy_rterm = ~0; /* Invalid initial value */
|
||||
|
||||
/* Save the RX and TX receiver termination values */
|
||||
static void k1_phy_rterm_set(u32 val)
|
||||
{
|
||||
k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX);
|
||||
}
|
||||
|
||||
static bool k1_phy_rterm_valid(void)
|
||||
{
|
||||
/* Valid if no bits outside those we care about are set */
|
||||
return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX));
|
||||
}
|
||||
|
||||
static u32 k1_phy_rterm_rx(void)
|
||||
{
|
||||
return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm);
|
||||
}
|
||||
|
||||
static u32 k1_phy_rterm_tx(void)
|
||||
{
|
||||
return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm);
|
||||
}
|
||||
|
||||
/* Only the combo PHY has a PMU pointer defined */
|
||||
static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
return !!k1_phy->pmu;
|
||||
}
|
||||
|
||||
/* The PLL clocks are driven by the external oscillator */
|
||||
static const struct clk_parent_data k1_pcie_phy_data[] = {
|
||||
{ .fw_name = "refclk", },
|
||||
};
|
||||
|
||||
static struct k1_pcie_phy *clk_hw_to_k1_phy(struct clk_hw *clk_hw)
|
||||
{
|
||||
return container_of(clk_hw, struct k1_pcie_phy, pll_hw);
|
||||
}
|
||||
|
||||
/* USB mode only works on the combo PHY, which has only one lane */
|
||||
static void k1_pcie_phy_pll_prepare_usb(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
void __iomem *regs = k1_phy->regs;
|
||||
u32 val;
|
||||
|
||||
val = readl(regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
val &= ~CFG_INTERNAL_TIMER_ADJ;
|
||||
val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_USB);
|
||||
writel(val, regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
|
||||
val = readl(regs + PCIE_PU_PLL_1);
|
||||
val &= ~SSC_DEP_SEL;
|
||||
val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_5000PPM);
|
||||
writel(val, regs + PCIE_PU_PLL_1);
|
||||
}
|
||||
|
||||
/* Perform PCIe-specific register updates before starting the PLL clock */
|
||||
static void k1_pcie_phy_pll_prepare_pcie(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
void __iomem *regs = k1_phy->regs;
|
||||
u32 val;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < k1_phy->pcie_lanes; i++) {
|
||||
val = readl(regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
val &= ~CFG_INTERNAL_TIMER_ADJ;
|
||||
val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_PCIE);
|
||||
writel(val, regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
|
||||
regs += PHY_LANE_OFFSET; /* Next lane */
|
||||
}
|
||||
|
||||
regs = k1_phy->regs;
|
||||
val = readl(regs + PCIE_RC_DONE_STATUS);
|
||||
val |= CFG_FORCE_RCV_RETRY;
|
||||
writel(val, regs + PCIE_RC_DONE_STATUS);
|
||||
|
||||
val = readl(regs + PCIE_PU_PLL_1);
|
||||
val &= ~SSC_DEP_SEL;
|
||||
val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_NONE);
|
||||
writel(val, regs + PCIE_PU_PLL_1);
|
||||
|
||||
val = readl(regs + PCIE_PU_PLL_2);
|
||||
val |= GEN_REF100; /* Enable 100 MHz PLL output clock */
|
||||
writel(val, regs + PCIE_PU_PLL_2);
|
||||
}
|
||||
|
||||
static int k1_pcie_phy_pll_prepare(struct clk_hw *clk_hw)
|
||||
{
|
||||
struct k1_pcie_phy *k1_phy = clk_hw_to_k1_phy(clk_hw);
|
||||
void __iomem *regs = k1_phy->regs;
|
||||
u32 val;
|
||||
u32 i;
|
||||
|
||||
if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3)
|
||||
k1_pcie_phy_pll_prepare_usb(k1_phy);
|
||||
else
|
||||
k1_pcie_phy_pll_prepare_pcie(k1_phy);
|
||||
|
||||
/*
|
||||
* Disable 100 MHz input reference with spread-spectrum
|
||||
* clocking and select the 24 MHz clock input frequency
|
||||
*/
|
||||
val = readl(regs + PCIE_PU_PLL_1);
|
||||
val &= ~REF_100_WSSC;
|
||||
val &= ~FREF_SEL;
|
||||
val |= FIELD_PREP(FREF_SEL, FREF_24M);
|
||||
writel(val, regs + PCIE_PU_PLL_1);
|
||||
|
||||
/* Mark PLL configuration done on all lanes */
|
||||
for (i = 0; i < k1_phy->pcie_lanes; i++) {
|
||||
val = readl(regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
val |= CFG_SW_PHY_INIT_DONE;
|
||||
writel(val, regs + PCIE_PU_ADDR_CLK_CFG);
|
||||
|
||||
regs += PHY_LANE_OFFSET; /* Next lane */
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for indication the PHY PLL is locked. Lanes for ports
|
||||
* B and C share a PLL, so it's enough to sample just lane 0.
|
||||
*/
|
||||
return readl_poll_timeout(k1_phy->regs + PCIE_PU_ADDR_CLK_CFG,
|
||||
val, val & PLL_READY,
|
||||
POLL_DELAY, PLL_TIMEOUT);
|
||||
}
|
||||
|
||||
/* Prepare implies enable, and once enabled, it's always on */
|
||||
static const struct clk_ops k1_pcie_phy_pll_ops = {
|
||||
.prepare = k1_pcie_phy_pll_prepare,
|
||||
};
|
||||
|
||||
/* We represent the PHY PLL as a private clock */
|
||||
static int k1_pcie_phy_pll_setup(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
struct clk_hw *hw = &k1_phy->pll_hw;
|
||||
struct device *dev = k1_phy->dev;
|
||||
struct clk_init_data init = { };
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
name = kasprintf(GFP_KERNEL, "pcie%u_phy_pll", k1_phy->phy->id);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
init.name = name;
|
||||
init.ops = &k1_pcie_phy_pll_ops;
|
||||
init.parent_data = k1_pcie_phy_data;
|
||||
init.num_parents = ARRAY_SIZE(k1_pcie_phy_data);
|
||||
|
||||
hw->init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(dev, hw);
|
||||
|
||||
kfree(name); /* __clk_register() duplicates the name we provide */
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
k1_phy->pll = devm_clk_hw_get_clk(dev, hw, "pll");
|
||||
if (IS_ERR(k1_phy->pll))
|
||||
return PTR_ERR(k1_phy->pll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Select PCIe or USB 3 mode for the combo PHY. */
|
||||
static void k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb)
|
||||
{
|
||||
struct regmap *pmu = k1_phy->pmu;
|
||||
|
||||
/* Only change it if it's not already in the desired state */
|
||||
if (!regmap_test_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL) == usb)
|
||||
regmap_assign_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL, usb);
|
||||
}
|
||||
|
||||
static void k1_pcie_phy_init_pcie(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
u32 rx_rterm = k1_phy_rterm_rx();
|
||||
u32 tx_rterm = k1_phy_rterm_tx();
|
||||
void __iomem *regs;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
/* For the combo PHY, set PHY to PCIe mode */
|
||||
if (k1_phy_port_a(k1_phy))
|
||||
k1_combo_phy_sel(k1_phy, false);
|
||||
|
||||
regs = k1_phy->regs;
|
||||
for (i = 0; i < k1_phy->pcie_lanes; i++) {
|
||||
val = readl(regs + PCIE_RX_REG1);
|
||||
|
||||
/* Set RX analog front-end receiver termination value */
|
||||
val &= ~AFE_RTERM_REG;
|
||||
val |= FIELD_PREP(AFE_RTERM_REG, rx_rterm);
|
||||
|
||||
/* And enable refclock receiver termination */
|
||||
val |= EN_RTERM;
|
||||
writel(val, regs + PCIE_RX_REG1);
|
||||
|
||||
val = readl(regs + PCIE_RX_REG2);
|
||||
/* Use PCIE_RX_REG1 AFE_RTERM_REG value */
|
||||
val &= ~RX_RTERM_SEL;
|
||||
writel(val, regs + PCIE_RX_REG2);
|
||||
|
||||
val = readl(regs + PCIE_TX_REG1);
|
||||
|
||||
/* Set TX driver termination value */
|
||||
val &= ~TX_RTERM_REG;
|
||||
val |= FIELD_PREP(TX_RTERM_REG, tx_rterm);
|
||||
|
||||
/* Use PCIE_TX_REG1 TX_RTERM_REG value */
|
||||
val |= TX_RTERM_SEL;
|
||||
writel(val, regs + PCIE_TX_REG1);
|
||||
|
||||
/* Set the input clock to 24 MHz, and clear RC_CAL_TOGGLE */
|
||||
val = readl(regs + PCIE_RC_CAL_REG2);
|
||||
val &= CLKSEL;
|
||||
val |= FIELD_PREP(CLKSEL, CLKSEL_24M);
|
||||
val &= ~RC_CAL_TOGGLE;
|
||||
writel(val, regs + PCIE_RC_CAL_REG2);
|
||||
|
||||
/* Now trigger recalibration by setting RC_CAL_TOGGLE again */
|
||||
val |= RC_CAL_TOGGLE;
|
||||
writel(val, regs + PCIE_RC_CAL_REG2);
|
||||
|
||||
val = readl(regs + PCIE_LTSSM_DIS_ENTRY);
|
||||
/* Override the reference clock; set to refclk driver mode */
|
||||
val |= OVRD_REFCLK_MODE;
|
||||
val &= ~CFG_REFCLK_MODE;
|
||||
val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER);
|
||||
writel(val, regs + PCIE_LTSSM_DIS_ENTRY);
|
||||
|
||||
regs += PHY_LANE_OFFSET; /* Next lane */
|
||||
}
|
||||
}
|
||||
|
||||
/* Only called for combo PHY */
|
||||
static void k1_pcie_phy_init_usb(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
k1_combo_phy_sel(k1_phy, true);
|
||||
|
||||
/* We're not doing any testing */
|
||||
writel(0, k1_phy->regs + USB3_TEST_CTRL);
|
||||
}
|
||||
|
||||
static int k1_pcie_phy_init(struct phy *phy)
|
||||
{
|
||||
struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy);
|
||||
|
||||
/* Note: port type is only valid for port A (both checks needed) */
|
||||
if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3)
|
||||
k1_pcie_phy_init_usb(k1_phy);
|
||||
else
|
||||
k1_pcie_phy_init_pcie(k1_phy);
|
||||
|
||||
|
||||
return clk_prepare_enable(k1_phy->pll);
|
||||
}
|
||||
|
||||
static int k1_pcie_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy);
|
||||
|
||||
clk_disable_unprepare(k1_phy->pll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops k1_pcie_phy_ops = {
|
||||
.init = k1_pcie_phy_init,
|
||||
.exit = k1_pcie_phy_exit,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Get values needed for calibrating PHYs operating in PCIe mode. Only
|
||||
* the combo PHY is able to do this, and its calibration values are used
|
||||
* for configuring all PCIe PHYs.
|
||||
*
|
||||
* We always need to de-assert the "global" reset on the combo PHY,
|
||||
* because the USB driver depends on it. If used for PCIe, that driver
|
||||
* will (also) de-assert this, but by leaving it de-asserted for the
|
||||
* combo PHY, the USB driver doesn't have to do this. Note: although
|
||||
* SpacemiT refers to this as the global reset, we name the "phy" reset.
|
||||
*
|
||||
* In addition, we guarantee the APP_HOLD_PHY_RESET bit is clear for the
|
||||
* combo PHY, so the USB driver doesn't have to manage that either. The
|
||||
* PCIe driver is free to change this bit for normal operation.
|
||||
*
|
||||
* Calibration only needs to be done once. It's possible calibration has
|
||||
* already completed (e.g., it might have happened in the boot loader, or
|
||||
* -EPROBE_DEFER might result in this function being called again). So we
|
||||
* check that early too, to avoid doing it more than once.
|
||||
*
|
||||
* Otherwise we temporarily power up the PHY using the PCIe app clocks
|
||||
* and resets, wait for the hardware to indicate calibration is done,
|
||||
* grab the value, then shut the PHY down again.
|
||||
*/
|
||||
static int k1_pcie_combo_phy_calibrate(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
struct reset_control_bulk_data resets[] = {
|
||||
{ .id = "dbi", },
|
||||
{ .id = "mstr", },
|
||||
{ .id = "slv", },
|
||||
};
|
||||
struct clk_bulk_data clocks[] = {
|
||||
{ .id = "dbi", },
|
||||
{ .id = "mstr", },
|
||||
{ .id = "slv", },
|
||||
};
|
||||
struct device *dev = k1_phy->dev;
|
||||
int ret = 0;
|
||||
int val;
|
||||
|
||||
/* Nothing to do if we already set the receiver termination value */
|
||||
if (k1_phy_rterm_valid())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We also guarantee the APP_HOLD_PHY_RESET bit is clear. We can
|
||||
* leave this bit clear even if an error happens below.
|
||||
*/
|
||||
regmap_assign_bits(k1_phy->pmu, PCIE_CLK_RES_CTRL,
|
||||
PCIE_APP_HOLD_PHY_RST, false);
|
||||
|
||||
/* If the calibration already completed (e.g. by U-Boot), we're done */
|
||||
val = readl(k1_phy->regs + PCIE_RCAL_RESULT);
|
||||
if (val & R_TUNE_DONE)
|
||||
goto out_tune_done;
|
||||
|
||||
/* Put the PHY into PCIe mode */
|
||||
k1_combo_phy_sel(k1_phy, false);
|
||||
|
||||
/* Get and enable the PCIe app clocks */
|
||||
ret = clk_bulk_get(dev, ARRAY_SIZE(clocks), clocks);
|
||||
if (ret < 0)
|
||||
goto out_tune_done;
|
||||
ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks);
|
||||
if (ret)
|
||||
goto out_put_clocks;
|
||||
|
||||
/* Get the PCIe application resets (not the PHY reset) */
|
||||
ret = reset_control_bulk_get_shared(dev, ARRAY_SIZE(resets), resets);
|
||||
if (ret)
|
||||
goto out_disable_clocks;
|
||||
|
||||
/* De-assert the PCIe application resets */
|
||||
ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets);
|
||||
if (ret)
|
||||
goto out_put_resets;
|
||||
|
||||
/*
|
||||
* This is the core activity here. Wait for the hardware to
|
||||
* signal that it has completed calibration/tuning. Once it
|
||||
* has, the register value will contain the values we'll
|
||||
* use to configure PCIe PHYs.
|
||||
*/
|
||||
ret = readl_poll_timeout(k1_phy->regs + PCIE_RCAL_RESULT,
|
||||
val, val & R_TUNE_DONE,
|
||||
POLL_DELAY, CALIBRATION_TIMEOUT);
|
||||
|
||||
/* Clean up. We're done with the resets and clocks */
|
||||
reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
|
||||
out_put_resets:
|
||||
reset_control_bulk_put(ARRAY_SIZE(resets), resets);
|
||||
out_disable_clocks:
|
||||
clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks);
|
||||
out_put_clocks:
|
||||
clk_bulk_put(ARRAY_SIZE(clocks), clocks);
|
||||
out_tune_done:
|
||||
/* If we got the value without timing out, set k1_phy_rterm */
|
||||
if (!ret)
|
||||
k1_phy_rterm_set(val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct phy *
|
||||
k1_pcie_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
|
||||
{
|
||||
struct k1_pcie_phy *k1_phy = dev_get_drvdata(dev);
|
||||
u32 type;
|
||||
|
||||
/* The argument specifying the PHY mode is required */
|
||||
if (args->args_count != 1)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* We only support PCIe and USB 3 mode */
|
||||
type = args->args[0];
|
||||
if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* This PHY can only be used once */
|
||||
if (k1_phy->type != PHY_NONE)
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
k1_phy->type = type;
|
||||
|
||||
return k1_phy->phy;
|
||||
}
|
||||
|
||||
/* Use the maximum number of PCIe lanes unless limited by device tree */
|
||||
static u32 k1_pcie_num_lanes(struct k1_pcie_phy *k1_phy, bool port_a)
|
||||
{
|
||||
struct device *dev = k1_phy->dev;
|
||||
u32 count = 0;
|
||||
u32 max;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &count);
|
||||
if (count == 1)
|
||||
return 1;
|
||||
|
||||
if (count == 2 && !port_a)
|
||||
return 2;
|
||||
|
||||
max = port_a ? 1 : 2;
|
||||
if (ret != -EINVAL)
|
||||
dev_warn(dev, "bad lane count %u for port; using %u\n",
|
||||
count, max);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static int k1_pcie_combo_phy_probe(struct k1_pcie_phy *k1_phy)
|
||||
{
|
||||
struct device *dev = k1_phy->dev;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
/* Setting the PHY mode requires access to the PMU regmap */
|
||||
regmap = syscon_regmap_lookup_by_phandle(dev_of_node(dev), SYSCON_APMU);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap), "failed to get PMU\n");
|
||||
k1_phy->pmu = regmap;
|
||||
|
||||
ret = k1_pcie_combo_phy_calibrate(k1_phy);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "calibration failed\n");
|
||||
|
||||
/* Needed by k1_pcie_combo_phy_xlate(), which also sets k1_phy->type */
|
||||
dev_set_drvdata(dev, k1_phy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int k1_pcie_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy *(*xlate)(struct device *dev,
|
||||
const struct of_phandle_args *args);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct reset_control *phy_reset;
|
||||
struct phy_provider *provider;
|
||||
struct k1_pcie_phy *k1_phy;
|
||||
bool probing_port_a;
|
||||
int ret;
|
||||
|
||||
xlate = of_device_get_match_data(dev);
|
||||
probing_port_a = xlate == k1_pcie_combo_phy_xlate;
|
||||
|
||||
/* Only the combo PHY can calibrate, so it must probe first */
|
||||
if (!k1_phy_rterm_valid() && !probing_port_a)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
k1_phy = devm_kzalloc(dev, sizeof(*k1_phy), GFP_KERNEL);
|
||||
if (!k1_phy)
|
||||
return -ENOMEM;
|
||||
k1_phy->dev = dev;
|
||||
|
||||
k1_phy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(k1_phy->regs))
|
||||
return dev_err_probe(dev, PTR_ERR(k1_phy->regs),
|
||||
"error mapping registers\n");
|
||||
|
||||
/* De-assert the PHY (global) reset and leave it that way */
|
||||
phy_reset = devm_reset_control_get_exclusive_deasserted(dev, "phy");
|
||||
if (IS_ERR(phy_reset))
|
||||
return PTR_ERR(phy_reset);
|
||||
|
||||
if (probing_port_a) {
|
||||
ret = k1_pcie_combo_phy_probe(k1_phy);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"error probing combo phy\n");
|
||||
}
|
||||
|
||||
k1_phy->pcie_lanes = k1_pcie_num_lanes(k1_phy, probing_port_a);
|
||||
|
||||
k1_phy->phy = devm_phy_create(dev, NULL, &k1_pcie_phy_ops);
|
||||
if (IS_ERR(k1_phy->phy))
|
||||
return dev_err_probe(dev, PTR_ERR(k1_phy->phy),
|
||||
"error creating phy\n");
|
||||
phy_set_drvdata(k1_phy->phy, k1_phy);
|
||||
|
||||
ret = k1_pcie_phy_pll_setup(k1_phy);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "error initializing clock\n");
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, xlate);
|
||||
if (IS_ERR(provider))
|
||||
return dev_err_probe(dev, PTR_ERR(provider),
|
||||
"error registering provider\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id k1_pcie_phy_of_match[] = {
|
||||
{ .compatible = "spacemit,k1-combo-phy", k1_pcie_combo_phy_xlate, },
|
||||
{ .compatible = "spacemit,k1-pcie-phy", of_phy_simple_xlate, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, k1_pcie_phy_of_match);
|
||||
|
||||
static struct platform_driver k1_pcie_phy_driver = {
|
||||
.probe = k1_pcie_phy_probe,
|
||||
.driver = {
|
||||
.of_match_table = k1_pcie_phy_of_match,
|
||||
.name = "spacemit-k1-pcie-phy",
|
||||
}
|
||||
};
|
||||
module_platform_driver(k1_pcie_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("SpacemiT K1 PCIe and USB 3 PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -26,13 +26,15 @@
|
||||
#include "phy-qcom-qmp-qserdes-com-v4.h"
|
||||
#include "phy-qcom-qmp-qserdes-com-v6.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-dp-com-v8.h"
|
||||
|
||||
/* EDP_PHY registers */
|
||||
#define DP_PHY_CFG 0x0010
|
||||
#define DP_PHY_CFG_1 0x0014
|
||||
#define DP_PHY_PD_CTL 0x001c
|
||||
#define DP_PHY_MODE 0x0020
|
||||
|
||||
#define DP_AUX_CFG_SIZE 10
|
||||
#define DP_AUX_CFG_SIZE 13
|
||||
#define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n)))
|
||||
|
||||
#define DP_PHY_AUX_INTERRUPT_MASK 0x0058
|
||||
@@ -76,6 +78,7 @@ struct phy_ver_ops {
|
||||
int (*com_power_on)(const struct qcom_edp *edp);
|
||||
int (*com_resetsm_cntrl)(const struct qcom_edp *edp);
|
||||
int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp);
|
||||
int (*com_clk_fwd_cfg)(const struct qcom_edp *edp);
|
||||
int (*com_configure_pll)(const struct qcom_edp *edp);
|
||||
int (*com_configure_ssc)(const struct qcom_edp *edp);
|
||||
};
|
||||
@@ -83,6 +86,7 @@ struct phy_ver_ops {
|
||||
struct qcom_edp_phy_cfg {
|
||||
bool is_edp;
|
||||
const u8 *aux_cfg;
|
||||
const u8 *vco_div_cfg;
|
||||
const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
|
||||
const struct phy_ver_ops *ver_ops;
|
||||
};
|
||||
@@ -103,7 +107,9 @@ struct qcom_edp {
|
||||
|
||||
struct phy_configure_opts_dp dp_opts;
|
||||
|
||||
struct clk_bulk_data clks[2];
|
||||
struct clk_bulk_data *clks;
|
||||
int num_clks;
|
||||
|
||||
struct regulator_bulk_data supplies[2];
|
||||
|
||||
bool is_edp;
|
||||
@@ -179,8 +185,12 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
|
||||
.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
|
||||
};
|
||||
|
||||
static const u8 edp_phy_aux_cfg_v4[10] = {
|
||||
0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
|
||||
static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = {
|
||||
0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
|
||||
};
|
||||
|
||||
static const u8 edp_phy_vco_div_cfg_v4[4] = {
|
||||
0x01, 0x01, 0x02, 0x00,
|
||||
};
|
||||
|
||||
static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
|
||||
@@ -204,8 +214,16 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 =
|
||||
.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
|
||||
};
|
||||
|
||||
static const u8 edp_phy_aux_cfg_v5[10] = {
|
||||
0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03
|
||||
static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = {
|
||||
0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
|
||||
};
|
||||
|
||||
static const u8 edp_phy_aux_cfg_v8[DP_AUX_CFG_SIZE] = {
|
||||
0x00, 0x00, 0xa0, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x04,
|
||||
};
|
||||
|
||||
static const u8 edp_phy_vco_div_cfg_v8[4] = {
|
||||
0x00, 0x00, 0x02, 0x01,
|
||||
};
|
||||
|
||||
static int qcom_edp_phy_init(struct phy *phy)
|
||||
@@ -218,12 +236,16 @@ static int qcom_edp_phy_init(struct phy *phy)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
|
||||
ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks);
|
||||
if (ret)
|
||||
goto out_disable_supplies;
|
||||
|
||||
memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg));
|
||||
|
||||
ret = edp->cfg->ver_ops->com_clk_fwd_cfg(edp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
|
||||
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
|
||||
edp->edp + DP_PHY_PD_CTL);
|
||||
@@ -343,22 +365,22 @@ static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel
|
||||
|
||||
switch (dp_opts->link_rate) {
|
||||
case 1620:
|
||||
vco_div = 0x1;
|
||||
vco_div = edp->cfg->vco_div_cfg[0];
|
||||
*pixel_freq = 1620000000UL / 2;
|
||||
break;
|
||||
|
||||
case 2700:
|
||||
vco_div = 0x1;
|
||||
vco_div = edp->cfg->vco_div_cfg[1];
|
||||
*pixel_freq = 2700000000UL / 2;
|
||||
break;
|
||||
|
||||
case 5400:
|
||||
vco_div = 0x2;
|
||||
vco_div = edp->cfg->vco_div_cfg[2];
|
||||
*pixel_freq = 5400000000UL / 4;
|
||||
break;
|
||||
|
||||
case 8100:
|
||||
vco_div = 0x0;
|
||||
vco_div = edp->cfg->vco_div_cfg[3];
|
||||
*pixel_freq = 8100000000UL / 6;
|
||||
break;
|
||||
|
||||
@@ -396,6 +418,11 @@ static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp)
|
||||
val, val & BIT(0), 500, 10000);
|
||||
}
|
||||
|
||||
static int qcom_edp_com_clk_fwd_cfg_v4(const struct qcom_edp *edp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp)
|
||||
{
|
||||
/* Turn on BIAS current for PHY/PLL */
|
||||
@@ -528,6 +555,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
|
||||
.com_power_on = qcom_edp_phy_power_on_v4,
|
||||
.com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4,
|
||||
.com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4,
|
||||
.com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
|
||||
.com_configure_pll = qcom_edp_com_configure_pll_v4,
|
||||
.com_configure_ssc = qcom_edp_com_configure_ssc_v4,
|
||||
};
|
||||
@@ -535,17 +563,20 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
|
||||
static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
|
||||
.is_edp = false,
|
||||
.aux_cfg = edp_phy_aux_cfg_v5,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
|
||||
.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
|
||||
.ver_ops = &qcom_edp_phy_ops_v4,
|
||||
};
|
||||
|
||||
static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
|
||||
.aux_cfg = edp_phy_aux_cfg_v4,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
|
||||
.ver_ops = &qcom_edp_phy_ops_v4,
|
||||
};
|
||||
|
||||
static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
|
||||
.aux_cfg = edp_phy_aux_cfg_v4,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
|
||||
.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
|
||||
.ver_ops = &qcom_edp_phy_ops_v4,
|
||||
};
|
||||
@@ -553,6 +584,7 @@ static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
|
||||
static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
|
||||
.is_edp = true,
|
||||
.aux_cfg = edp_phy_aux_cfg_v4,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
|
||||
.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
|
||||
.ver_ops = &qcom_edp_phy_ops_v4,
|
||||
};
|
||||
@@ -726,16 +758,197 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
|
||||
.com_power_on = qcom_edp_phy_power_on_v6,
|
||||
.com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6,
|
||||
.com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6,
|
||||
.com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
|
||||
.com_configure_pll = qcom_edp_com_configure_pll_v6,
|
||||
.com_configure_ssc = qcom_edp_com_configure_ssc_v6,
|
||||
};
|
||||
|
||||
static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
|
||||
.aux_cfg = edp_phy_aux_cfg_v4,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
|
||||
.swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
|
||||
.ver_ops = &qcom_edp_phy_ops_v6,
|
||||
};
|
||||
|
||||
static int qcom_edp_com_configure_ssc_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
|
||||
u32 step1;
|
||||
u32 step2;
|
||||
|
||||
switch (dp_opts->link_rate) {
|
||||
case 1620:
|
||||
case 2700:
|
||||
case 8100:
|
||||
step1 = 0x5b;
|
||||
step2 = 0x02;
|
||||
break;
|
||||
|
||||
case 5400:
|
||||
step1 = 0x5b;
|
||||
step2 = 0x02;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other link rates aren't supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(0x01, edp->pll + DP_QSERDES_V8_COM_SSC_EN_CENTER);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_SSC_ADJ_PER1);
|
||||
writel(0x6b, edp->pll + DP_QSERDES_V8_COM_SSC_PER1);
|
||||
writel(0x02, edp->pll + DP_QSERDES_V8_COM_SSC_PER2);
|
||||
writel(step1, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0);
|
||||
writel(step2, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_edp_com_configure_pll_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
|
||||
u32 div_frac_start2_mode0;
|
||||
u32 div_frac_start3_mode0;
|
||||
u32 dec_start_mode0;
|
||||
u32 lock_cmp1_mode0;
|
||||
u32 lock_cmp2_mode0;
|
||||
u32 code1_mode0;
|
||||
u32 code2_mode0;
|
||||
u32 hsclk_sel;
|
||||
|
||||
switch (dp_opts->link_rate) {
|
||||
case 1620:
|
||||
hsclk_sel = 0x5;
|
||||
dec_start_mode0 = 0x34;
|
||||
div_frac_start2_mode0 = 0xc0;
|
||||
div_frac_start3_mode0 = 0x0b;
|
||||
lock_cmp1_mode0 = 0x37;
|
||||
lock_cmp2_mode0 = 0x04;
|
||||
code1_mode0 = 0x71;
|
||||
code2_mode0 = 0x0c;
|
||||
break;
|
||||
|
||||
case 2700:
|
||||
hsclk_sel = 0x3;
|
||||
dec_start_mode0 = 0x34;
|
||||
div_frac_start2_mode0 = 0xc0;
|
||||
div_frac_start3_mode0 = 0x0b;
|
||||
lock_cmp1_mode0 = 0x07;
|
||||
lock_cmp2_mode0 = 0x07;
|
||||
code1_mode0 = 0x71;
|
||||
code2_mode0 = 0x0c;
|
||||
break;
|
||||
|
||||
case 5400:
|
||||
case 8100:
|
||||
hsclk_sel = 0x2;
|
||||
dec_start_mode0 = 0x4f;
|
||||
div_frac_start2_mode0 = 0xa0;
|
||||
div_frac_start3_mode0 = 0x01;
|
||||
lock_cmp1_mode0 = 0x18;
|
||||
lock_cmp2_mode0 = 0x15;
|
||||
code1_mode0 = 0x14;
|
||||
code2_mode0 = 0x25;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other link rates aren't supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(0x01, edp->pll + DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL);
|
||||
writel(0x3b, edp->pll + DP_QSERDES_V8_COM_SYSCLK_EN_SEL);
|
||||
writel(0x02, edp->pll + DP_QSERDES_V8_COM_SYS_CLK_CTRL);
|
||||
writel(0x0c, edp->pll + DP_QSERDES_V8_COM_CLK_ENABLE1);
|
||||
writel(0x06, edp->pll + DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE);
|
||||
writel(0x30, edp->pll + DP_QSERDES_V8_COM_CLK_SELECT);
|
||||
writel(hsclk_sel, edp->pll + DP_QSERDES_V8_COM_HSCLK_SEL_1);
|
||||
writel(0x07, edp->pll + DP_QSERDES_V8_COM_PLL_IVCO);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP_EN);
|
||||
writel(0x36, edp->pll + DP_QSERDES_V8_COM_PLL_CCTRL_MODE0);
|
||||
writel(0x16, edp->pll + DP_QSERDES_V8_COM_PLL_RCTRL_MODE0);
|
||||
writel(0x06, edp->pll + DP_QSERDES_V8_COM_CP_CTRL_MODE0);
|
||||
writel(dec_start_mode0, edp->pll + DP_QSERDES_V8_COM_DEC_START_MODE0);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0);
|
||||
writel(div_frac_start2_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0);
|
||||
writel(div_frac_start3_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0);
|
||||
writel(0x96, edp->pll + DP_QSERDES_V8_COM_CMN_CONFIG_1);
|
||||
writel(0x3f, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_MAP);
|
||||
writel(lock_cmp1_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP1_MODE0);
|
||||
writel(lock_cmp2_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP2_MODE0);
|
||||
|
||||
writel(0x0a, edp->pll + DP_QSERDES_V8_COM_BG_TIMER);
|
||||
writel(0x0a, edp->pll + DP_QSERDES_V8_COM_CORECLK_DIV_MODE0);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_CTRL);
|
||||
writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN);
|
||||
writel(0x00, edp->pll + DP_QSERDES_V8_COM_CORE_CLK_EN);
|
||||
writel(0xa0, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE1_MODE0);
|
||||
writel(0x01, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE2_MODE0);
|
||||
|
||||
writel(code1_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0);
|
||||
writel(code2_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int qcom_edp_phy_com_resetsm_cntrl_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
writel(0x20, edp->pll + DP_QSERDES_V8_COM_RESETSM_CNTRL);
|
||||
|
||||
return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_C_READY_STATUS,
|
||||
val, val & BIT(0), 500, 10000);
|
||||
}
|
||||
|
||||
static int qcom_edp_com_clk_fwd_cfg_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
writel(0x3f, edp->pll + DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_edp_com_bias_en_clkbuflr_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
/* Turn on BIAS current for PHY/PLL */
|
||||
writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_edp_phy_power_on_v8(const struct qcom_edp *edp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
|
||||
DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
|
||||
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
|
||||
edp->edp + DP_PHY_PD_CTL);
|
||||
writel(0xfc, edp->edp + DP_PHY_MODE);
|
||||
|
||||
return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_CMN_STATUS,
|
||||
val, val & BIT(7), 5, 200);
|
||||
}
|
||||
|
||||
static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
|
||||
.com_power_on = qcom_edp_phy_power_on_v8,
|
||||
.com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v8,
|
||||
.com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v8,
|
||||
.com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v8,
|
||||
.com_configure_pll = qcom_edp_com_configure_pll_v8,
|
||||
.com_configure_ssc = qcom_edp_com_configure_ssc_v8,
|
||||
};
|
||||
|
||||
static struct qcom_edp_phy_cfg glymur_phy_cfg = {
|
||||
.aux_cfg = edp_phy_aux_cfg_v8,
|
||||
.vco_div_cfg = edp_phy_vco_div_cfg_v8,
|
||||
.swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
|
||||
.ver_ops = &qcom_edp_phy_ops_v8,
|
||||
};
|
||||
|
||||
static int qcom_edp_phy_power_on(struct phy *phy)
|
||||
{
|
||||
const struct qcom_edp *edp = phy_get_drvdata(phy);
|
||||
@@ -885,7 +1098,7 @@ static int qcom_edp_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct qcom_edp *edp = phy_get_drvdata(phy);
|
||||
|
||||
clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
|
||||
clk_bulk_disable_unprepare(edp->num_clks, edp->clks);
|
||||
regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
|
||||
|
||||
return 0;
|
||||
@@ -1092,11 +1305,9 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(edp->pll))
|
||||
return PTR_ERR(edp->pll);
|
||||
|
||||
edp->clks[0].id = "aux";
|
||||
edp->clks[1].id = "cfg_ahb";
|
||||
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks);
|
||||
if (edp->num_clks < 0)
|
||||
return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n");
|
||||
|
||||
edp->supplies[0].supply = "vdda-phy";
|
||||
edp->supplies[1].supply = "vdda-pll";
|
||||
@@ -1133,6 +1344,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_edp_phy_match_table[] = {
|
||||
{ .compatible = "qcom,glymur-dp-phy", .data = &glymur_phy_cfg, },
|
||||
{ .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, },
|
||||
{ .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, },
|
||||
{ .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, },
|
||||
|
||||
@@ -37,6 +37,17 @@
|
||||
#define EUSB2_TUNE_EUSB_EQU 0x5A
|
||||
#define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B
|
||||
|
||||
static const int squelch_detector[] = {
|
||||
[0] = -6000,
|
||||
[1] = -5000,
|
||||
[2] = -4000,
|
||||
[3] = -3000,
|
||||
[4] = -2000,
|
||||
[5] = -1000,
|
||||
[6] = 0,
|
||||
[7] = 1000,
|
||||
};
|
||||
|
||||
struct eusb2_repeater_init_tbl_reg {
|
||||
unsigned int reg;
|
||||
unsigned int value;
|
||||
@@ -75,6 +86,13 @@ static const struct eusb2_repeater_init_tbl_reg smb2360_init_tbl[] = {
|
||||
{ EUSB2_TUNE_USB2_PREEM, 0x2 },
|
||||
};
|
||||
|
||||
static const struct eusb2_repeater_init_tbl_reg smb2370_init_tbl[] = {
|
||||
{ EUSB2_TUNE_IUSB2, 0x4 },
|
||||
{ EUSB2_TUNE_SQUELCH_U, 0x3 },
|
||||
{ EUSB2_TUNE_USB2_SLEW, 0x7 },
|
||||
{ EUSB2_TUNE_USB2_PREEM, 0x0 },
|
||||
};
|
||||
|
||||
static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = {
|
||||
.init_tbl = pm8550b_init_tbl,
|
||||
.init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl),
|
||||
@@ -97,6 +115,13 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
|
||||
.num_vregs = ARRAY_SIZE(pm8550b_vreg_l),
|
||||
};
|
||||
|
||||
static const struct eusb2_repeater_cfg smb2370_eusb2_cfg = {
|
||||
.init_tbl = smb2370_init_tbl,
|
||||
.init_tbl_num = ARRAY_SIZE(smb2370_init_tbl),
|
||||
.vreg_list = pm8550b_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(pm8550b_vreg_l),
|
||||
};
|
||||
|
||||
static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
|
||||
{
|
||||
int num = rptr->cfg->num_vregs;
|
||||
@@ -120,7 +145,9 @@ static int eusb2_repeater_init(struct phy *phy)
|
||||
struct regmap *regmap = rptr->regmap;
|
||||
u32 base = rptr->base;
|
||||
u32 poll_val;
|
||||
s32 dt_val;
|
||||
int ret;
|
||||
int i;
|
||||
u8 val;
|
||||
|
||||
ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs);
|
||||
@@ -147,6 +174,15 @@ static int eusb2_repeater_init(struct phy *phy)
|
||||
if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val))
|
||||
regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val);
|
||||
|
||||
if (!of_property_read_s32(np, "qcom,squelch-detector-bp", &dt_val)) {
|
||||
for (i = 0; i < ARRAY_SIZE(squelch_detector); i++) {
|
||||
if (squelch_detector[i] == dt_val) {
|
||||
regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for status OK */
|
||||
ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val,
|
||||
poll_val & RPTR_OK, 10, 5);
|
||||
@@ -278,6 +314,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = {
|
||||
.compatible = "qcom,smb2360-eusb2-repeater",
|
||||
.data = &smb2360_eusb2_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,smb2370-eusb2-repeater",
|
||||
.data = &smb2370_eusb2_cfg,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table);
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
#include "phy-qcom-qmp-common.h"
|
||||
|
||||
#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-misc-v3.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v4.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v5.h"
|
||||
#include "phy-qcom-qmp-pcs-misc-v8.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v4.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v5.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v6.h"
|
||||
@@ -43,6 +48,9 @@
|
||||
#include "phy-qcom-qmp-dp-phy-v4.h"
|
||||
#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-usb43-pcs-v8.h"
|
||||
|
||||
/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
|
||||
/* DP PHY soft reset */
|
||||
@@ -61,6 +69,7 @@
|
||||
/* QPHY_V3_DP_COM_TYPEC_CTRL register bits */
|
||||
#define SW_PORTSELECT_VAL BIT(0)
|
||||
#define SW_PORTSELECT_MUX BIT(1)
|
||||
#define INVERT_CC_POLARITY BIT(2)
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
||||
|
||||
@@ -79,6 +88,7 @@ enum qphy_reg_layout {
|
||||
QPHY_PCS_AUTONOMOUS_MODE_CTRL,
|
||||
QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
|
||||
QPHY_PCS_POWER_DOWN_CONTROL,
|
||||
QPHY_PCS_CLAMP_ENABLE,
|
||||
|
||||
QPHY_COM_RESETSM_CNTRL,
|
||||
QPHY_COM_C_READY_STATUS,
|
||||
@@ -94,6 +104,8 @@ enum qphy_reg_layout {
|
||||
QPHY_TX_HIGHZ_DRVR_EN,
|
||||
QPHY_TX_TRANSCEIVER_BIAS_EN,
|
||||
|
||||
QPHY_AON_TOGGLE_ENABLE,
|
||||
QPHY_DP_AON_TOGGLE_ENABLE,
|
||||
/* Keep last to ensure regs_layout arrays are properly initialized */
|
||||
QPHY_LAYOUT_SIZE
|
||||
};
|
||||
@@ -106,6 +118,8 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V3_PCS_MISC_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V3_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V3_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V3_COM_CMN_STATUS,
|
||||
@@ -131,6 +145,8 @@ static const unsigned int qmp_v45_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V4_PCS_MISC_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V4_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V4_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V4_COM_CMN_STATUS,
|
||||
@@ -156,6 +172,8 @@ static const unsigned int qmp_v5_5nm_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V5_PCS_MISC_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V5_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V5_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V5_COM_CMN_STATUS,
|
||||
@@ -181,6 +199,8 @@ static const unsigned int qmp_v6_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS,
|
||||
@@ -206,6 +226,8 @@ static const unsigned int qmp_v6_n4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS,
|
||||
@@ -246,6 +268,237 @@ 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_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,
|
||||
[QPHY_PCS_STATUS] = QPHY_V8_USB43_PCS_PCS_STATUS1,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL,
|
||||
|
||||
/* In PCS_USB */
|
||||
[QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V8_PCS_USB_AUTONOMOUS_MODE_CTRL,
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V8_PCS_USB_LFPS_RXTERM_IRQ_CLEAR,
|
||||
|
||||
[QPHY_PCS_CLAMP_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE,
|
||||
[QPHY_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE,
|
||||
[QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE,
|
||||
|
||||
[QPHY_COM_RESETSM_CNTRL] = QSERDES_V8_COM_RESETSM_CNTRL,
|
||||
[QPHY_COM_C_READY_STATUS] = QSERDES_V8_COM_C_READY_STATUS,
|
||||
[QPHY_COM_CMN_STATUS] = QSERDES_V8_COM_CMN_STATUS,
|
||||
[QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN,
|
||||
|
||||
[QPHY_DP_PHY_STATUS] = QSERDES_V8_DP_PHY_STATUS,
|
||||
[QPHY_DP_PHY_VCO_DIV] = QSERDES_V8_DP_PHY_VCO_DIV,
|
||||
|
||||
[QPHY_TX_TX_DRV_LVL] = QSERDES_V8_LALB_TX0_DRV_LVL,
|
||||
[QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_LALB_TX0_EMP_POST1_LVL,
|
||||
[QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_LALB_HIGHZ_DRVR_EN,
|
||||
[QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_LALB_TRANSMITTER_EN_CTRL,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb43dp_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1, 0xe1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1, 0x4d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x95),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0xe1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0x4d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO_MODE1, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_CFG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x76),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x33),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xaf),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1, 0x01),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1, 0xc4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2, 0x89),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3, 0x20),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1, 0x21),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_SIGDET_LVL, 0x55),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME, 0xa4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_CONFIG, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_DLY_TIME, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2, 0x30),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG1, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG5, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb43dp_lalb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x81),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4, 0x8D),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_4, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0, 0xa4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1, 0xa2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2, 0x6e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3, 0x51),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5, 0x26),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7, 0x2a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B0, 0x4c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B1, 0xc4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B2, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B3, 0x64),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B4, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B5, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B6, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B7, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1, 0x26),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1, 0x26),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2, 0x26),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2, 0x26),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_0_1, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_2_3, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2, 0x22),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3, 0x22),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2, 0x85),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3, 0x45),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_ENABLES, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CNTRL, 0xa3),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_LVL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_TRIM, 0x66),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2, 0x32),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01, 0x76),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23, 0x67),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1, 0x33),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3, 0x43),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3, 0x51),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123, 0xe5),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123, 0xf5),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL, 0xd0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_EN, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE0_1, 0x88),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE2_3, 0x88),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_AUX_CLK_CTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_EOM_CTRL1, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2, 0x77),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_CNTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1, 0xdd),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3, 0xd8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123, 0x1C),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DIG_BKUP_CTRL16, 0x37),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
|
||||
@@ -1132,6 +1385,38 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x56),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x01),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
|
||||
@@ -1159,6 +1444,33 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_n3p_dp_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VMODE_CTRL1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT1, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x50),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRAN_DRVR_EMP_EN, 0x5f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_EMP_POST1_LVL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_EMP_POST1_LVL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_PRE1_EMPH, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_PRE1_EMPH, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_DRV_LVL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_DRV_LVL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_HIGHZ_DRVR_EN, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x50),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x51),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET, 0x10),
|
||||
};
|
||||
|
||||
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),
|
||||
@@ -1275,6 +1587,109 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr3[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_rbr[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x7a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x83),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x37),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xfe),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa4),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x21),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa3),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr2[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xf6),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr3[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x63),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x5b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x4f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x6b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0x84),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
|
||||
@@ -1649,6 +2064,12 @@ static struct regulator_bulk_data qmp_phy_vreg_l[] = {
|
||||
{ .supply = "vdda-pll", .init_load_uA = 36000, },
|
||||
};
|
||||
|
||||
static struct regulator_bulk_data qmp_phy_vreg_refgen[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 21800 },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 36000 },
|
||||
{ .supply = "refgen", .init_load_uA = 3270 },
|
||||
};
|
||||
|
||||
static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
|
||||
{ 0x00, 0x0c, 0x15, 0x1a },
|
||||
{ 0x02, 0x0e, 0x16, 0xff },
|
||||
@@ -1771,6 +2192,7 @@ struct qmp_combo_offsets {
|
||||
u16 usb3_serdes;
|
||||
u16 usb3_pcs_misc;
|
||||
u16 usb3_pcs;
|
||||
u16 usb3_pcs_aon;
|
||||
u16 usb3_pcs_usb;
|
||||
u16 dp_serdes;
|
||||
u16 dp_txa;
|
||||
@@ -1792,6 +2214,8 @@ struct qmp_phy_cfg {
|
||||
int pcs_tbl_num;
|
||||
const struct qmp_phy_init_tbl *pcs_usb_tbl;
|
||||
int pcs_usb_tbl_num;
|
||||
const struct qmp_phy_init_tbl *pcs_misc_tbl;
|
||||
int pcs_misc_tbl_num;
|
||||
|
||||
const struct qmp_phy_init_tbl *dp_serdes_tbl;
|
||||
int dp_serdes_tbl_num;
|
||||
@@ -1815,6 +2239,7 @@ struct qmp_phy_cfg {
|
||||
const u8 (*pre_emphasis_hbr3_hbr2)[4][4];
|
||||
|
||||
/* DP PHY callbacks */
|
||||
int (*configure_dp_clocks)(struct qmp_combo *qmp);
|
||||
int (*configure_dp_phy)(struct qmp_combo *qmp);
|
||||
void (*configure_dp_tx)(struct qmp_combo *qmp);
|
||||
int (*calibrate_dp_phy)(struct qmp_combo *qmp);
|
||||
@@ -1836,6 +2261,7 @@ struct qmp_phy_cfg {
|
||||
/* Offset from PCS to PCS_USB region */
|
||||
unsigned int pcs_usb_offset;
|
||||
|
||||
bool invert_cc_polarity;
|
||||
};
|
||||
|
||||
struct qmp_combo {
|
||||
@@ -1852,6 +2278,7 @@ struct qmp_combo {
|
||||
void __iomem *tx2;
|
||||
void __iomem *rx2;
|
||||
void __iomem *pcs_misc;
|
||||
void __iomem *pcs_aon;
|
||||
void __iomem *pcs_usb;
|
||||
|
||||
void __iomem *dp_serdes;
|
||||
@@ -1891,6 +2318,7 @@ struct qmp_combo {
|
||||
|
||||
static void qmp_v3_dp_aux_init(struct qmp_combo *qmp);
|
||||
static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp);
|
||||
static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp);
|
||||
static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp);
|
||||
static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp);
|
||||
|
||||
@@ -1899,6 +2327,10 @@ 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);
|
||||
static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp);
|
||||
|
||||
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
|
||||
{
|
||||
u32 reg;
|
||||
@@ -1976,6 +2408,7 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = {
|
||||
.usb3_serdes = 0x1000,
|
||||
.usb3_pcs_misc = 0x1c00,
|
||||
.usb3_pcs = 0x1e00,
|
||||
.usb3_pcs_aon = 0x2000,
|
||||
.usb3_pcs_usb = 0x2100,
|
||||
.dp_serdes = 0x3000,
|
||||
.dp_txa = 0x3400,
|
||||
@@ -1983,6 +2416,19 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = {
|
||||
.dp_dp_phy = 0x3c00,
|
||||
};
|
||||
|
||||
static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = {
|
||||
.com = 0x0000,
|
||||
.usb3_pcs_aon = 0x0100,
|
||||
.usb3_serdes = 0x1000,
|
||||
.usb3_pcs_misc = 0x1400,
|
||||
.usb3_pcs = 0x1600,
|
||||
.usb3_pcs_usb = 0x1900,
|
||||
.dp_serdes = 0x2000,
|
||||
.dp_dp_phy = 0x2400,
|
||||
.txa = 0x4000,
|
||||
.txb = 0x5000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_offsets_v3,
|
||||
|
||||
@@ -2018,6 +2464,7 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2026,6 +2473,7 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = {
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
.invert_cc_polarity = true,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = {
|
||||
@@ -2153,6 +2601,7 @@ static const struct qmp_phy_cfg sc8180x_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2199,6 +2648,7 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2244,6 +2694,7 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2332,6 +2783,7 @@ static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2380,6 +2832,7 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2427,6 +2880,7 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2472,6 +2926,7 @@ static const struct qmp_phy_cfg sm8650_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2517,6 +2972,7 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = {
|
||||
|
||||
.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,
|
||||
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
|
||||
|
||||
@@ -2527,6 +2983,52 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = {
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = {
|
||||
.offsets = &qmp_combo_usb43dp_offsets_v8,
|
||||
|
||||
.serdes_tbl = glymur_usb43dp_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(glymur_usb43dp_serdes_tbl),
|
||||
.tx_tbl = glymur_usb43dp_lalb_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(glymur_usb43dp_lalb_tbl),
|
||||
.pcs_tbl = glymur_usb43dp_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_tbl),
|
||||
.pcs_usb_tbl = glymur_usb43dp_pcs_usb_tbl,
|
||||
.pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_usb_tbl),
|
||||
.pcs_misc_tbl = glymur_usb43dp_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_misc_tbl),
|
||||
|
||||
.dp_serdes_tbl = qmp_v8_dp_serdes_tbl,
|
||||
.dp_serdes_tbl_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl),
|
||||
.dp_tx_tbl = qmp_v8_n3p_dp_tx_tbl,
|
||||
.dp_tx_tbl_num = ARRAY_SIZE(qmp_v8_n3p_dp_tx_tbl),
|
||||
|
||||
.serdes_tbl_rbr = qmp_v8_dp_serdes_tbl_rbr,
|
||||
.serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_rbr),
|
||||
.serdes_tbl_hbr = qmp_v8_dp_serdes_tbl_hbr,
|
||||
.serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr),
|
||||
.serdes_tbl_hbr2 = qmp_v8_dp_serdes_tbl_hbr2,
|
||||
.serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr2),
|
||||
.serdes_tbl_hbr3 = qmp_v8_dp_serdes_tbl_hbr3,
|
||||
.serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr3),
|
||||
|
||||
.swing_hbr_rbr = &qmp_dp_v6_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_v8_dp_aux_init,
|
||||
.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,
|
||||
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
|
||||
.vreg_list = qmp_phy_vreg_refgen,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen),
|
||||
};
|
||||
|
||||
static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
@@ -2689,7 +3191,7 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
|
||||
return reverse;
|
||||
}
|
||||
|
||||
static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp)
|
||||
static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
|
||||
u32 phy_vco_div;
|
||||
@@ -2736,7 +3238,7 @@ static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp)
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
|
||||
|
||||
ret = qmp_combo_configure_dp_clocks(qmp);
|
||||
ret = qmp_v3_configure_dp_clocks(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2822,6 +3324,35 @@ static void qmp_v4_dp_aux_init(struct qmp_combo *qmp)
|
||||
qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
|
||||
}
|
||||
|
||||
static void qmp_v8_dp_aux_init(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
|
||||
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
|
||||
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
|
||||
qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
|
||||
|
||||
/* Turn on BIAS current for PHY/PLL */
|
||||
writel(0x1c, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]);
|
||||
|
||||
writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0);
|
||||
writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
|
||||
writel(0x06, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
|
||||
writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3);
|
||||
writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4);
|
||||
writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5);
|
||||
writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6);
|
||||
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 |
|
||||
PHY_AUX_REQ_ERR_MASK,
|
||||
qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
|
||||
}
|
||||
|
||||
static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
@@ -2836,6 +3367,58 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp)
|
||||
qmp_combo_configure_dp_swing(qmp);
|
||||
}
|
||||
|
||||
static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
|
||||
u32 phy_vco_div;
|
||||
unsigned long pixel_freq;
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
|
||||
switch (dp_opts->link_rate) {
|
||||
case 1620:
|
||||
phy_vco_div = 0x4;
|
||||
pixel_freq = 1620000000UL / 2;
|
||||
break;
|
||||
case 2700:
|
||||
phy_vco_div = 0x2;
|
||||
pixel_freq = 2700000000UL / 2;
|
||||
break;
|
||||
case 5400:
|
||||
phy_vco_div = 0x4;
|
||||
pixel_freq = 5400000000UL / 4;
|
||||
break;
|
||||
case 8100:
|
||||
phy_vco_div = 0x3;
|
||||
pixel_freq = 8100000000UL / 6;
|
||||
break;
|
||||
default:
|
||||
/* Other link rates aren't supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]);
|
||||
|
||||
/* disable core reset tsync */
|
||||
writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
|
||||
|
||||
writel(0x04, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC);
|
||||
writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC);
|
||||
writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_CYC);
|
||||
writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD);
|
||||
|
||||
writel(0x3e, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TSYNC_OVRD);
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL);
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL);
|
||||
writel(0x01, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_CFG1);
|
||||
writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD);
|
||||
writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN0_DRV_LVL);
|
||||
writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN1_DRV_LVL);
|
||||
|
||||
clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000);
|
||||
clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
@@ -2852,7 +3435,7 @@ static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp)
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
|
||||
writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
|
||||
|
||||
ret = qmp_combo_configure_dp_clocks(qmp);
|
||||
ret = qmp->cfg->configure_dp_clocks(qmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2966,6 +3549,62 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
|
||||
const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
|
||||
u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
ret = qmp_v456_configure_dp_phy(qmp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (dp_opts->lanes == 1) {
|
||||
bias0_en = reverse ? 0x3e : 0x15;
|
||||
bias1_en = reverse ? 0x15 : 0x3e;
|
||||
drvr0_en = reverse ? 0x13 : 0x10;
|
||||
drvr1_en = reverse ? 0x10 : 0x13;
|
||||
} else if (dp_opts->lanes == 2) {
|
||||
bias0_en = reverse ? 0x3f : 0x15;
|
||||
bias1_en = reverse ? 0x15 : 0x3f;
|
||||
drvr0_en = 0x10;
|
||||
drvr1_en = 0x10;
|
||||
} else {
|
||||
bias0_en = 0x3f;
|
||||
bias1_en = 0x3f;
|
||||
drvr0_en = 0x34;
|
||||
drvr1_en = 0x34;
|
||||
}
|
||||
|
||||
writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]);
|
||||
writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]);
|
||||
writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]);
|
||||
writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]);
|
||||
|
||||
writel(0x08, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
|
||||
udelay(100);
|
||||
writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
|
||||
udelay(500);
|
||||
|
||||
if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
|
||||
status,
|
||||
((status & BIT(1)) > 0),
|
||||
500,
|
||||
10000))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
writel(0x00, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]);
|
||||
writel(0x00, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]);
|
||||
|
||||
writel(0x2b, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
|
||||
writel(0x2b, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to calibrate the aux setting here as many times
|
||||
* as the caller tries
|
||||
@@ -3023,6 +3662,7 @@ 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;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
@@ -3058,10 +3698,20 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
|
||||
SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
|
||||
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);
|
||||
}
|
||||
|
||||
/* Use software based port select and switch on typec orientation */
|
||||
val = SW_PORTSELECT_MUX;
|
||||
if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
|
||||
val |= SW_PORTSELECT_VAL;
|
||||
|
||||
if (cfg->invert_cc_polarity)
|
||||
val |= INVERT_CC_POLARITY;
|
||||
|
||||
writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL);
|
||||
|
||||
switch (qmp->qmpphy_mode) {
|
||||
@@ -3235,6 +3885,8 @@ static int qmp_combo_usb_power_on(struct phy *phy)
|
||||
qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
|
||||
qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
qmp_configure(qmp->dev, qmp->pcs_misc, cfg->pcs_misc_tbl, cfg->pcs_misc_tbl_num);
|
||||
|
||||
|
||||
if (pcs_usb)
|
||||
qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl,
|
||||
@@ -3361,6 +4013,7 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp)
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
|
||||
void __iomem *pcs_misc = qmp->pcs_misc;
|
||||
void __iomem *pcs_aon = qmp->pcs_aon;
|
||||
u32 intr_mask;
|
||||
|
||||
if (qmp->phy_mode == PHY_MODE_USB_HOST_SS ||
|
||||
@@ -3380,9 +4033,14 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp)
|
||||
/* Enable required PHY autonomous mode interrupts */
|
||||
qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
|
||||
|
||||
/* Enable i/o clamp_n for autonomous mode */
|
||||
if (pcs_misc)
|
||||
qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
|
||||
/*
|
||||
* Enable i/o clamp_n for autonomous mode
|
||||
* V6 and later versions use pcs aon clamp register
|
||||
*/
|
||||
if (pcs_aon)
|
||||
qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN);
|
||||
else if (pcs_misc)
|
||||
qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN);
|
||||
}
|
||||
|
||||
static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp)
|
||||
@@ -3390,10 +4048,13 @@ static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp)
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
|
||||
void __iomem *pcs_misc = qmp->pcs_misc;
|
||||
void __iomem *pcs_aon = qmp->pcs_aon;
|
||||
|
||||
/* Disable i/o clamp_n on resume for normal mode */
|
||||
if (pcs_misc)
|
||||
qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN);
|
||||
if (pcs_aon)
|
||||
qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN);
|
||||
else if (pcs_misc)
|
||||
qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN);
|
||||
|
||||
qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
|
||||
ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
|
||||
@@ -4058,6 +4719,8 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
|
||||
qmp->serdes = base + offs->usb3_serdes;
|
||||
qmp->pcs_misc = base + offs->usb3_pcs_misc;
|
||||
qmp->pcs = base + offs->usb3_pcs;
|
||||
if (offs->usb3_pcs_aon)
|
||||
qmp->pcs_aon = base + offs->usb3_pcs_aon;
|
||||
qmp->pcs_usb = base + offs->usb3_pcs_usb;
|
||||
|
||||
qmp->dp_serdes = base + offs->dp_serdes;
|
||||
@@ -4319,6 +4982,10 @@ static int qmp_combo_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id qmp_combo_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,glymur-qmp-usb3-dp-phy",
|
||||
.data = &glymur_usb3dpphy_cfg,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sar2130p-qmp-usb3-dp-phy",
|
||||
.data = &sar2130p_usb3dpphy_cfg,
|
||||
|
||||
21
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h
Normal file
21
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_DP_PHY_V2_H_
|
||||
#define QCOM_PHY_QMP_DP_PHY_V2_H_
|
||||
|
||||
// /* Only for QMP V2 PHY - DP PHY registers */
|
||||
#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK 0x048
|
||||
#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c
|
||||
#define QSERDES_V2_DP_PHY_AUX_BIST_CFG 0x050
|
||||
|
||||
#define QSERDES_V2_DP_PHY_VCO_DIV 0x068
|
||||
#define QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL 0x06c
|
||||
#define QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL 0x088
|
||||
|
||||
#define QSERDES_V2_DP_PHY_SPARE0 0x0ac
|
||||
#define QSERDES_V2_DP_PHY_STATUS 0x0c0
|
||||
|
||||
#endif
|
||||
25
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h
Normal file
25
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_DP_PHY_V8_H_
|
||||
#define QCOM_PHY_QMP_DP_PHY_V8_H_
|
||||
|
||||
/* Only for QMP V8 PHY - DP PHY registers */
|
||||
#define QSERDES_V8_DP_PHY_VCO_DIV 0x070
|
||||
#define QSERDES_V8_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0
|
||||
#define QSERDES_V8_DP_PHY_TSYNC_OVRD 0x074
|
||||
#define QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL 0x078
|
||||
#define QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL 0x0bc
|
||||
#define QSERDES_V8_DP_PHY_AUXLESS_CFG1 0x0c8
|
||||
#define QSERDES_V8_DP_PHY_LFPS_PERIOD 0x0d0
|
||||
#define QSERDES_V8_DP_PHY_LFPS_CYC 0x0d4
|
||||
#define QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC 0x0d8
|
||||
#define QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC 0x0d8
|
||||
#define QSERDES_V8_DP_PHY_LN0_DRV_LVL 0x0e0
|
||||
#define QSERDES_V8_DP_PHY_LN1_DRV_LVL 0x0e4
|
||||
#define QSERDES_V8_DP_PHY_STATUS 0x114
|
||||
|
||||
|
||||
#endif
|
||||
52
drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h
Normal file
52
drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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
|
||||
@@ -37,6 +37,9 @@
|
||||
#include "phy-qcom-qmp-pcs-pcie-v6_30.h"
|
||||
#include "phy-qcom-qmp-pcs-v6_30.h"
|
||||
#include "phy-qcom-qmp-pcie-qhp.h"
|
||||
#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"
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
||||
|
||||
@@ -100,6 +103,13 @@ static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_v8_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = QPHY_V8_PCS_SW_RESET,
|
||||
[QPHY_START_CTRL] = QPHY_V8_PCS_START_CONTROL,
|
||||
[QPHY_PCS_STATUS] = QPHY_V8_PCS_PCS_STATUS1,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_PCS_POWER_DOWN_CONTROL,
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_START_CTRL] = QPHY_V8_50_PCS_START_CONTROL,
|
||||
[QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1,
|
||||
@@ -3067,6 +3077,149 @@ static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl[]
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0x93),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYS_CLK_CTRL, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x46),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MISC_1, 0x88),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MODE, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_DC_LEVEL_CTRL, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_SPARE_FOR_ECO, 0x02),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX, 0x1b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_2, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_3, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_10B_8B, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_20B_10B, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3, 0x53),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PHPRE_CTRL, 0x20),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL, 0x89),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4, 0x2d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_LVL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_BAND_CTRL0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SVS_MODE_CTRL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0, 0xc2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1, 0xc2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0, 0xe4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1, 0x63),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2, 0xd8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3, 0x99),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4, 0x67),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0, 0xa4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1, 0xa4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3, 0x9f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4, 0x48),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_GM_CAL, 0x0d),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN, 0x2e),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_SIGDET_LVL, 0xcc),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL, 0x40),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG4, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG5, 0x22),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_TX_RX_CONFIG, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME, 0x27),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME, 0x27),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_PRE_GAIN, 0x2e),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3, 0x28),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5, 0xf2),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5, 0xf2),
|
||||
QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f),
|
||||
};
|
||||
|
||||
struct qmp_pcie_offsets {
|
||||
u16 serdes;
|
||||
u16 pcs;
|
||||
@@ -3363,6 +3516,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
|
||||
.ln_shrd = 0x8000,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_0 = {
|
||||
.serdes = 0x1000,
|
||||
.pcs = 0x1400,
|
||||
.pcs_misc = 0x1800,
|
||||
.tx = 0x0000,
|
||||
.rx = 0x0200,
|
||||
.tx2 = 0x0800,
|
||||
.rx2 = 0x0a00,
|
||||
};
|
||||
|
||||
static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
|
||||
.serdes = 0x8000,
|
||||
.pcs = 0x9000,
|
||||
@@ -4425,6 +4588,34 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v8_0,
|
||||
|
||||
.tbls = {
|
||||
.serdes = kaanapali_qmp_gen3x2_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_serdes_tbl),
|
||||
.tx = kaanapali_qmp_gen3x2_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_tx_tbl),
|
||||
.rx = kaanapali_qmp_gen3x2_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_rx_tbl),
|
||||
.pcs = kaanapali_qmp_gen3x2_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_tbl),
|
||||
.pcs_misc = kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(kaanapali_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_v8_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
|
||||
.lanes = 4,
|
||||
|
||||
@@ -4441,6 +4632,22 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v8_0,
|
||||
|
||||
.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_v8_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;
|
||||
@@ -5192,6 +5399,9 @@ static int qmp_pcie_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,glymur-qmp-gen4x2-pcie-phy",
|
||||
.data = &glymur_qmp_gen4x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
|
||||
.data = &glymur_qmp_gen5x4_pciephy_cfg,
|
||||
}, {
|
||||
@@ -5209,6 +5419,9 @@ 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,kaanapali-qmp-gen3x2-pcie-phy",
|
||||
.data = &qmp_v8_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,msm8998-qmp-pcie-phy",
|
||||
.data = &msm8998_pciephy_cfg,
|
||||
|
||||
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h
Normal file
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_AON_V6_H_
|
||||
#define QCOM_PHY_QMP_PCS_AON_V6_H_
|
||||
|
||||
/* Only for QMP V6 PHY - PCS_AON registers */
|
||||
#define QPHY_V6_PCS_AON_CLAMP_ENABLE 0x00
|
||||
|
||||
#endif
|
||||
17
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h
Normal file
17
drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_AON_V8_H_
|
||||
#define QCOM_PHY_QMP_PCS_AON_V8_H_
|
||||
|
||||
/* Only for QMP V8 PHY - PCS_AON registers */
|
||||
#define QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE 0x00
|
||||
#define QPHY_V8_PCS_AON_USB4_AON_CLAMP_ENABLE 0x04
|
||||
#define QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE 0x08
|
||||
#define QPHY_V8_PCS_AON_USB4_AON_TOGGLE_ENABLE 0x0c
|
||||
#define QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE 0x10
|
||||
#define QPHY_V8_PCS_AON_DUMMY_STATUS 0x14
|
||||
|
||||
#endif
|
||||
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h
Normal file
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_MISC_V5_H_
|
||||
#define QCOM_PHY_QMP_PCS_MISC_V5_H_
|
||||
|
||||
/* Only for QMP V5 PHY - PCS_MISC registers */
|
||||
#define QPHY_V5_PCS_MISC_CLAMP_ENABLE 0x0c
|
||||
|
||||
#endif
|
||||
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h
Normal file
12
drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_MISC_V8_H_
|
||||
#define QCOM_PHY_QMP_PCS_MISC_V8_H_
|
||||
|
||||
/* Only for QMP V8 PHY - PCS_MISC registers */
|
||||
#define QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1 0x08
|
||||
|
||||
#endif
|
||||
34
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h
Normal file
34
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_PCS_PCIE_V8_H_
|
||||
#define QCOM_PHY_QMP_PCS_PCIE_V8_H_
|
||||
|
||||
/* Only for QMP V8 PHY - PCIE PCS registers */
|
||||
|
||||
#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2 0x00c
|
||||
#define QPHY_PCIE_V8_PCS_TX_RX_CONFIG 0x018
|
||||
#define QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE 0x01c
|
||||
#define QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS 0x090
|
||||
#define QPHY_PCIE_V8_PCS_EQ_CONFIG1 0x0a0
|
||||
#define QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME 0x0f0
|
||||
#define QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME 0x0f4
|
||||
#define QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5 0x108
|
||||
#define QPHY_PCIE_V8_PCS_G4_PRE_GAIN 0x15c
|
||||
#define QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB 0x170
|
||||
#define QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN 0x178
|
||||
#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1 0x17c
|
||||
#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3 0x184
|
||||
#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5 0x18c
|
||||
#define QPHY_PCIE_V8_PCS_RX_SIGDET_LVL 0x190
|
||||
#define QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5 0x1ac
|
||||
#define QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL 0x1b8
|
||||
#define QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5 0x1c0
|
||||
#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6 0x1d0
|
||||
#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1 0x1dc
|
||||
#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2 0x1e0
|
||||
#define QPHY_PCIE_V8_PCS_EQ_CONFIG4 0x1f8
|
||||
#define QPHY_PCIE_V8_PCS_EQ_CONFIG5 0x1fc
|
||||
#endif
|
||||
106
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h
Normal file
106
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_COM_V2_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_COM_V2_H_
|
||||
|
||||
/* Only for QMP V2 PHY - QSERDES COM registers */
|
||||
#define QSERDES_V2_COM_ATB_SEL1 0x000
|
||||
#define QSERDES_V2_COM_ATB_SEL2 0x004
|
||||
#define QSERDES_V2_COM_FREQ_UPDATE 0x008
|
||||
#define QSERDES_V2_COM_BG_TIMER 0x00c
|
||||
#define QSERDES_V2_COM_SSC_EN_CENTER 0x010
|
||||
#define QSERDES_V2_COM_SSC_ADJ_PER1 0x014
|
||||
#define QSERDES_V2_COM_SSC_ADJ_PER2 0x018
|
||||
#define QSERDES_V2_COM_SSC_PER1 0x01c
|
||||
#define QSERDES_V2_COM_SSC_PER2 0x020
|
||||
#define QSERDES_V2_COM_SSC_STEP_SIZE1 0x024
|
||||
#define QSERDES_V2_COM_SSC_STEP_SIZE2 0x028
|
||||
#define QSERDES_V2_COM_POST_DIV 0x02c
|
||||
#define QSERDES_V2_COM_POST_DIV_MUX 0x030
|
||||
#define QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN 0x034
|
||||
#define QSERDES_V2_COM_CLK_ENABLE1 0x038
|
||||
#define QSERDES_V2_COM_SYS_CLK_CTRL 0x03c
|
||||
#define QSERDES_V2_COM_SYSCLK_BUF_ENABLE 0x040
|
||||
#define QSERDES_V2_COM_PLL_EN 0x044
|
||||
#define QSERDES_V2_COM_PLL_IVCO 0x048
|
||||
#define QSERDES_V2_COM_LOCK_CMP1_MODE0 0x04c
|
||||
#define QSERDES_V2_COM_LOCK_CMP2_MODE0 0x050
|
||||
#define QSERDES_V2_COM_LOCK_CMP3_MODE0 0x054
|
||||
#define QSERDES_V2_COM_LOCK_CMP1_MODE1 0x058
|
||||
#define QSERDES_V2_COM_LOCK_CMP2_MODE1 0x05c
|
||||
#define QSERDES_V2_COM_LOCK_CMP3_MODE1 0x060
|
||||
#define QSERDES_V2_COM_EP_CLOCK_DETECT_CTR 0x068
|
||||
#define QSERDES_V2_COM_SYSCLK_DET_COMP_STATUS 0x06c
|
||||
#define QSERDES_V2_COM_CLK_EP_DIV 0x074
|
||||
#define QSERDES_V2_COM_CP_CTRL_MODE0 0x078
|
||||
#define QSERDES_V2_COM_CP_CTRL_MODE1 0x07c
|
||||
#define QSERDES_V2_COM_PLL_RCTRL_MODE0 0x084
|
||||
#define QSERDES_V2_COM_PLL_RCTRL_MODE1 0x088
|
||||
#define QSERDES_V2_COM_PLL_CCTRL_MODE0 0x090
|
||||
#define QSERDES_V2_COM_PLL_CCTRL_MODE1 0x094
|
||||
#define QSERDES_V2_COM_PLL_CNTRL 0x09c
|
||||
#define QSERDES_V2_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
|
||||
#define QSERDES_V2_COM_SYSCLK_EN_SEL 0x0ac
|
||||
#define QSERDES_V2_COM_CML_SYSCLK_SEL 0x0b0
|
||||
#define QSERDES_V2_COM_RESETSM_CNTRL 0x0b4
|
||||
#define QSERDES_V2_COM_RESETSM_CNTRL2 0x0b8
|
||||
#define QSERDES_V2_COM_LOCK_CMP_EN 0x0c8
|
||||
#define QSERDES_V2_COM_LOCK_CMP_CFG 0x0cc
|
||||
#define QSERDES_V2_COM_DEC_START_MODE0 0x0d0
|
||||
#define QSERDES_V2_COM_DEC_START_MODE1 0x0d4
|
||||
#define QSERDES_V2_COM_VCOCAL_DEADMAN_CTRL 0x0d8
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START1_MODE0 0x0dc
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START2_MODE0 0x0e0
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START3_MODE0 0x0e4
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START1_MODE1 0x0e8
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START2_MODE1 0x0ec
|
||||
#define QSERDES_V2_COM_DIV_FRAC_START3_MODE1 0x0f0
|
||||
#define QSERDES_V2_COM_VCO_TUNE_MINVAL1 0x0f4
|
||||
#define QSERDES_V2_COM_VCO_TUNE_MINVAL2 0x0f8
|
||||
#define QSERDES_V2_COM_INTEGLOOP_INITVAL 0x100
|
||||
#define QSERDES_V2_COM_INTEGLOOP_EN 0x104
|
||||
#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE0 0x108
|
||||
#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE0 0x10c
|
||||
#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE1 0x110
|
||||
#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE1 0x114
|
||||
#define QSERDES_V2_COM_VCO_TUNE_MAXVAL1 0x118
|
||||
#define QSERDES_V2_COM_VCO_TUNE_MAXVAL2 0x11c
|
||||
#define QSERDES_V2_COM_VCO_TUNE_CTRL 0x124
|
||||
#define QSERDES_V2_COM_VCO_TUNE_MAP 0x128
|
||||
#define QSERDES_V2_COM_VCO_TUNE1_MODE0 0x12c
|
||||
#define QSERDES_V2_COM_VCO_TUNE2_MODE0 0x130
|
||||
#define QSERDES_V2_COM_VCO_TUNE1_MODE1 0x134
|
||||
#define QSERDES_V2_COM_VCO_TUNE2_MODE1 0x138
|
||||
#define QSERDES_V2_COM_VCO_TUNE_INITVAL1 0x13c
|
||||
#define QSERDES_V2_COM_VCO_TUNE_INITVAL2 0x140
|
||||
#define QSERDES_V2_COM_VCO_TUNE_TIMER1 0x144
|
||||
#define QSERDES_V2_COM_VCO_TUNE_TIMER2 0x148
|
||||
#define QSERDES_V2_COM_CMN_STATUS 0x15c
|
||||
#define QSERDES_V2_COM_RESET_SM_STATUS 0x160
|
||||
#define QSERDES_V2_COM_RESTRIM_CODE_STATUS 0x164
|
||||
#define QSERDES_V2_COM_PLLCAL_CODE1_STATUS 0x168
|
||||
#define QSERDES_V2_COM_PLLCAL_CODE2_STATUS 0x16c
|
||||
#define QSERDES_V2_COM_CLK_SELECT 0x174
|
||||
#define QSERDES_V2_COM_HSCLK_SEL 0x178
|
||||
#define QSERDES_V2_COM_INTEGLOOP_BINCODE_STATUS 0x17c
|
||||
#define QSERDES_V2_COM_PLL_ANALOG 0x180
|
||||
#define QSERDES_V2_COM_CORECLK_DIV 0x184
|
||||
#define QSERDES_V2_COM_SW_RESET 0x188
|
||||
#define QSERDES_V2_COM_CORE_CLK_EN 0x18c
|
||||
#define QSERDES_V2_COM_C_READY_STATUS 0x190
|
||||
#define QSERDES_V2_COM_CMN_CONFIG 0x194
|
||||
#define QSERDES_V2_COM_CMN_RATE_OVERRIDE 0x198
|
||||
#define QSERDES_V2_COM_SVS_MODE_CLK_SEL 0x19c
|
||||
#define QSERDES_V2_COM_DEBUG_BUS0 0x1a0
|
||||
#define QSERDES_V2_COM_DEBUG_BUS1 0x1a4
|
||||
#define QSERDES_V2_COM_DEBUG_BUS2 0x1a8
|
||||
#define QSERDES_V2_COM_DEBUG_BUS3 0x1ac
|
||||
#define QSERDES_V2_COM_DEBUG_BUS_SEL 0x1b0
|
||||
#define QSERDES_V2_COM_CMN_MISC1 0x1b4
|
||||
#define QSERDES_V2_COM_CMN_MISC2 0x1b8
|
||||
#define QSERDES_V2_COM_CORECLK_DIV_MODE1 0x1bc
|
||||
|
||||
#endif
|
||||
@@ -33,6 +33,7 @@
|
||||
#define QSERDES_V8_COM_CP_CTRL_MODE0 0x070
|
||||
#define QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074
|
||||
#define QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078
|
||||
#define QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c
|
||||
#define QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080
|
||||
#define QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084
|
||||
#define QSERDES_V8_COM_DEC_START_MODE0 0x088
|
||||
@@ -40,6 +41,7 @@
|
||||
#define QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090
|
||||
#define QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094
|
||||
#define QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098
|
||||
#define QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1 0x09c
|
||||
#define QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8
|
||||
#define QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac
|
||||
#define QSERDES_V8_COM_BG_TIMER 0x0bc
|
||||
@@ -47,13 +49,22 @@
|
||||
#define QSERDES_V8_COM_SSC_PER1 0x0cc
|
||||
#define QSERDES_V8_COM_SSC_PER2 0x0d0
|
||||
#define QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc
|
||||
#define QSERDES_V8_COM_CLK_ENABLE1 0x0e0
|
||||
#define QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4
|
||||
#define QSERDES_V8_COM_PLL_IVCO 0x0f4
|
||||
#define QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8
|
||||
#define QSERDES_V8_COM_SYSCLK_EN_SEL 0x110
|
||||
#define QSERDES_V8_COM_RESETSM_CNTRL 0x118
|
||||
#define QSERDES_V8_COM_LOCK_CMP_EN 0x120
|
||||
#define QSERDES_V8_COM_LOCK_CMP_CFG 0x124
|
||||
#define QSERDES_V8_COM_VCO_TUNE_MAP 0x140
|
||||
#define QSERDES_V8_COM_CLK_SELECT 0x164
|
||||
#define QSERDES_V8_COM_CORE_CLK_EN 0x170
|
||||
#define QSERDES_V8_COM_CMN_CONFIG_1 0x174
|
||||
#define QSERDES_V8_COM_CMN_MISC_1 0x184
|
||||
#define QSERDES_V8_COM_CMN_MODE 0x188
|
||||
#define QSERDES_V8_COM_VCO_DC_LEVEL_CTRL 0x198
|
||||
#define QSERDES_V8_COM_PLL_SPARE_FOR_ECO 0x2b4
|
||||
#define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
|
||||
#define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
|
||||
#define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
|
||||
|
||||
52
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h
Normal file
52
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_DP_COM_V8_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_DP_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
|
||||
639
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h
Normal file
639
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h
Normal file
@@ -0,0 +1,639 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_V8_LALBH_
|
||||
#define QCOM_PHY_QMP_QSERDES_V8_LALBH_
|
||||
|
||||
#define QSERDES_V8_LALB_BIST_MODE_LANENO 0x0
|
||||
#define QSERDES_V8_LALB_BIST_INVERT 0x4
|
||||
#define QSERDES_V8_LALB_PERL_LENGTH1 0x8
|
||||
#define QSERDES_V8_LALB_PERL_LENGTH2 0xc
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN1 0x10
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN2 0x14
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN3 0x18
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN4 0x1c
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN5 0x20
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN6 0x24
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN7 0x28
|
||||
#define QSERDES_V8_LALB_BIST_PATTERN8 0x2c
|
||||
#define QSERDES_V8_LALB_PRBS_SEED1 0x30
|
||||
#define QSERDES_V8_LALB_PRBS_SEED2 0x34
|
||||
#define QSERDES_V8_LALB_PRBS_SEED3 0x38
|
||||
#define QSERDES_V8_LALB_PRBS_SEED4 0x3c
|
||||
#define QSERDES_V8_LALB_PRBS_SEED5 0x40
|
||||
#define QSERDES_V8_LALB_PRBS_SEED6 0x44
|
||||
#define QSERDES_V8_LALB_PRBS_SEED7 0x48
|
||||
#define QSERDES_V8_LALB_SW_RESET_PWRDNB 0x4c
|
||||
#define QSERDES_V8_LALB_RESET_GEN 0x50
|
||||
#define QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL 0x54
|
||||
#define QSERDES_V8_LALB_CDR_EN_RXEQ_RESET 0x58
|
||||
#define QSERDES_V8_LALB_CLKBUF_ENABLE 0x5c
|
||||
#define QSERDES_V8_LALB_TX0_EMP_POST1_LVL 0x60
|
||||
#define QSERDES_V8_LALB_TX1_EMP_POST1_LVL 0x64
|
||||
#define QSERDES_V8_LALB_TX0_IDLE_CTRL 0x68
|
||||
#define QSERDES_V8_LALB_TX1_IDLE_CTRL 0x6c
|
||||
#define QSERDES_V8_LALB_TX0_DRV_LVL 0x70
|
||||
#define QSERDES_V8_LALB_TX0_DRV_LVL_OFFSET 0x74
|
||||
#define QSERDES_V8_LALB_TX1_DRV_LVL 0x78
|
||||
#define QSERDES_V8_LALB_TX1_DRV_LVL_OFFSET 0x7c
|
||||
#define QSERDES_V8_LALB_TRAN_DRVR_EMP_EN 0x80
|
||||
#define QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL 0x84
|
||||
#define QSERDES_V8_LALB_TX0_PRE1_EMPH 0x88
|
||||
#define QSERDES_V8_LALB_TX1_PRE1_EMPH 0x8c
|
||||
#define QSERDES_V8_LALB_TX0_PRE2_EMPH 0x90
|
||||
#define QSERDES_V8_LALB_TX1_PRE2_EMPH 0x94
|
||||
#define QSERDES_V8_LALB_STALL_LDO_BOOST_EN 0x98
|
||||
#define QSERDES_V8_LALB_PRE_EMPH_EN_CTRL 0x9c
|
||||
#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1 0xa0
|
||||
#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2 0xa4
|
||||
#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3 0xa8
|
||||
#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4 0xac
|
||||
#define QSERDES_V8_LALB_TRANSMITTER_EN_CTRL 0xb0
|
||||
#define QSERDES_V8_LALB_HIGHZ_DRVR_EN 0xb4
|
||||
#define QSERDES_V8_LALB_TX_MISC_CTRL1 0xb8
|
||||
#define QSERDES_V8_LALB_LPB_EN_CTRL1 0xbc
|
||||
#define QSERDES_V8_LALB_LBP_EN_CTRL2 0xc0
|
||||
#define QSERDES_V8_LALB_TX0_SERDES_BYP_CTRL 0xc4
|
||||
#define QSERDES_V8_LALB_TX1_SERDES_BYP_CTRL 0xc8
|
||||
#define QSERDES_V8_LALB_LANE_MODE_1 0xcc
|
||||
#define QSERDES_V8_LALB_LANE_MODE_2 0xd0
|
||||
#define QSERDES_V8_LALB_LANE_MODE_3 0xd4
|
||||
#define QSERDES_V8_LALB_LANE_MODE_4 0xd8
|
||||
#define QSERDES_V8_LALB_ATB_SEL1 0xdc
|
||||
#define QSERDES_V8_LALB_ATB_SEL2 0xe0
|
||||
#define QSERDES_V8_LALB_TX0_RES_CODE_LANE 0xe4
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_OVRD 0xe8
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL 0xec
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_INIT_CODE 0xf0
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET 0xf4
|
||||
#define QSERDES_V8_LALB_TX1_RES_CODE_LANE 0xf8
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_OVRD 0xfc
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL 0x100
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_INIT_CODE 0x104
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET 0x108
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL 0x10c
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL 0x110
|
||||
#define QSERDES_V8_LALB_VMODE_CTRL1 0x114
|
||||
#define QSERDES_V8_LALB_SLEW_CNTL_RATE01 0x118
|
||||
#define QSERDES_V8_LALB_SLEW_CNTL_RATE23 0x11c
|
||||
#define QSERDES_V8_LALB_SLEW_CNTL_RATE4 0x120
|
||||
#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT1 0x124
|
||||
#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT2 0x128
|
||||
#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT3 0x12c
|
||||
#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT1 0x130
|
||||
#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT2 0x134
|
||||
#define QSERDES_V8_LALB_LDO_TIMER_CTRL 0x138
|
||||
#define QSERDES_V8_LALB_AC_JTAG_ENABLE 0x13c
|
||||
#define QSERDES_V8_LALB_AC_JTAG_INITP 0x140
|
||||
#define QSERDES_V8_LALB_AC_JTAG_INITN 0x144
|
||||
#define QSERDES_V8_LALB_AC_JTAG_LVL 0x148
|
||||
#define QSERDES_V8_LALB_AC_JTAG_MODE 0x14c
|
||||
#define QSERDES_V8_LALB_AC_JTAG_RESET 0x150
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0 0x154
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1 0x158
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2 0x15c
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3 0x160
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4 0x164
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5 0x168
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6 0x16c
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7 0x170
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B0 0x174
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B1 0x178
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B2 0x17c
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B3 0x180
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B4 0x184
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B5 0x188
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B6 0x18c
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE2_B7 0x190
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B0 0x194
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B1 0x198
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B2 0x19c
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B3 0x1a0
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B4 0x1a4
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B5 0x1a8
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B6 0x1ac
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE3_B7 0x1b0
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B0 0x1b4
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B1 0x1b8
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B2 0x1bc
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B3 0x1c0
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B4 0x1c4
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B5 0x1c8
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B6 0x1cc
|
||||
#define QSERDES_V8_LALB_RX_MODE_RATE4_B7 0x1d0
|
||||
#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL1 0x1d4
|
||||
#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL2 0x1d8
|
||||
#define QSERDES_V8_LALB_CMUX_DCC_CTRL1 0x1dc
|
||||
#define QSERDES_V8_LALB_CMUX_DCC_POSTCAL_OFFSET 0x1e0
|
||||
#define QSERDES_V8_LALB_CMUX_DCC_OVRD 0x1e4
|
||||
#define QSERDES_V8_LALB_TX_DCC_CTRL 0x1e8
|
||||
#define QSERDES_V8_LALB_TX0_CTUNE_DCC_CONFIG 0x1ec
|
||||
#define QSERDES_V8_LALB_TX0_CTUNE_DCC_POSTCAL_OFFSET 0x1f0
|
||||
#define QSERDES_V8_LALB_TX0_CTUNE_DCC_OVRD 0x1f4
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_CONFIG 0x1f8
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x1fc
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_CONFIG 0x200
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x204
|
||||
#define QSERDES_V8_LALB_TX1_CTUNE_DCC_CONFIG 0x208
|
||||
#define QSERDES_V8_LALB_TX1_CTUNE_DCC_POSTCAL_OFFSET 0x20c
|
||||
#define QSERDES_V8_LALB_TX1_CTUNE_DCC_OVRD 0x210
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_CONFIG 0x214
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x218
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_CONFIG 0x21c
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x220
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CTRL 0x224
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE0 0x228
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE1 0x22c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE2 0x230
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE3 0x234
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE4 0x238
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAL_CTRL 0x23c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE0 0x240
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE0 0x244
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1 0x248
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1 0x24c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2 0x250
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2 0x254
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE3 0x258
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE3 0x25c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE4 0x260
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE4 0x264
|
||||
#define QSERDES_V8_LALB_CDR_VCTRL_RATE_0_1 0x268
|
||||
#define QSERDES_V8_LALB_CDR_VCTRL_RATE_2_3 0x26c
|
||||
#define QSERDES_V8_LALB_CDR_VCTRL_RATE_4 0x270
|
||||
#define QSERDES_V8_LALB_KVCO_INIT_RATE_0_1 0x274
|
||||
#define QSERDES_V8_LALB_KVCO_INIT_RATE_2_3 0x278
|
||||
#define QSERDES_V8_LALB_KVCO_INIT_RATE_4 0x27c
|
||||
#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE0 0x280
|
||||
#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1 0x284
|
||||
#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2 0x288
|
||||
#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE3 0x28c
|
||||
#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE4 0x290
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_0_1 0x294
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_2_3 0x298
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_4 0x29c
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_0_1 0x2a0
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_2_3 0x2a4
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_4 0x2a8
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE0 0x2ac
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE0 0x2b0
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1 0x2b4
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1 0x2b8
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2 0x2bc
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2 0x2c0
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE3 0x2c4
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE3 0x2c8
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE4 0x2cc
|
||||
#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE4 0x2d0
|
||||
#define QSERDES_V8_LALB_KP_CDR_UP_DN 0x2d4
|
||||
#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_0_1 0x2d8
|
||||
#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3 0x2dc
|
||||
#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE4 0x2e0
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0 0x2e4
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE0 0x2e8
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1 0x2ec
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1 0x2f0
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2 0x2f4
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2 0x2f8
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3 0x2fc
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE3 0x300
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4 0x304
|
||||
#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE4 0x308
|
||||
#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0 0x30c
|
||||
#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1 0x310
|
||||
#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2 0x314
|
||||
#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3 0x318
|
||||
#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4 0x31c
|
||||
#define QSERDES_V8_LALB_CDR_KVCO_KP_CAL_FREQ_MEAS_CTRL 0x320
|
||||
#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CTRL 0x324
|
||||
#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT1 0x328
|
||||
#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT2 0x32c
|
||||
#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT3 0x330
|
||||
#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123 0x334
|
||||
#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_4 0x338
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE0 0x33c
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1 0x340
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2 0x344
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE3 0x348
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE4 0x34c
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL1 0x350
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2 0x354
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3 0x358
|
||||
#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL4 0x35c
|
||||
#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE0 0x360
|
||||
#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1 0x364
|
||||
#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2 0x368
|
||||
#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE3 0x36c
|
||||
#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE4 0x370
|
||||
#define QSERDES_V8_LALB_RX_IDAC_I0_DC_OFFSETS 0x374
|
||||
#define QSERDES_V8_LALB_RX_IDAC_I0BAR_DC_OFFSETS 0x378
|
||||
#define QSERDES_V8_LALB_RX_IDAC_I1_DC_OFFSETS 0x37c
|
||||
#define QSERDES_V8_LALB_RX_IDAC_I1BAR_DC_OFFSETS 0x380
|
||||
#define QSERDES_V8_LALB_RX_IDAC_Q_DC_OFFSETS 0x384
|
||||
#define QSERDES_V8_LALB_RX_IDAC_QBAR_DC_OFFSETS 0x388
|
||||
#define QSERDES_V8_LALB_RX_IDAC_A_DC_OFFSETS 0x38c
|
||||
#define QSERDES_V8_LALB_RX_IDAC_ABAR_DC_OFFSETS 0x390
|
||||
#define QSERDES_V8_LALB_RX_IDAC_EN 0x394
|
||||
#define QSERDES_V8_LALB_DATA_SLICER_INIT_TIMER_CTRL 0x398
|
||||
#define QSERDES_V8_LALB_RX_IDAC_ENABLES 0x39c
|
||||
#define QSERDES_V8_LALB_RX_IDAC_SIGN 0x3a0
|
||||
#define QSERDES_V8_LALB_RX_IDAC_TSETTLE 0x3a4
|
||||
#define QSERDES_V8_LALB_SIGDET_ENABLES 0x3a8
|
||||
#define QSERDES_V8_LALB_SIGDET_CNTRL 0x3ac
|
||||
#define QSERDES_V8_LALB_SIGDET_LVL 0x3b0
|
||||
#define QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL 0x3b4
|
||||
#define QSERDES_V8_LALB_SIGDET_CAL_CTRL1 0x3b8
|
||||
#define QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x3bc
|
||||
#define QSERDES_V8_LALB_SIGDET_CAL_TRIM 0x3c0
|
||||
#define QSERDES_V8_LALB_IA_OFFSET_CENTER_CAL_CTRL 0x3c4
|
||||
#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE0 0x3c8
|
||||
#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1 0x3cc
|
||||
#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2 0x3d0
|
||||
#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE3 0x3d4
|
||||
#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE4 0x3d8
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE0 0x3dc
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE1 0x3e0
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE2 0x3e4
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE3 0x3e8
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE4 0x3ec
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_CTRL 0x3f0
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE0 0x3f4
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1 0x3f8
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2 0x3fc
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE3 0x400
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE4 0x404
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE0 0x408
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1 0x40c
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2 0x410
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE3 0x414
|
||||
#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE4 0x418
|
||||
#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123 0x41c
|
||||
#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE4 0x420
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01 0x424
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23 0x428
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE4 0x42c
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1 0x430
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3 0x434
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE4 0x438
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1 0x43c
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3 0x440
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE4 0x444
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1 0x448
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3 0x44c
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE4 0x450
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123 0x454
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE4 0x458
|
||||
#define QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG 0x45c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ 0x460
|
||||
#define QSERDES_V8_LALB_CDR_FAST_SLOW_VCO_OVRD 0x464
|
||||
#define QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL 0x468
|
||||
#define QSERDES_V8_LALB_CDR_FAST_LOCK_EN_CTRL 0x46c
|
||||
#define QSERDES_V8_LALB_RX_RCVR_EN 0x470
|
||||
#define QSERDES_V8_LALB_LANE_RATE_CTRL 0x474
|
||||
#define QSERDES_V8_LALB_RX_TERM_RCVR_CTRL 0x478
|
||||
#define QSERDES_V8_LALB_REC_DETECT_CTRL 0x47c
|
||||
#define QSERDES_V8_LALB_RCV_DETECT_LVL 0x480
|
||||
#define QSERDES_V8_LALB_GM_CAL_EN 0x484
|
||||
#define QSERDES_V8_LALB_GM_CAL_RES_RATE0_1 0x488
|
||||
#define QSERDES_V8_LALB_GM_CAL_RES_RATE2_3 0x48c
|
||||
#define QSERDES_V8_LALB_GM_CAL_RES_RATE4 0x490
|
||||
#define QSERDES_V8_LALB_RX_TERM_BW_RATE_0123 0x494
|
||||
#define QSERDES_V8_LALB_RX_TERM_BW_RATE4 0x498
|
||||
#define QSERDES_V8_LALB_AUX_CLK_CTRL 0x49c
|
||||
#define QSERDES_V8_LALB_AUX_OFFSET_CONTROL 0x4a0
|
||||
#define QSERDES_V8_LALB_AUXDATA_TB 0x4a4
|
||||
#define QSERDES_V8_LALB_EOM_CTRL1 0x4a8
|
||||
#define QSERDES_V8_LALB_EOM_CTRL2 0x4ac
|
||||
#define QSERDES_V8_LALB_EOM_CTRL3 0x4b0
|
||||
#define QSERDES_V8_LALB_EOM_CTRL4 0x4b4
|
||||
#define QSERDES_V8_LALB_DFE_EN_TIMER 0x4b8
|
||||
#define QSERDES_V8_LALB_RX_EQ_OFFSET_LSB 0x4bc
|
||||
#define QSERDES_V8_LALB_RX_EQ_OFFSET_MSB 0x4c0
|
||||
#define QSERDES_V8_LALB_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x4c4
|
||||
#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL2 0x4c8
|
||||
#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL3 0x4cc
|
||||
#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL1 0x4d0
|
||||
#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2 0x4d4
|
||||
#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3 0x4d8
|
||||
#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4 0x4dc
|
||||
#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL5 0x4e0
|
||||
#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_LSB 0x4e4
|
||||
#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_MSB 0x4e8
|
||||
#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_LSB 0x4ec
|
||||
#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_MSB 0x4f0
|
||||
#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_0_1_2 0x4f4
|
||||
#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_3_4 0x4f8
|
||||
#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2 0x4fc
|
||||
#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_3_4 0x500
|
||||
#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK1 0x504
|
||||
#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK2 0x508
|
||||
#define QSERDES_V8_LALB_VGA_CAL_CNTRL1 0x50c
|
||||
#define QSERDES_V8_LALB_VGA_CAL_CNTRL2 0x510
|
||||
#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1 0x514
|
||||
#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3 0x518
|
||||
#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE4 0x51c
|
||||
#define QSERDES_V8_LALB_KVGA_CTRL1 0x520
|
||||
#define QSERDES_V8_LALB_KVGA_CTRL2 0x524
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL1 0x528
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL2 0x52c
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE0 0x530
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE1 0x534
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE2 0x538
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE3 0x53c
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE4 0x540
|
||||
#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_CAL_PAM3 0x544
|
||||
#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_0_1 0x548
|
||||
#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_2_3 0x54c
|
||||
#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE4 0x550
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_CTRL 0x554
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_MANVAL_KTAP 0x558
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_0_1_2 0x55c
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_3_4 0x560
|
||||
#define QSERDES_V8_LALB_DFE_TAP2_CTRL 0x564
|
||||
#define QSERDES_V8_LALB_DFE_TAP2_MANVAL_KTAP 0x568
|
||||
#define QSERDES_V8_LALB_DFE_TAP3_CTRL 0x56c
|
||||
#define QSERDES_V8_LALB_DFE_TAP3_MANVAL_KTAP 0x570
|
||||
#define QSERDES_V8_LALB_DFE_TAP4_CTRL 0x574
|
||||
#define QSERDES_V8_LALB_DFE_TAP4_MANVAL_KTAP 0x578
|
||||
#define QSERDES_V8_LALB_DFE_TAP5_CTRL 0x57c
|
||||
#define QSERDES_V8_LALB_DFE_TAP5_MANVAL_KTAP 0x580
|
||||
#define QSERDES_V8_LALB_DFE_TAP6_CTRL 0x584
|
||||
#define QSERDES_V8_LALB_DFE_TAP6_MANVAL_KTAP 0x588
|
||||
#define QSERDES_V8_LALB_DFE_TAP7_CTRL 0x58c
|
||||
#define QSERDES_V8_LALB_DFE_TAP7_MANVAL_KTAP 0x590
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE 0x594
|
||||
#define QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE 0x598
|
||||
#define QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE 0x59c
|
||||
#define QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE 0x5a0
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CTRL 0x5a4
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_GAIN 0x5a8
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX 0x5ac
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL1 0x5b0
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL2 0x5b4
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE0 0x5b8
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE1 0x5bc
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE2 0x5c0
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE3 0x5c4
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE4 0x5c8
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE0 0x5cc
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE1 0x5d0
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE2 0x5d4
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE3 0x5d8
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE4 0x5dc
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_ANA_CTRL 0x5e0
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_VDCC_CTRL 0x5e4
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123 0x5e8
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE4 0x5ec
|
||||
#define QSERDES_V8_LALB_BLW_CTRL 0x5f0
|
||||
#define QSERDES_V8_LALB_BLW_ANA_VER_CTRL 0x5f4
|
||||
#define QSERDES_V8_LALB_BLW_GAIN_CAL_CTRL 0x5f8
|
||||
#define QSERDES_V8_LALB_BLW_GAIN_FORCE_CODE 0x5fc
|
||||
#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE3 0x600
|
||||
#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE4 0x604
|
||||
#define QSERDES_V8_LALB_IVTH_CAL_CTRL1 0x608
|
||||
#define QSERDES_V8_LALB_IVTH_CAL_CTRL2 0x60c
|
||||
#define QSERDES_V8_LALB_IVTH_CAL_CTRL3 0x610
|
||||
#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_VAL 0x614
|
||||
#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_VAL 0x618
|
||||
#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_VAL 0x61c
|
||||
#define QSERDES_V8_LALB_IVTH_CAL_VAL_OVRD_MUX 0x620
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES 0x624
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE0 0x628
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE1 0x62c
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE2 0x630
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE3 0x634
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE4 0x638
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE0 0x63c
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE1 0x640
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE2 0x644
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE3 0x648
|
||||
#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE4 0x64c
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE0 0x650
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE1 0x654
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE2 0x658
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE3 0x65c
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE4 0x660
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE0 0x664
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE1 0x668
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE2 0x66c
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE3 0x670
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE4 0x674
|
||||
#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE0 0x678
|
||||
#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE1 0x67c
|
||||
#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE2 0x680
|
||||
#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE3 0x684
|
||||
#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE4 0x688
|
||||
#define QSERDES_V8_LALB_DEBUG_BUS_SEL 0x68c
|
||||
#define QSERDES_V8_LALB_BIST_STATUS 0x690
|
||||
#define QSERDES_V8_LALB_BIST_ERROR_COUNT1 0x694
|
||||
#define QSERDES_V8_LALB_BIST_ERROR_COUNT2 0x698
|
||||
#define QSERDES_V8_LALB_AC_JTAG_OUTP 0x69c
|
||||
#define QSERDES_V8_LALB_AC_JTAG_OUTN 0x6a0
|
||||
#define QSERDES_V8_LALB_DATA_SLICER_DEBUG_STATUS 0x6a4
|
||||
#define QSERDES_V8_LALB_DATA_SLICER_TIMER1_STATUS 0x6a8
|
||||
#define QSERDES_V8_LALB_DATA_SLICER_TIMER2_STATUS 0x6ac
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_CODE_STATUS 0x6b0
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_CODE_STATUS 0x6b4
|
||||
#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_STATUS 0x6b8
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_CODE_STATUS 0x6bc
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_CODE_STATUS 0x6c0
|
||||
#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_STATUS 0x6c4
|
||||
#define QSERDES_V8_LALB_CMUX_DCC_CAL_FSM_STATUS 0x6c8
|
||||
#define QSERDES_V8_LALB_CMUX_DCC_READCODE_STATUS 0x6cc
|
||||
#define QSERDES_V8_LALB_TX_DCC_CAL_ANA_STATUS 0x6d0
|
||||
#define QSERDES_V8_LALB_TX0_CTUNE_DCC_FSM_DEBUG_STATUS 0x6d4
|
||||
#define QSERDES_V8_LALB_TX0_COARSE_DCC_READCODE_STATUS 0x6d8
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6dc
|
||||
#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6e0
|
||||
#define QSERDES_V8_LALB_TX0_FINE_DCC_READCODE_STATUS 0x6e4
|
||||
#define QSERDES_V8_LALB_TX1_CTUNE_DCC_FSM_DEBUG_STATUS 0x6e8
|
||||
#define QSERDES_V8_LALB_TX1_COARSE_DCC_READCODE_STATUS 0x6ec
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6f0
|
||||
#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6f4
|
||||
#define QSERDES_V8_LALB_TX1_FINE_DCC_READCODE_STATUS 0x6f8
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAL_STATUS 0x6fc
|
||||
#define QSERDES_V8_LALB_CDR_VCTRL_STATUS 0x700
|
||||
#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_STATUS 0x704
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_DEBUG1_STATUS 0x708
|
||||
#define QSERDES_V8_LALB_KVCO_CAL_DEBUG2_STATUS 0x70c
|
||||
#define QSERDES_V8_LALB_KP_CAL_DEBUG1_STATUS 0x710
|
||||
#define QSERDES_V8_LALB_KP_CAL_DEBUG2_STATUS 0x714
|
||||
#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG1_STATUS 0x718
|
||||
#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG2_STATUS 0x71c
|
||||
#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG3_STATUS 0x720
|
||||
#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG4_STATUS 0x724
|
||||
#define QSERDES_V8_LALB_IVCM_CAL_STATUS 0x728
|
||||
#define QSERDES_V8_LALB_IVCM_CAL_DEBUG_STATUS 0x72c
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_I0 0x730
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_I0BAR 0x734
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_I1 0x738
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_I1BAR 0x73c
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_Q 0x740
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_QBAR 0x744
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_A 0x748
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_ABAR 0x74c
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_SM_ON 0x750
|
||||
#define QSERDES_V8_LALB_IDAC_STATUS_SIGNERROR 0x754
|
||||
#define QSERDES_V8_LALB_RX_SIGDET_STATUS 0x758
|
||||
#define QSERDES_V8_LALB_SIGDET_CAL_CODE_STATUS 0x75c
|
||||
#define QSERDES_V8_LALB_SIGDET_CAL_FSM_DEBUG_STATUS 0x760
|
||||
#define QSERDES_V8_LALB_CDR_FREQ_LOCK_CNT_STATUS 0x764
|
||||
#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_STATUS 0x768
|
||||
#define QSERDES_V8_LALB_CDR_LOCK_DEBUG_STATUS 0x76c
|
||||
#define QSERDES_V8_LALB_IDATA_HIGH_STATUS1 0x770
|
||||
#define QSERDES_V8_LALB_IDATA_HIGH_STATUS2 0x774
|
||||
#define QSERDES_V8_LALB_IDATA_HIGH_STATUS3 0x778
|
||||
#define QSERDES_V8_LALB_IDATA_HIGH_STATUS4 0x77c
|
||||
#define QSERDES_V8_LALB_IDATA_LOW_STATUS1 0x780
|
||||
#define QSERDES_V8_LALB_IDATA_LOW_STATUS2 0x784
|
||||
#define QSERDES_V8_LALB_IDATA_LOW_STATUS3 0x788
|
||||
#define QSERDES_V8_LALB_IDATA_LOW_STATUS4 0x78c
|
||||
#define QSERDES_V8_LALB_QDATA_STATUS1 0x790
|
||||
#define QSERDES_V8_LALB_QDATA_STATUS2 0x794
|
||||
#define QSERDES_V8_LALB_QDATA_STATUS3 0x798
|
||||
#define QSERDES_V8_LALB_QDATA_STATUS4 0x79c
|
||||
#define QSERDES_V8_LALB_IA_ERROR_COUNTER_LOW 0x7a0
|
||||
#define QSERDES_V8_LALB_IA_ERROR_COUNTER_HIGH 0x7a4
|
||||
#define QSERDES_V8_LALB_EOM_ERR_CNT_LSB_STATUS 0x7a8
|
||||
#define QSERDES_V8_LALB_EOM_ERR_CNT_MSB_STATUS 0x7ac
|
||||
#define QSERDES_V8_LALB_EOM_OP_STATUS 0x7b0
|
||||
#define QSERDES_V8_LALB_AUX_MIXER_INDEX_STATUS 0x7b4
|
||||
#define QSERDES_V8_LALB_AUX_OFFSET_STATUS 0x7b8
|
||||
#define QSERDES_V8_LALB_AUXDATA_TB_STATUS 0x7bc
|
||||
#define QSERDES_V8_LALB_AUX_MIXER_CTRL_0_STATUS 0x7c0
|
||||
#define QSERDES_V8_LALB_AUX_MIXER_CTRL_90_STATUS 0x7c4
|
||||
#define QSERDES_V8_LALB_AUX_MIXER_CTRL_180_STATUS 0x7c8
|
||||
#define QSERDES_V8_LALB_IQ_MIXER_INDEX_STATUS 0x7cc
|
||||
#define QSERDES_V8_LALB_IQTUNE_FLTR_INDEX_STATUS 0x7d0
|
||||
#define QSERDES_V8_LALB_IQ_MIXER_CTRL_0_STATUS 0x7d4
|
||||
#define QSERDES_V8_LALB_IQ_MIXER_CTRL_90_STATUS 0x7d8
|
||||
#define QSERDES_V8_LALB_IQ_MIXER_CTRL_180_STATUS 0x7dc
|
||||
#define QSERDES_V8_LALB_READ_EQCODE 0x7e0
|
||||
#define QSERDES_V8_LALB_READ_OFFSETCODE 0x7e4
|
||||
#define QSERDES_V8_LALB_VGA_READ_CODE 0x7e8
|
||||
#define QSERDES_V8_LALB_VTHRESH_READ_CODE 0x7ec
|
||||
#define QSERDES_V8_LALB_DFE_TAP1_READ_CODE 0x7f0
|
||||
#define QSERDES_V8_LALB_DFE_TAP2_READ_CODE 0x7f4
|
||||
#define QSERDES_V8_LALB_DFE_TAP3_READ_CODE 0x7f8
|
||||
#define QSERDES_V8_LALB_DFE_TAP4_READ_CODE 0x7fc
|
||||
#define QSERDES_V8_LALB_DFE_TAP5_READ_CODE 0x800
|
||||
#define QSERDES_V8_LALB_DFE_TAP6_READ_CODE 0x804
|
||||
#define QSERDES_V8_LALB_DFE_TAP7_READ_CODE 0x808
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_BIN_CODE 0x80c
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK0_CODE 0x810
|
||||
#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK90_CODE 0x814
|
||||
#define QSERDES_V8_LALB_BLW_READ_CODE 0x818
|
||||
#define QSERDES_V8_LALB_IA_OFFSET_CAL_DEBUG_STATUS 0x81c
|
||||
#define QSERDES_V8_LALB_IA_OFFSET_CAL_STATUS 0x820
|
||||
#define QSERDES_V8_LALB_IVTH_CAL_STATUS 0x824
|
||||
#define QSERDES_V8_LALB_IVTH_NRZ_EYE_HEIGHT_STATUS 0x828
|
||||
#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MAX_STATUS 0x82c
|
||||
#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MIN_STATUS 0x830
|
||||
#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MAX_STATUS 0x834
|
||||
#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MIN_STATUS 0x838
|
||||
#define QSERDES_V8_LALB_IVTH_UP_INIT_CTR_STATUS 0x83c
|
||||
#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_STATUS 0x840
|
||||
#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_STATUS 0x844
|
||||
#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_STATUS 0x848
|
||||
#define QSERDES_V8_LALB_DEBUG_BUS0 0x84c
|
||||
#define QSERDES_V8_LALB_DEBUG_BUS1 0x850
|
||||
#define QSERDES_V8_LALB_DEBUG_BUS2 0x854
|
||||
#define QSERDES_V8_LALB_DEBUG_BUS3 0x858
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL1 0x85c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL2 0x860
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL3 0x864
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL4 0x868
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL5 0x86c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL6 0x870
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL7 0x874
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL8 0x878
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL9 0x87c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL10 0x880
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL11 0x884
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL12 0x888
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL13 0x88c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL14 0x890
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL15 0x894
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL16 0x898
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL17 0x89c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL18 0x8a0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL19 0x8a4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL20 0x8a8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL21 0x8ac
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL22 0x8b0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL23 0x8b4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL24 0x8b8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL25 0x8bc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL26 0x8c0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL27 0x8c4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL28 0x8c8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL29 0x8cc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL30 0x8d0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL31 0x8d4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL32 0x8d8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_1 0x8dc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_2 0x8e0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_3 0x8e4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_4 0x8e8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_5 0x8ec
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS1 0x8f0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS2 0x8f4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS3 0x8f8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS4 0x8fc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS5 0x900
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS6 0x904
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS7 0x908
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS8 0x90c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS9 0x910
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS10 0x914
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS11 0x918
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS12 0x91c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS13 0x920
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS14 0x924
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS15 0x928
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS16 0x92c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS17 0x930
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS18 0x934
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS19 0x938
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS20 0x93c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS21 0x940
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS22 0x944
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS23 0x948
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS24 0x94c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS25 0x950
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS26 0x954
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS27 0x958
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS28 0x95c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS29 0x960
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS30 0x964
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS31 0x968
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS32 0x96c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS1 0x970
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS2 0x974
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS3 0x978
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS4 0x97c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS5 0x980
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS6 0x984
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS7 0x988
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS8 0x98c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS9 0x990
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS10 0x994
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS11 0x998
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS12 0x99c
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS13 0x9a0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS14 0x9a4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS15 0x9a8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS16 0x9ac
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS17 0x9b0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS18 0x9b4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS19 0x9b8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS20 0x9bc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS21 0x9c0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS22 0x9c4
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS23 0x9c8
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS24 0x9cc
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS25 0x9d0
|
||||
#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS26 0x9d4
|
||||
#endif /* QCOM_PHY_QMP_QSERDES_V8_LALBH_ */
|
||||
71
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h
Normal file
71
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_
|
||||
|
||||
#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX 0x030
|
||||
#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX 0x034
|
||||
#define QSERDES_V8_PCIE_TX_LANE_MODE_1 0x07c
|
||||
#define QSERDES_V8_PCIE_TX_LANE_MODE_2 0x080
|
||||
#define QSERDES_V8_PCIE_TX_LANE_MODE_3 0x084
|
||||
#define QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN 0x0b4
|
||||
#define QSERDES_V8_PCIE_TX_TX_BAND0 0x0e0
|
||||
#define QSERDES_V8_PCIE_TX_TX_BAND1 0x0e4
|
||||
#define QSERDES_V8_PCIE_TX_SEL_10B_8B 0x0f4
|
||||
#define QSERDES_V8_PCIE_TX_SEL_20B_10B 0x0f8
|
||||
#define QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN 0x058
|
||||
#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1 0x118
|
||||
#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2 0x11c
|
||||
#define QSERDES_V8_PCIE_TX_PHPRE_CTRL 0x128
|
||||
#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3 0x148
|
||||
#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4 0x14c
|
||||
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4 0x0dc
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3 0x0ec
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4 0x0f0
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS 0x0f4
|
||||
#define QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1 0x170
|
||||
#define QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL 0x178
|
||||
#define QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4 0x1b4
|
||||
#define QSERDES_V8_PCIE_RX_SIGDET_ENABLES 0x1d8
|
||||
#define QSERDES_V8_PCIE_RX_SIGDET_LVL 0x1e0
|
||||
#define QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL 0x0b8
|
||||
#define QSERDES_V8_PCIE_RX_RX_BAND_CTRL0 0x0bc
|
||||
#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0 0x0c4
|
||||
#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1 0x0c8
|
||||
#define QSERDES_V8_PCIE_RX_SVS_MODE_CTRL 0x0b4
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1 0x058
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2 0x05c
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3 0x084
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3 0x098
|
||||
#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3 0x0ac
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0 0x218
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1 0x21c
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2 0x220
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4 0x228
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7 0x234
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0 0x260
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1 0x264
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2 0x268
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3 0x26c
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4 0x270
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0 0x284
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1 0x288
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2 0x28c
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3 0x290
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4 0x294
|
||||
#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5 0x298
|
||||
#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x31c
|
||||
#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4 0x320
|
||||
#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB 0x11c
|
||||
#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB 0x120
|
||||
#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23 0x108
|
||||
#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4 0x10c
|
||||
#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3 0x198
|
||||
#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4 0x19c
|
||||
#define QSERDES_V8_PCIE_RX_GM_CAL 0x1a0
|
||||
|
||||
#endif
|
||||
68
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h
Normal file
68
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V2_H_
|
||||
#define QCOM_PHY_QMP_QSERDES_TXRX_V2_H_
|
||||
|
||||
/* Only for QMP V2 PHY - TX registers */
|
||||
#define QSERDES_V2_TX_BIST_MODE_LANENO 0x000
|
||||
#define QSERDES_V2_TX_CLKBUF_ENABLE 0x008
|
||||
#define QSERDES_V2_TX_TX_EMP_POST1_LVL 0x00c
|
||||
#define QSERDES_V2_TX_TX_DRV_LVL 0x01c
|
||||
#define QSERDES_V2_TX_RESET_TSYNC_EN 0x024
|
||||
#define QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN 0x028
|
||||
#define QSERDES_V2_TX_TX_BAND 0x02c
|
||||
#define QSERDES_V2_TX_SLEW_CNTL 0x030
|
||||
#define QSERDES_V2_TX_INTERFACE_SELECT 0x034
|
||||
#define QSERDES_V2_TX_RES_CODE_LANE_TX 0x03c
|
||||
#define QSERDES_V2_TX_RES_CODE_LANE_RX 0x040
|
||||
#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX 0x044
|
||||
#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX 0x048
|
||||
#define QSERDES_V2_TX_DEBUG_BUS_SEL 0x058
|
||||
#define QSERDES_V2_TX_TRANSCEIVER_BIAS_EN 0x05c
|
||||
#define QSERDES_V2_TX_HIGHZ_DRVR_EN 0x060
|
||||
#define QSERDES_V2_TX_TX_POL_INV 0x064
|
||||
#define QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN 0x068
|
||||
#define QSERDES_V2_TX_LANE_MODE_1 0x08c
|
||||
#define QSERDES_V2_TX_LANE_MODE_2 0x090
|
||||
#define QSERDES_V2_TX_LANE_MODE_3 0x094
|
||||
#define QSERDES_V2_TX_RCV_DETECT_LVL_2 0x0a4
|
||||
#define QSERDES_V2_TX_TRAN_DRVR_EMP_EN 0x0c0
|
||||
#define QSERDES_V2_TX_TX_INTERFACE_MODE 0x0c4
|
||||
#define QSERDES_V2_TX_VMODE_CTRL1 0x0f0
|
||||
|
||||
/* Only for QMP V2 PHY - RX registers */
|
||||
#define QSERDES_V2_RX_UCDR_FO_GAIN 0x008
|
||||
#define QSERDES_V2_RX_UCDR_SO_GAIN_HALF 0x00c
|
||||
#define QSERDES_V2_RX_UCDR_SO_GAIN 0x014
|
||||
#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_HALF 0x024
|
||||
#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028
|
||||
#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN 0x02c
|
||||
#define QSERDES_V2_RX_UCDR_FASTLOCK_FO_GAIN 0x030
|
||||
#define QSERDES_V2_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034
|
||||
#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c
|
||||
#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040
|
||||
#define QSERDES_V2_RX_UCDR_PI_CONTROLS 0x044
|
||||
#define QSERDES_V2_RX_RX_TERM_BW 0x07c
|
||||
#define QSERDES_V2_RX_VGA_CAL_CNTRL1 0x0bc
|
||||
#define QSERDES_V2_RX_VGA_CAL_CNTRL2 0x0c0
|
||||
#define QSERDES_V2_RX_RX_EQ_GAIN2_LSB 0x0c8
|
||||
#define QSERDES_V2_RX_RX_EQ_GAIN2_MSB 0x0cc
|
||||
#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d0
|
||||
#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4
|
||||
#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8
|
||||
#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc
|
||||
#define QSERDES_V2_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8
|
||||
#define QSERDES_V2_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc
|
||||
#define QSERDES_V2_RX_SIGDET_ENABLES 0x100
|
||||
#define QSERDES_V2_RX_SIGDET_CNTRL 0x104
|
||||
#define QSERDES_V2_RX_SIGDET_LVL 0x108
|
||||
#define QSERDES_V2_RX_SIGDET_DEGLITCH_CNTRL 0x10c
|
||||
#define QSERDES_V2_RX_RX_BAND 0x110
|
||||
#define QSERDES_V2_RX_RX_INTERFACE_MODE 0x11c
|
||||
#define QSERDES_V2_RX_RX_MODE_00 0x164
|
||||
#define QSERDES_V2_RX_RX_MODE_01 0x168
|
||||
|
||||
#endif
|
||||
@@ -84,6 +84,68 @@ 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 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),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl milos_ufsphy_tx[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0xcc),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl milos_ufsphy_rx[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl milos_ufsphy_pcs[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
|
||||
QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
|
||||
@@ -1165,6 +1227,11 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
|
||||
}
|
||||
|
||||
/* Regulator bulk data with load values for specific configurations */
|
||||
static const struct regulator_bulk_data milos_ufsphy_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 140120 },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 18340 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 51400 },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 14600 },
|
||||
@@ -1258,6 +1325,32 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
|
||||
.rx2 = 0x1a00,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg milos_ufsphy_cfg = {
|
||||
.lanes = 2,
|
||||
|
||||
.offsets = &qmp_ufs_offsets_v6,
|
||||
.max_supported_gear = UFS_HS_G4,
|
||||
|
||||
.tbls = {
|
||||
.serdes = milos_ufsphy_serdes,
|
||||
.serdes_num = ARRAY_SIZE(milos_ufsphy_serdes),
|
||||
.tx = milos_ufsphy_tx,
|
||||
.tx_num = ARRAY_SIZE(milos_ufsphy_tx),
|
||||
.rx = milos_ufsphy_rx,
|
||||
.rx_num = ARRAY_SIZE(milos_ufsphy_rx),
|
||||
.pcs = milos_ufsphy_pcs,
|
||||
.pcs_num = ARRAY_SIZE(milos_ufsphy_pcs),
|
||||
},
|
||||
.tbls_hs_b = {
|
||||
.serdes = sm8550_ufsphy_hs_b_serdes,
|
||||
.serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
|
||||
},
|
||||
|
||||
.vreg_list = milos_ufsphy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(milos_ufsphy_vreg_l),
|
||||
.regs = ufsphy_v6_regs_layout,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
|
||||
.lanes = 1,
|
||||
|
||||
@@ -2166,6 +2259,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id qmp_ufs_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,milos-qmp-ufs-phy",
|
||||
.data = &milos_ufsphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,msm8996-qmp-ufs-phy",
|
||||
.data = &msm8996_ufsphy_cfg,
|
||||
}, {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "phy-qcom-qmp-pcs-usb-v5.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v6.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v7.h"
|
||||
#include "phy-qcom-qmp-pcs-usb-v8.h"
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
||||
|
||||
@@ -109,6 +110,139 @@ static const unsigned int qmp_v7_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V7_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb3_uniphy_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x75),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE1, 0x25),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE0, 0x00),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0x75),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE0, 0x25),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_BUF_ENABLE, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADDITIONAL_MISC, 0x0c),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG1, 0xc4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG2, 0x89),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG3, 0x20),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG6, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_REFGEN_REQ_CONFIG1, 0x21),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_RX_SIGDET_LVL, 0x55),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_CDR_RESET_TIME, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG1, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG2, 0x30),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_PCS_TX_RX_CONFIG, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG1, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG5, 0x10),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb3_uniphy_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_TX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_RX, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_1, 0xf5),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_3, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_4, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_5, 0x5f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_RCV_DETECT_LVL_2, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_TX_PI_QEC_CTRL, 0x21),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb3_uniphy_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FO_GAIN, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_GAIN, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_PI_CONTROLS, 0x99),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN2, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_AUX_DATA_TCOARSE_TFINE, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL1, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL2, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_GM_CAL, 0x1b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_LOW, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_ENABLES, 0x0c),
|
||||
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CNTRL, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_LOW, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH3, 0xdf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH4, 0xed),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_LOW, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH2, 0x91),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH3, 0xb7),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH4, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_EN_TIMER, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_DCC_CTRL1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_VTH_CODE, 0x10),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_CTRL1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_TRIM, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_usb_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_WAIT_TIME, 0x75),
|
||||
QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RCVR_DTCT_DLY_U3_L, 0x40),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
|
||||
@@ -1266,7 +1400,7 @@ struct qmp_phy_cfg {
|
||||
int pcs_usb_tbl_num;
|
||||
|
||||
/* regulators to be requested */
|
||||
const char * const *vreg_list;
|
||||
const struct regulator_bulk_data *vreg_list;
|
||||
int num_vregs;
|
||||
|
||||
/* array of registers with different offsets */
|
||||
@@ -1344,8 +1478,9 @@ static const char * const usb3phy_reset_l[] = {
|
||||
};
|
||||
|
||||
/* list of regulators */
|
||||
static const char * const qmp_phy_vreg_l[] = {
|
||||
"vdda-phy", "vdda-pll",
|
||||
static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
|
||||
{ .supply = "vdda-phy", .init_load_uA = 21800, },
|
||||
{ .supply = "vdda-pll", .init_load_uA = 36000, },
|
||||
};
|
||||
|
||||
static const struct qmp_usb_offsets qmp_usb_offsets_v3 = {
|
||||
@@ -1403,6 +1538,14 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = {
|
||||
.rx = 0x1000,
|
||||
};
|
||||
|
||||
static const struct qmp_usb_offsets qmp_usb_offsets_v8 = {
|
||||
.serdes = 0,
|
||||
.pcs = 0x0400,
|
||||
.pcs_usb = 0x1200,
|
||||
.tx = 0x0e00,
|
||||
.rx = 0x1000,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = {
|
||||
.offsets = &qmp_usb_offsets_v3,
|
||||
|
||||
@@ -1704,6 +1847,24 @@ static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = {
|
||||
.regs = qmp_v7_usb3phy_regs_layout,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = {
|
||||
.offsets = &qmp_usb_offsets_v8,
|
||||
|
||||
.serdes_tbl = glymur_usb3_uniphy_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_serdes_tbl),
|
||||
.tx_tbl = glymur_usb3_uniphy_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_tx_tbl),
|
||||
.rx_tbl = glymur_usb3_uniphy_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_rx_tbl),
|
||||
.pcs_tbl = glymur_usb3_uniphy_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_tbl),
|
||||
.pcs_usb_tbl = glymur_usb3_uniphy_pcs_usb_tbl,
|
||||
.pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_usb_tbl),
|
||||
.vreg_list = qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
|
||||
.regs = qmp_v7_usb3phy_regs_layout,
|
||||
};
|
||||
|
||||
static int qmp_usb_serdes_init(struct qmp_usb *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
@@ -1986,23 +2147,6 @@ static const struct dev_pm_ops qmp_usb_pm_ops = {
|
||||
qmp_usb_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static int qmp_usb_vreg_init(struct qmp_usb *qmp)
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
struct device *dev = qmp->dev;
|
||||
int num = cfg->num_vregs;
|
||||
int i;
|
||||
|
||||
qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
|
||||
if (!qmp->vregs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
qmp->vregs[i].supply = cfg->vreg_list[i];
|
||||
|
||||
return devm_regulator_bulk_get(dev, num, qmp->vregs);
|
||||
}
|
||||
|
||||
static int qmp_usb_reset_init(struct qmp_usb *qmp,
|
||||
const char *const *reset_list,
|
||||
int num_resets)
|
||||
@@ -2251,7 +2395,8 @@ static int qmp_usb_probe(struct platform_device *pdev)
|
||||
if (!qmp->cfg)
|
||||
return -EINVAL;
|
||||
|
||||
ret = qmp_usb_vreg_init(qmp);
|
||||
ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs,
|
||||
qmp->cfg->vreg_list, &qmp->vregs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2302,6 +2447,9 @@ static int qmp_usb_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id qmp_usb_of_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,glymur-qmp-usb3-uni-phy",
|
||||
.data = &glymur_usb3_uniphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq5424-qmp-usb3-phy",
|
||||
.data = &ipq9574_usb3phy_cfg,
|
||||
}, {
|
||||
|
||||
33
drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h
Normal file
33
drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_USB43_PCS_V8_H_
|
||||
#define QCOM_PHY_QMP_USB43_PCS_V8_H_
|
||||
|
||||
#define QPHY_V8_USB43_PCS_SW_RESET 0x000
|
||||
#define QPHY_V8_USB43_PCS_PCS_STATUS1 0x014
|
||||
#define QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL 0x040
|
||||
#define QPHY_V8_USB43_PCS_START_CONTROL 0x044
|
||||
#define QPHY_V8_USB43_PCS_POWER_STATE_CONFIG1 0x090
|
||||
#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1 0x0c4
|
||||
#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2 0x0c8
|
||||
#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3 0x0cc
|
||||
#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6 0x0d8
|
||||
#define QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1 0x0dc
|
||||
#define QPHY_V8_USB43_PCS_RX_SIGDET_LVL 0x188
|
||||
#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
|
||||
#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
|
||||
#define QPHY_V8_USB43_PCS_RATE_SLEW_CNTRL1 0x198
|
||||
#define QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME 0x1ac
|
||||
#define QPHY_V8_USB43_PCS_RX_CONFIG 0x1b0
|
||||
#define QPHY_V8_USB43_PCS_TSYNC_DLY_TIME 0x1b4
|
||||
#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1 0x1c0
|
||||
#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2 0x1c4
|
||||
#define QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG 0x1d0
|
||||
#define QPHY_V8_USB43_PCS_EQ_CONFIG1 0x1dc
|
||||
#define QPHY_V8_USB43_PCS_EQ_CONFIG2 0x1e0
|
||||
#define QPHY_V8_USB43_PCS_EQ_CONFIG5 0x1ec
|
||||
|
||||
#endif
|
||||
224
drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h
Normal file
224
drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_
|
||||
#define QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_
|
||||
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1 0x000
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1 0x004
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE1 0x008
|
||||
#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE1 0x00c
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_MODE1 0x010
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1 0x014
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1 0x018
|
||||
#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1 0x01c
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1 0x020
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1 0x024
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MODE1 0x028
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1 0x02c
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1 0x030
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1 0x034
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1 0x038
|
||||
#define QSERDES_V8_USB43_COM_HSCLK_SEL_1 0x03c
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1 0x040
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE1 0x044
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1 0x048
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1 0x04c
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x050
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x054
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0 0x060
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0 0x064
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE0 0x068
|
||||
#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE0 0x06c
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_MODE0 0x070
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0 0x074
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0 0x078
|
||||
#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0 0x07c
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0 0x080
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0 0x084
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MODE0 0x088
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0 0x08c
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0 0x090
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0 0x094
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0 0x098
|
||||
#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1 0x09c
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0 0x0a0
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0 0x0a4
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0 0x0a8
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0 0x0ac
|
||||
#define QSERDES_V8_USB43_COM_ATB_SEL1 0x0b0
|
||||
#define QSERDES_V8_USB43_COM_ATB_SEL2 0x0b4
|
||||
#define QSERDES_V8_USB43_COM_FREQ_UPDATE 0x0b8
|
||||
#define QSERDES_V8_USB43_COM_BG_TIMER 0x0bc
|
||||
#define QSERDES_V8_USB43_COM_SSC_EN_CENTER 0x0c0
|
||||
#define QSERDES_V8_USB43_COM_SSC_ADJ_PER1 0x0c4
|
||||
#define QSERDES_V8_USB43_COM_SSC_ADJ_PER2 0x0c8
|
||||
#define QSERDES_V8_USB43_COM_SSC_PER1 0x0cc
|
||||
#define QSERDES_V8_USB43_COM_SSC_PER2 0x0d0
|
||||
#define QSERDES_V8_USB43_COM_POST_DIV 0x0d4
|
||||
#define QSERDES_V8_USB43_COM_POST_DIV_MUX 0x0d8
|
||||
#define QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN 0x0dc
|
||||
#define QSERDES_V8_USB43_COM_CLK_ENABLE1 0x0e0
|
||||
#define QSERDES_V8_USB43_COM_SYS_CLK_CTRL 0x0e4
|
||||
#define QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE 0x0e8
|
||||
#define QSERDES_V8_USB43_COM_PLL_EN 0x0ec
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS_OVRD 0x0f0
|
||||
#define QSERDES_V8_USB43_COM_PLL_IVCO 0x0f4
|
||||
#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE1 0x0f8
|
||||
#define QSERDES_V8_USB43_COM_CMN_IETRIM 0x0fc
|
||||
#define QSERDES_V8_USB43_COM_CMN_IPTRIM 0x100
|
||||
#define QSERDES_V8_USB43_COM_EP_CLOCK_DETECT_CTRL 0x104
|
||||
#define QSERDES_V8_USB43_COM_PLL_CNTRL 0x108
|
||||
#define QSERDES_V8_USB43_COM_BIAS_EN_CTRL_BY_PSM 0x10c
|
||||
#define QSERDES_V8_USB43_COM_SYSCLK_EN_SEL 0x110
|
||||
#define QSERDES_V8_USB43_COM_CML_SYSCLK_SEL 0x114
|
||||
#define QSERDES_V8_USB43_COM_RESETSM_CNTRL 0x118
|
||||
#define QSERDES_V8_USB43_COM_RESETSM_CNTRL2 0x11c
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP_EN 0x120
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP_CFG 0x124
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_INITVAL 0x128
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_EN 0x12c
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN0 0x130
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN1 0x134
|
||||
#define QSERDES_V8_USB43_COM_VCOCAL_DEADMAN_CTRL 0x138
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_CTRL 0x13c
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_MAP 0x140
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL1 0x144
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL2 0x148
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL1 0x14c
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL2 0x150
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL1 0x154
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL2 0x158
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER1 0x15c
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER2 0x160
|
||||
#define QSERDES_V8_USB43_COM_CLK_SELECT 0x164
|
||||
#define QSERDES_V8_USB43_COM_PLL_ANALOG 0x168
|
||||
#define QSERDES_V8_USB43_COM_SW_RESET 0x16c
|
||||
#define QSERDES_V8_USB43_COM_CORE_CLK_EN 0x170
|
||||
#define QSERDES_V8_USB43_COM_CMN_CONFIG_1 0x174
|
||||
#define QSERDES_V8_USB43_COM_CMN_CONFIG_3 0x178
|
||||
#define QSERDES_V8_USB43_COM_CMN_RATE_OVERRIDE 0x17c
|
||||
#define QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL 0x180
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS_SEL 0x184
|
||||
#define QSERDES_V8_USB43_COM_CMN_MISC1 0x188
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE 0x18c
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD 0x190
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD1 0x194
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD2 0x198
|
||||
#define QSERDES_V8_USB43_COM_VCO_DC_LEVEL_CTRL 0x19c
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1 0x1a0
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_CTRL_1 0x1a4
|
||||
#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a8
|
||||
#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_2 0x1ac
|
||||
#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_3 0x1b0
|
||||
#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_4 0x1b4
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC 0x1b8
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_2 0x1bc
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_3 0x1c0
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_4 0x1c4
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_5 0x1c8
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE2 0x1cc
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE2 0x1d0
|
||||
#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE2 0x1d4
|
||||
#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE2 0x1d8
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_MODE2 0x1dc
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE2 0x1e0
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE2 0x1e4
|
||||
#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE2 0x1e8
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE2 0x1ec
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE2 0x1f0
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MODE2 0x1f4
|
||||
#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE2 0x1f8
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE2 0x1fc
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE2 0x200
|
||||
#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE2 0x204
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE2 0x208
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE2 0x20c
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE2 0x210
|
||||
#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE2 0x214
|
||||
#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE2 0x218
|
||||
#define QSERDES_V8_USB43_COM_HSCLK_SEL_2 0x21c
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE2 0x220
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE2 0x224
|
||||
#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_2 0x228
|
||||
#define QSERDES_V8_USB43_COM_CMN_CONFIG_2 0x22c
|
||||
#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_2 0x230
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_0 0x234
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_1 0x238
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_2 0x23c
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_3 0x240
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_4 0x244
|
||||
#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_5 0x248
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE0 0x24c
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE0 0x250
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE1 0x254
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE1 0x258
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE2 0x25c
|
||||
#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE2 0x260
|
||||
#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_0 0x264
|
||||
#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_1 0x268
|
||||
#define QSERDES_V8_USB43_COM_ADAPTIVE_ANALOG_CONFIG 0x26c
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE0 0x270
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x274
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x278
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE1 0x27c
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x280
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x284
|
||||
#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE2 0x288
|
||||
#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE2 0x28c
|
||||
#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE2 0x290
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD3 0x294
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD4 0x298
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD5 0x29c
|
||||
#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD6 0x2a0
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_6 0x2a4
|
||||
#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_7 0x2a8
|
||||
#define QSERDES_V8_USB43_COM_VCO_WAIT_CYCLES 0x2ac
|
||||
#define QSERDES_V8_USB43_COM_BIAS_WAIT_CYCLES 0x2b0
|
||||
#define QSERDES_V8_USB43_COM_AUX_CLK_PSM_ENABLE 0x2b4
|
||||
#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO 0x2b8
|
||||
#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_1 0x2bc
|
||||
#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_2 0x2c0
|
||||
#define QSERDES_V8_USB43_COM_LDO_CAL_1 0x2c4
|
||||
#define QSERDES_V8_USB43_COM_LDO_CAL_2 0x2c8
|
||||
#define QSERDES_V8_USB43_COM_LDO_CAL_3 0x2cc
|
||||
#define QSERDES_V8_USB43_COM_LDO_CAL_4 0x2d0
|
||||
#define QSERDES_V8_USB43_COM_LDO_CAL_5 0x2d4
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_1 0x2d8
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_2 0x2dc
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_3 0x2e0
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_4 0x2e4
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_5 0x2e8
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_6 0x2ec
|
||||
#define QSERDES_V8_USB43_COM_PSM_CAL_EN 0x2f0
|
||||
#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1 0x2f4
|
||||
#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_2 0x2f8
|
||||
#define QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL 0x2fc
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_7 0x300
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_8 0x304
|
||||
#define QSERDES_V8_USB43_COM_DCC_CAL_9 0x308
|
||||
#define QSERDES_V8_USB43_COM_MODE_OPERATION_STATUS 0x30c
|
||||
#define QSERDES_V8_USB43_COM_SYSCLK_DET_COMP_STATUS 0x310
|
||||
#define QSERDES_V8_USB43_COM_CMN_STATUS 0x314
|
||||
#define QSERDES_V8_USB43_COM_RESET_SM_STATUS 0x318
|
||||
#define QSERDES_V8_USB43_COM_RESTRIM_CODE_STATUS 0x31c
|
||||
#define QSERDES_V8_USB43_COM_PLLCAL_CODE1_STATUS 0x320
|
||||
#define QSERDES_V8_USB43_COM_PLLCAL_CODE2_STATUS 0x324
|
||||
#define QSERDES_V8_USB43_COM_INTEGLOOP_BINCODE_STATUS 0x328
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS0 0x32c
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS1 0x330
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS2 0x334
|
||||
#define QSERDES_V8_USB43_COM_DEBUG_BUS3 0x338
|
||||
#define QSERDES_V8_USB43_COM_C_READY_STATUS 0x33c
|
||||
#define QSERDES_V8_USB43_COM_READ_DUMMY_1 0x340
|
||||
#define QSERDES_V8_USB43_COM_READ_DUMMY_2 0x344
|
||||
#define QSERDES_V8_USB43_COM_READ_DUMMY_3 0x348
|
||||
#define QSERDES_V8_USB43_COM_IVCO_CAL_CODE_STATUS 0x34c
|
||||
#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_2 0x350
|
||||
#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_3 0x354
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,9 @@
|
||||
#include "phy-qcom-qmp-qserdes-com.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-com-v2.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v2.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-com-v3.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v3.h"
|
||||
|
||||
@@ -32,7 +35,9 @@
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v7.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-com-v8.h"
|
||||
#include "phy-qcom-qmp-usb43-qserdes-com-v8.h"
|
||||
#include "phy-qcom-qmp-qserdes-txrx-v8.h"
|
||||
#include "phy-qcom-qmp-qserdes-lalb-v8.h"
|
||||
|
||||
#include "phy-qcom-qmp-qserdes-pll.h"
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ config PHY_RCAR_GEN3_USB2
|
||||
depends on ARCH_RENESAS
|
||||
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
|
||||
depends on USB_SUPPORT
|
||||
depends on REGULATOR
|
||||
select GENERIC_PHY
|
||||
select MULTIPLEXER
|
||||
select USB_COMMON
|
||||
help
|
||||
Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
|
||||
|
||||
@@ -85,7 +85,7 @@ static int rcar_gen2_phy_init(struct phy *p)
|
||||
* Try to acquire exclusive access to PHY. The first driver calling
|
||||
* phy_init() on a given channel wins, and all attempts to use another
|
||||
* PHY on this channel will fail until phy_exit() is called by the first
|
||||
* driver. Achieving this with cmpxcgh() should be SMP-safe.
|
||||
* driver. Achieving this with cmpxchg() should be SMP-safe.
|
||||
*/
|
||||
if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1)
|
||||
return -EBUSY;
|
||||
@@ -337,7 +337,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rcar_gen2_phy_driver *drv;
|
||||
struct phy_provider *provider;
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
const struct rcar_gen2_phy_data *data;
|
||||
@@ -379,7 +378,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
if (!drv->channels)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_child_of_node(dev->of_node, np) {
|
||||
for_each_child_of_node_scoped(dev->of_node, np) {
|
||||
struct rcar_gen2_channel *channel = drv->channels + i;
|
||||
u32 channel_num;
|
||||
int error, n;
|
||||
@@ -391,7 +390,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
error = of_property_read_u32(np, "reg", &channel_num);
|
||||
if (error || channel_num >= data->num_channels) {
|
||||
dev_err(dev, "Invalid \"reg\" property\n");
|
||||
of_node_put(np);
|
||||
return error;
|
||||
}
|
||||
channel->select_mask = select_mask[channel_num];
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mux/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/usb/of.h>
|
||||
@@ -141,6 +143,7 @@ struct rcar_gen3_chan {
|
||||
bool extcon_host;
|
||||
bool is_otg_channel;
|
||||
bool uses_otg_pins;
|
||||
bool otg_internal_reg;
|
||||
};
|
||||
|
||||
struct rcar_gen3_phy_drv_data {
|
||||
@@ -204,28 +207,43 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
|
||||
writel(val, usb2_base + USB2_LINECTRL1);
|
||||
}
|
||||
|
||||
static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
|
||||
static void rcar_gen3_phy_usb2_set_vbus(struct rcar_gen3_chan *ch,
|
||||
u32 vbus_ctrl_reg,
|
||||
u32 vbus_ctrl_val,
|
||||
bool enable)
|
||||
{
|
||||
void __iomem *usb2_base = ch->base;
|
||||
u32 vbus_ctrl_reg = USB2_ADPCTRL;
|
||||
u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS;
|
||||
u32 val;
|
||||
|
||||
val = readl(usb2_base + vbus_ctrl_reg);
|
||||
if (enable)
|
||||
val |= vbus_ctrl_val;
|
||||
else
|
||||
val &= ~vbus_ctrl_val;
|
||||
writel(val, usb2_base + vbus_ctrl_reg);
|
||||
|
||||
dev_vdbg(ch->dev, "%s: reg=0x%08x, val=%08x, enable=%d\n",
|
||||
__func__, vbus_ctrl_reg, val, enable);
|
||||
}
|
||||
|
||||
static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
|
||||
{
|
||||
if (ch->otg_internal_reg) {
|
||||
regulator_hardware_enable(ch->vbus, vbus);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) {
|
||||
if (ch->vbus)
|
||||
regulator_hardware_enable(ch->vbus, vbus);
|
||||
|
||||
vbus_ctrl_reg = USB2_VBCTRL;
|
||||
vbus_ctrl_val = USB2_VBCTRL_VBOUT;
|
||||
rcar_gen3_phy_usb2_set_vbus(ch, USB2_VBCTRL,
|
||||
USB2_VBCTRL_VBOUT, vbus);
|
||||
return;
|
||||
}
|
||||
|
||||
val = readl(usb2_base + vbus_ctrl_reg);
|
||||
if (vbus)
|
||||
val |= vbus_ctrl_val;
|
||||
else
|
||||
val &= ~vbus_ctrl_val;
|
||||
dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
|
||||
writel(val, usb2_base + vbus_ctrl_reg);
|
||||
rcar_gen3_phy_usb2_set_vbus(ch, USB2_ADPCTRL,
|
||||
USB2_ADPCTRL_DRVVBUS, vbus);
|
||||
}
|
||||
|
||||
static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
|
||||
@@ -583,7 +601,7 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
|
||||
if (channel->vbus) {
|
||||
if (channel->vbus && !channel->otg_internal_reg) {
|
||||
ret = regulator_enable(channel->vbus);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -624,7 +642,7 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
|
||||
}
|
||||
}
|
||||
|
||||
if (channel->vbus)
|
||||
if (channel->vbus && !channel->otg_internal_reg)
|
||||
ret = regulator_disable(channel->vbus);
|
||||
|
||||
return ret;
|
||||
@@ -799,11 +817,149 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_regulator_endisable(struct regulator_dev *rdev,
|
||||
bool enable)
|
||||
{
|
||||
struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev);
|
||||
struct device *dev = channel->dev;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "pm_runtime_get failed: %i\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rcar_gen3_phy_usb2_set_vbus(channel, USB2_VBCTRL,
|
||||
USB2_VBCTRL_VBOUT, enable);
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
return rcar_gen3_phy_usb2_regulator_endisable(rdev, true);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
return rcar_gen3_phy_usb2_regulator_endisable(rdev, false);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev);
|
||||
void __iomem *usb2_base = channel->base;
|
||||
struct device *dev = channel->dev;
|
||||
u32 vbus_ctrl_reg = USB2_VBCTRL;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "pm_runtime_get failed: %i\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl(usb2_base + vbus_ctrl_reg);
|
||||
|
||||
pm_runtime_put_noidle(dev);
|
||||
dev_dbg(channel->dev, "%s: %08x\n", __func__, val);
|
||||
|
||||
return (val & USB2_VBCTRL_VBOUT) ? 1 : 0;
|
||||
}
|
||||
|
||||
static const struct regulator_ops rcar_gen3_phy_usb2_regulator_ops = {
|
||||
.enable = rcar_gen3_phy_usb2_regulator_enable,
|
||||
.disable = rcar_gen3_phy_usb2_regulator_disable,
|
||||
.is_enabled = rcar_gen3_phy_usb2_regulator_is_enabled,
|
||||
};
|
||||
|
||||
static const struct regulator_desc rcar_gen3_phy_usb2_regulator = {
|
||||
.name = "otg-vbus-regulator",
|
||||
.of_match = of_match_ptr("vbus-regulator"),
|
||||
.ops = &rcar_gen3_phy_usb2_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.fixed_uV = 5000000,
|
||||
.n_voltages = 1,
|
||||
};
|
||||
|
||||
static void rcar_gen3_phy_usb2_vbus_disable_action(void *data)
|
||||
{
|
||||
struct regulator *vbus = data;
|
||||
|
||||
regulator_disable(vbus);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_gen3_chan *channel,
|
||||
bool enable)
|
||||
{
|
||||
struct device *dev = channel->dev;
|
||||
int ret;
|
||||
|
||||
channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
|
||||
if (IS_ERR(channel->vbus))
|
||||
return PTR_ERR(channel->vbus);
|
||||
|
||||
if (!enable)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel)
|
||||
{
|
||||
struct device *dev = channel->dev;
|
||||
struct regulator_config rcfg = { .dev = dev, };
|
||||
struct regulator_dev *rdev;
|
||||
bool enable = false;
|
||||
|
||||
rcfg.of_node = of_get_available_child_by_name(dev->of_node,
|
||||
"vbus-regulator");
|
||||
if (rcfg.of_node) {
|
||||
rcfg.driver_data = channel;
|
||||
rdev = devm_regulator_register(dev, &rcar_gen3_phy_usb2_regulator,
|
||||
&rcfg);
|
||||
of_node_put(rcfg.of_node);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(dev, PTR_ERR(rdev),
|
||||
"Failed to create vbus-regulator\n");
|
||||
|
||||
channel->otg_internal_reg = true;
|
||||
enable = true;
|
||||
}
|
||||
|
||||
return rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(channel, enable);
|
||||
}
|
||||
|
||||
/* Temporary wrapper until the multiplexer subsystem supports optional muxes */
|
||||
static inline struct mux_state *
|
||||
devm_mux_state_get_optional(struct device *dev, const char *mux_name)
|
||||
{
|
||||
if (!of_property_present(dev->of_node, "mux-states"))
|
||||
return NULL;
|
||||
|
||||
return devm_mux_state_get(dev, mux_name);
|
||||
}
|
||||
|
||||
static void rcar_gen3_phy_mux_state_deselect(void *data)
|
||||
{
|
||||
mux_state_deselect(data);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rcar_gen3_chan *channel;
|
||||
struct phy_provider *provider;
|
||||
struct mux_state *mux_state;
|
||||
int ret = 0, i, irq;
|
||||
|
||||
if (!dev->of_node) {
|
||||
@@ -852,78 +1008,87 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
* devm_phy_create() will call pm_runtime_enable(&phy->dev);
|
||||
* And then, phy-core will manage runtime pm for this device.
|
||||
*/
|
||||
pm_runtime_enable(dev);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n");
|
||||
|
||||
channel->phy_data = of_device_get_match_data(dev);
|
||||
if (!channel->phy_data) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
if (!channel->phy_data)
|
||||
return -EINVAL;
|
||||
|
||||
platform_set_drvdata(pdev, channel);
|
||||
channel->dev = dev;
|
||||
|
||||
ret = rcar_gen3_phy_usb2_init_bus(channel);
|
||||
if (ret)
|
||||
goto error;
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&channel->lock);
|
||||
for (i = 0; i < NUM_OF_PHYS; i++) {
|
||||
channel->rphys[i].phy = devm_phy_create(dev, NULL,
|
||||
channel->phy_data->phy_usb2_ops);
|
||||
if (IS_ERR(channel->rphys[i].phy)) {
|
||||
dev_err(dev, "Failed to create USB2 PHY\n");
|
||||
ret = PTR_ERR(channel->rphys[i].phy);
|
||||
goto error;
|
||||
}
|
||||
if (IS_ERR(channel->rphys[i].phy))
|
||||
return dev_err_probe(dev, PTR_ERR(channel->rphys[i].phy),
|
||||
"Failed to create USB2 PHY\n");
|
||||
|
||||
channel->rphys[i].ch = channel;
|
||||
channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i];
|
||||
phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]);
|
||||
}
|
||||
|
||||
if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel)
|
||||
channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
|
||||
else
|
||||
mux_state = devm_mux_state_get_optional(dev, NULL);
|
||||
if (IS_ERR(mux_state))
|
||||
return PTR_ERR(mux_state);
|
||||
if (mux_state) {
|
||||
ret = mux_state_select(mux_state);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to select USB mux\n");
|
||||
|
||||
ret = devm_add_action_or_reset(dev, rcar_gen3_phy_mux_state_deselect,
|
||||
mux_state);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register USB mux state deselect\n");
|
||||
}
|
||||
|
||||
if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) {
|
||||
ret = rcar_gen3_phy_usb2_vbus_regulator_register(channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
channel->vbus = devm_regulator_get_optional(dev, "vbus");
|
||||
}
|
||||
if (IS_ERR(channel->vbus)) {
|
||||
if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) {
|
||||
ret = PTR_ERR(channel->vbus);
|
||||
goto error;
|
||||
}
|
||||
if (PTR_ERR(channel->vbus) == -EPROBE_DEFER)
|
||||
return PTR_ERR(channel->vbus);
|
||||
|
||||
channel->vbus = NULL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq_optional(pdev, 0);
|
||||
if (irq < 0 && irq != -ENXIO) {
|
||||
ret = irq;
|
||||
goto error;
|
||||
return irq;
|
||||
} else if (irq > 0) {
|
||||
INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
|
||||
ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
|
||||
IRQF_SHARED, dev_name(dev), channel);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to request irq (%d)\n", irq);
|
||||
goto error;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to request irq (%d)\n",
|
||||
irq);
|
||||
}
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "Failed to register PHY provider\n");
|
||||
ret = PTR_ERR(provider);
|
||||
goto error;
|
||||
return dev_err_probe(dev, PTR_ERR(provider),
|
||||
"Failed to register PHY provider\n");
|
||||
} else if (channel->is_otg_channel) {
|
||||
ret = device_create_file(dev, &dev_attr_role);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
|
||||
@@ -932,8 +1097,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
|
||||
|
||||
if (channel->is_otg_channel)
|
||||
device_remove_file(&pdev->dev, &dev_attr_role);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_suspend(struct device *dev)
|
||||
|
||||
@@ -749,22 +749,23 @@ unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw,
|
||||
return vco;
|
||||
}
|
||||
|
||||
static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static int inno_hdmi_phy_rk3228_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
const struct pre_pll_config *cfg = pre_pll_cfg_table;
|
||||
|
||||
rate = (rate / 1000) * 1000;
|
||||
req->rate = (req->rate / 1000) * 1000;
|
||||
|
||||
for (; cfg->pixclock != 0; cfg++)
|
||||
if (cfg->pixclock == rate && !cfg->fracdiv)
|
||||
if (cfg->pixclock == req->rate && !cfg->fracdiv)
|
||||
break;
|
||||
|
||||
if (cfg->pixclock == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return cfg->pixclock;
|
||||
req->rate = cfg->pixclock;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
|
||||
@@ -835,7 +836,7 @@ static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops = {
|
||||
.unprepare = inno_hdmi_phy_rk3228_clk_unprepare,
|
||||
.is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared,
|
||||
.recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate,
|
||||
.round_rate = inno_hdmi_phy_rk3228_clk_round_rate,
|
||||
.determine_rate = inno_hdmi_phy_rk3228_clk_determine_rate,
|
||||
.set_rate = inno_hdmi_phy_rk3228_clk_set_rate,
|
||||
};
|
||||
|
||||
@@ -906,22 +907,23 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
|
||||
return inno->pixclock;
|
||||
}
|
||||
|
||||
static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static int inno_hdmi_phy_rk3328_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
const struct pre_pll_config *cfg = pre_pll_cfg_table;
|
||||
|
||||
rate = (rate / 1000) * 1000;
|
||||
req->rate = (req->rate / 1000) * 1000;
|
||||
|
||||
for (; cfg->pixclock != 0; cfg++)
|
||||
if (cfg->pixclock == rate)
|
||||
if (cfg->pixclock == req->rate)
|
||||
break;
|
||||
|
||||
if (cfg->pixclock == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return cfg->pixclock;
|
||||
req->rate = cfg->pixclock;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
|
||||
@@ -989,7 +991,7 @@ static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops = {
|
||||
.unprepare = inno_hdmi_phy_rk3328_clk_unprepare,
|
||||
.is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared,
|
||||
.recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate,
|
||||
.round_rate = inno_hdmi_phy_rk3328_clk_round_rate,
|
||||
.determine_rate = inno_hdmi_phy_rk3328_clk_determine_rate,
|
||||
.set_rate = inno_hdmi_phy_rk3328_clk_set_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -529,7 +529,7 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) {
|
||||
if (priv->ext_refclk) {
|
||||
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
|
||||
|
||||
if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
|
||||
@@ -554,11 +554,9 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->type == PHY_TYPE_PCIE) {
|
||||
if (device_property_read_bool(priv->dev, "rockchip,enable-ssc"))
|
||||
rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN,
|
||||
RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40);
|
||||
}
|
||||
if (priv->type == PHY_TYPE_PCIE && priv->enable_ssc)
|
||||
rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN,
|
||||
RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -582,7 +580,7 @@ static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = {
|
||||
.con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x101 },
|
||||
.con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
|
||||
/* pipe-grf */
|
||||
.u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 },
|
||||
.u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 },
|
||||
};
|
||||
|
||||
static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = {
|
||||
|
||||
@@ -1508,7 +1508,9 @@ static int samsung_mipi_dcphy_exit(struct phy *phy)
|
||||
{
|
||||
struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy);
|
||||
|
||||
return pm_runtime_put(samsung->dev);
|
||||
pm_runtime_put(samsung->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops samsung_mipi_dcphy_ops = {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -446,7 +446,6 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rockchip_usb_phy_base *phy_base;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device_node *child;
|
||||
int err;
|
||||
|
||||
phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL);
|
||||
@@ -472,12 +471,10 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(phy_base->reg_base);
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(dev->of_node, child) {
|
||||
for_each_available_child_of_node_scoped(dev->of_node, child) {
|
||||
err = rockchip_usb_phy_init(phy_base, child);
|
||||
if (err) {
|
||||
of_node_put(child);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
@@ -41,6 +41,13 @@
|
||||
#define EXYNOS2200_CLKRST_LINK_PCLK_SEL BIT(1)
|
||||
|
||||
#define EXYNOS2200_DRD_UTMI 0x10
|
||||
|
||||
/* ExynosAutov920 bits */
|
||||
#define UTMICTL_FORCE_UTMI_SUSPEND BIT(13)
|
||||
#define UTMICTL_FORCE_UTMI_SLEEP BIT(12)
|
||||
#define UTMICTL_FORCE_DPPULLDOWN BIT(9)
|
||||
#define UTMICTL_FORCE_DMPULLDOWN BIT(8)
|
||||
|
||||
#define EXYNOS2200_UTMI_FORCE_VBUSVALID BIT(1)
|
||||
#define EXYNOS2200_UTMI_FORCE_BVALID BIT(0)
|
||||
|
||||
@@ -250,6 +257,52 @@
|
||||
#define EXYNOS850_DRD_HSP_TEST 0x5c
|
||||
#define HSP_TEST_SIDDQ BIT(24)
|
||||
|
||||
#define EXYNOSAUTOV920_DRD_HSP_CLKRST 0x100
|
||||
#define HSPCLKRST_PHY20_SW_PORTRESET BIT(3)
|
||||
#define HSPCLKRST_PHY20_SW_POR BIT(1)
|
||||
#define HSPCLKRST_PHY20_SW_POR_SEL BIT(0)
|
||||
|
||||
#define EXYNOSAUTOV920_DRD_HSPCTL 0x104
|
||||
#define HSPCTRL_VBUSVLDEXTSEL BIT(13)
|
||||
#define HSPCTRL_VBUSVLDEXT BIT(12)
|
||||
#define HSPCTRL_EN_UTMISUSPEND BIT(9)
|
||||
#define HSPCTRL_COMMONONN BIT(8)
|
||||
|
||||
#define EXYNOSAUTOV920_DRD_HSP_TEST 0x10c
|
||||
|
||||
#define EXYNOSAUTOV920_DRD_HSPPLLTUNE 0x110
|
||||
#define HSPPLLTUNE_FSEL GENMASK(18, 16)
|
||||
|
||||
/* ExynosAutov920 phy usb31drd port reg */
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL 0x000
|
||||
#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN BIT(5)
|
||||
#define PHY_RST_CTRL_PIPE_LANE0_RESET_N BIT(4)
|
||||
#define PHY_RST_CTRL_PHY_RESET_OVRD_EN BIT(1)
|
||||
#define PHY_RST_CTRL_PHY_RESET BIT(0)
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0 0x0004
|
||||
#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR GENMASK(31, 16)
|
||||
#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK BIT(8)
|
||||
#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK BIT(4)
|
||||
#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL BIT(0)
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1 0x0008
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2 0x000c
|
||||
#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN BIT(0)
|
||||
#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA GENMASK(31, 16)
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0 0x100
|
||||
#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE BIT(14)
|
||||
#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE BIT(13)
|
||||
#define PHY_CONFIG0_PHY0_ANA_PWR_EN BIT(1)
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7 0x11c
|
||||
#define PHY_CONFIG7_PHY_TEST_POWERDOWN BIT(24)
|
||||
|
||||
#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4 0x110
|
||||
#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN BIT(2)
|
||||
|
||||
/* Exynos9 - GS101 */
|
||||
#define EXYNOS850_DRD_SECPMACTL 0x48
|
||||
#define SECPMACTL_PMA_ROPLL_REF_CLK_SEL GENMASK(13, 12)
|
||||
@@ -2054,6 +2107,595 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
|
||||
.n_regulators = ARRAY_SIZE(exynos5_regulator_names),
|
||||
};
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
if (high)
|
||||
reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
|
||||
else
|
||||
reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
|
||||
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
fsleep(1);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
struct device *dev = phy_drd->dev;
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
static const unsigned int timeout_us = 20000;
|
||||
static const unsigned int sleep_us = 40;
|
||||
u32 reg;
|
||||
int err;
|
||||
|
||||
/* Clear cr_para_con */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
|
||||
PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
|
||||
reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
|
||||
writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
|
||||
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, true);
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, false);
|
||||
|
||||
/*
|
||||
* The maximum time from phy reset de-assertion to de-assertion of
|
||||
* tx/rx_ack can be as high as 5ms in fast simulation mode.
|
||||
* Time to phy ready is < 20ms
|
||||
*/
|
||||
err = readl_poll_timeout(reg_phy +
|
||||
EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
|
||||
reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
|
||||
sleep_us, timeout_us);
|
||||
if (err)
|
||||
dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
|
||||
|
||||
reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
|
||||
u16 addr, u16 data)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 cnt = 0;
|
||||
u32 reg;
|
||||
|
||||
/* Pre Clocking */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
|
||||
/*
|
||||
* tx clks must be available prior to assertion of tx req.
|
||||
* tx pstate p2 to p0 transition directly is not permitted.
|
||||
* tx clk ready must be asserted synchronously on tx clk prior
|
||||
* to internal transmit clk alignment sequence in the phy
|
||||
* when entering from p2 to p1 to p0.
|
||||
*/
|
||||
do {
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, true);
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, false);
|
||||
cnt++;
|
||||
} while (cnt < 15);
|
||||
|
||||
reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
|
||||
/*
|
||||
* tx data path is active when tx lane is in p0 state
|
||||
* and tx data en asserted. enable cr_para_wr_en.
|
||||
*/
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
|
||||
reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
|
||||
reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
|
||||
PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
|
||||
|
||||
/* write addr */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
|
||||
reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
|
||||
PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
|
||||
PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
|
||||
/* check cr_para_ack*/
|
||||
cnt = 0;
|
||||
do {
|
||||
/*
|
||||
* data symbols are captured by phy on rising edge of the
|
||||
* tx_clk when tx data enabled.
|
||||
* completion of the write cycle is acknowledged by assertion
|
||||
* of the cr_para_ack.
|
||||
*/
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, true);
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
|
||||
if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
|
||||
break;
|
||||
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, false);
|
||||
|
||||
/*
|
||||
* wait for minimum of 10 cr_para_clk cycles after phy reset
|
||||
* is negated, before accessing control regs to allow for
|
||||
* internal resets.
|
||||
*/
|
||||
cnt++;
|
||||
} while (cnt < 10);
|
||||
|
||||
if (cnt < 10)
|
||||
exynosautov920_usb31drd_cr_clk(phy_drd, false);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
if (val)
|
||||
reg |= PHY_RST_CTRL_PHY_RESET;
|
||||
else
|
||||
reg &= ~PHY_RST_CTRL_PHY_RESET;
|
||||
|
||||
reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
if (val)
|
||||
reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N;
|
||||
else
|
||||
reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N;
|
||||
|
||||
reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Phy and Pipe Lane reset assert.
|
||||
* assert reset (phy_reset = 1).
|
||||
* The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1)
|
||||
*/
|
||||
exynosautov920_usb31drd_phy_reset(phy_drd, 1);
|
||||
exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
|
||||
|
||||
/*
|
||||
* ANA Power En, PCS & PMA PWR Stable Set
|
||||
* ramp-up power suppiles
|
||||
*/
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
|
||||
reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE |
|
||||
PHY_CONFIG0_PHY0_PMA_PWR_STABLE;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
|
||||
|
||||
fsleep(10);
|
||||
|
||||
/*
|
||||
* phy is not functional in test_powerdown mode, test_powerdown to be
|
||||
* de-asserted for normal operation
|
||||
*/
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
|
||||
reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
|
||||
|
||||
/*
|
||||
* phy reset signal be asserted for minimum 10us after power
|
||||
* supplies are ramped-up
|
||||
*/
|
||||
fsleep(10);
|
||||
|
||||
/*
|
||||
* Phy and Pipe Lane reset assert de-assert
|
||||
*/
|
||||
exynosautov920_usb31drd_phy_reset(phy_drd, 0);
|
||||
exynosautov920_usb31drd_lane0_reset(phy_drd, 0);
|
||||
|
||||
/* Pipe_rx0_sris_mode_en = 1 */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
|
||||
reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
|
||||
|
||||
/*
|
||||
* wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0)
|
||||
* Exit from the reset state is indicated by de-assertion of *_ack
|
||||
*/
|
||||
exynosautov920_usb31drd_port_phy_ready(phy_drd);
|
||||
|
||||
/* override values for level settings */
|
||||
exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
/* 1. Assert reset (phy_reset = 1) */
|
||||
exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
|
||||
exynosautov920_usb31drd_phy_reset(phy_drd, 1);
|
||||
|
||||
/* phy test power down */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
|
||||
reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Disable HWACG (hardware auto clock gating control). This
|
||||
* forces QACTIVE signal in Q-Channel interface to HIGH level,
|
||||
* to make sure the PHY clock is not gated by the hardware.
|
||||
*/
|
||||
reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
reg |= LINKCTRL_FORCE_QACT;
|
||||
writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
|
||||
/* De-assert link reset */
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
reg &= ~CLKRST_LINK_SW_RST;
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
|
||||
/* Set PHY POR High */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
|
||||
reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
|
||||
|
||||
/* Enable UTMI+ */
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP |
|
||||
UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
|
||||
/* set phy clock & control HS phy */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
|
||||
reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
|
||||
|
||||
fsleep(100);
|
||||
|
||||
/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
|
||||
reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
|
||||
writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID;
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
|
||||
reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
|
||||
|
||||
/* Setting FSEL for refference clock */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
|
||||
reg &= ~HSPPLLTUNE_FSEL;
|
||||
|
||||
switch (phy_drd->extrefclk) {
|
||||
case EXYNOS5_FSEL_50MHZ:
|
||||
reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
|
||||
break;
|
||||
case EXYNOS5_FSEL_26MHZ:
|
||||
reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
|
||||
break;
|
||||
case EXYNOS5_FSEL_24MHZ:
|
||||
reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
|
||||
break;
|
||||
case EXYNOS5_FSEL_20MHZ:
|
||||
reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
|
||||
break;
|
||||
case EXYNOS5_FSEL_19MHZ2:
|
||||
reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
|
||||
break;
|
||||
default:
|
||||
dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
|
||||
phy_drd->extrefclk);
|
||||
break;
|
||||
}
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
|
||||
|
||||
/* Enable PHY Power Mode */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
|
||||
reg &= ~HSP_TEST_SIDDQ;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
|
||||
|
||||
/* before POR low, 10us delay is needed to Finish PHY reset */
|
||||
fsleep(10);
|
||||
|
||||
/* Set PHY POR Low */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
|
||||
reg |= HSPCLKRST_PHY20_SW_POR_SEL;
|
||||
reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET);
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
|
||||
|
||||
/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
|
||||
fsleep(75);
|
||||
|
||||
/* Disable forcing pipe interface */
|
||||
reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
reg &= ~LINKCTRL_FORCE_PIPE_EN;
|
||||
writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
|
||||
/* Pclk to pipe_clk */
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL;
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
}
|
||||
|
||||
static void
|
||||
exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd)
|
||||
{
|
||||
u32 reg;
|
||||
void __iomem *reg_phy = phy_drd->reg_phy;
|
||||
|
||||
/* set phy clock & control HS phy */
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP;
|
||||
reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
|
||||
|
||||
/* Disable PHY Power Mode */
|
||||
reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
|
||||
reg |= HSP_TEST_SIDDQ;
|
||||
writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
|
||||
|
||||
/* clear force q-channel */
|
||||
reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
reg &= ~LINKCTRL_FORCE_QACT;
|
||||
writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
|
||||
|
||||
/* link sw reset is need for USB_DP/DM high-z in host mode */
|
||||
reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
reg |= CLKRST_LINK_SW_RST;
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
fsleep(10);
|
||||
reg &= ~CLKRST_LINK_SW_RST;
|
||||
writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
|
||||
}
|
||||
|
||||
static int exynosautov920_usbdrd_phy_init(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
int ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Bypass PHY isol */
|
||||
inst->phy_cfg->phy_isol(inst, false);
|
||||
|
||||
/* UTMI or PIPE3 specific init */
|
||||
inst->phy_cfg->phy_init(phy_drd);
|
||||
|
||||
clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
int ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
exynos850_usbdrd_phy_exit(phy);
|
||||
|
||||
/* enable PHY isol */
|
||||
inst->phy_cfg->phy_isol(inst, true);
|
||||
|
||||
clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
int ret = 0;
|
||||
|
||||
ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
|
||||
exynosautov920_usbdrd_hsphy_disable(phy_drd);
|
||||
else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3)
|
||||
exynosautov920_usb31drd_ssphy_disable(phy_drd);
|
||||
|
||||
/* enable PHY isol */
|
||||
inst->phy_cfg->phy_isol(inst, true);
|
||||
|
||||
clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
int ret;
|
||||
|
||||
dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
|
||||
|
||||
ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
|
||||
phy_drd->core_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable supply */
|
||||
ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators,
|
||||
phy_drd->regulators);
|
||||
if (ret) {
|
||||
dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n");
|
||||
goto fail_supply;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_supply:
|
||||
clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
|
||||
phy_drd->core_clks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
|
||||
dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n");
|
||||
|
||||
/* Disable supply */
|
||||
regulator_bulk_disable(phy_drd->drv_data->n_regulators,
|
||||
phy_drd->regulators);
|
||||
|
||||
clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
|
||||
phy_drd->core_clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const exynosautov920_usb30_regulators[] = {
|
||||
"dvdd", "vdd18",
|
||||
};
|
||||
|
||||
static const char * const exynosautov920_usb20_regulators[] = {
|
||||
"dvdd", "vdd18", "vdd33",
|
||||
};
|
||||
|
||||
static const struct
|
||||
exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = {
|
||||
{
|
||||
.id = EXYNOS5_DRDPHY_PIPE3,
|
||||
.phy_isol = exynos5_usbdrd_phy_isol,
|
||||
.phy_init = exynosautov920_usb31drd_pipe3_init,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = {
|
||||
.init = exynosautov920_usbdrd_phy_init,
|
||||
.exit = exynosautov920_usbdrd_combo_phy_exit,
|
||||
.power_on = exynosautov920_usbdrd_phy_power_on,
|
||||
.power_off = exynosautov920_usbdrd_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const
|
||||
struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = {
|
||||
.phy_cfg = usb31drd_phy_cfg_exynosautov920,
|
||||
.phy_ops = &exynosautov920_usb31drd_combo_ssphy_ops,
|
||||
.pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB31,
|
||||
.clk_names = exynos5_clk_names,
|
||||
.n_clks = ARRAY_SIZE(exynos5_clk_names),
|
||||
.core_clk_names = exynos5_core_clk_names,
|
||||
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
|
||||
.regulator_names = exynosautov920_usb30_regulators,
|
||||
.n_regulators = ARRAY_SIZE(exynosautov920_usb30_regulators),
|
||||
};
|
||||
|
||||
static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
|
||||
.init = exynosautov920_usbdrd_phy_init,
|
||||
.exit = exynosautov920_usbdrd_combo_phy_exit,
|
||||
.power_on = exynosautov920_usbdrd_phy_power_on,
|
||||
.power_off = exynosautov920_usbdrd_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct
|
||||
exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = {
|
||||
{
|
||||
.id = EXYNOS5_DRDPHY_UTMI,
|
||||
.phy_isol = exynos5_usbdrd_phy_isol,
|
||||
.phy_init = exynosautov920_usbdrd_utmi_init,
|
||||
},
|
||||
};
|
||||
|
||||
static const
|
||||
struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = {
|
||||
.phy_cfg = usbdrd_hsphy_cfg_exynosautov920,
|
||||
.phy_ops = &exynosautov920_usbdrd_combo_hsphy_ops,
|
||||
.pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20,
|
||||
.clk_names = exynos5_clk_names,
|
||||
.n_clks = ARRAY_SIZE(exynos5_clk_names),
|
||||
.core_clk_names = exynos5_core_clk_names,
|
||||
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
|
||||
.regulator_names = exynosautov920_usb20_regulators,
|
||||
.n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators),
|
||||
};
|
||||
|
||||
static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
|
||||
.init = exynosautov920_usbdrd_phy_init,
|
||||
.exit = exynosautov920_usbdrd_phy_exit,
|
||||
.power_on = exynosautov920_usbdrd_phy_power_on,
|
||||
.power_off = exynosautov920_usbdrd_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = {
|
||||
{
|
||||
.id = EXYNOS5_DRDPHY_UTMI,
|
||||
.phy_isol = exynos5_usbdrd_phy_isol,
|
||||
.phy_init = exynos850_usbdrd_utmi_init,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = {
|
||||
.phy_cfg = phy_cfg_exynosautov920,
|
||||
.phy_ops = &exynosautov920_usbdrd_phy_ops,
|
||||
.pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20,
|
||||
.clk_names = exynos5_clk_names,
|
||||
.n_clks = ARRAY_SIZE(exynos5_clk_names),
|
||||
.core_clk_names = exynos5_core_clk_names,
|
||||
.n_core_clks = ARRAY_SIZE(exynos5_core_clk_names),
|
||||
.regulator_names = exynosautov920_usb20_regulators,
|
||||
.n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators),
|
||||
};
|
||||
|
||||
static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = {
|
||||
{
|
||||
.id = EXYNOS5_DRDPHY_UTMI,
|
||||
@@ -2260,6 +2902,15 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
|
||||
}, {
|
||||
.compatible = "samsung,exynos990-usbdrd-phy",
|
||||
.data = &exynos990_usbdrd_phy
|
||||
}, {
|
||||
.compatible = "samsung,exynosautov920-usb31drd-combo-ssphy",
|
||||
.data = &exynosautov920_usb31drd_combo_ssphy
|
||||
}, {
|
||||
.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
|
||||
.data = &exynosautov920_usbdrd_combo_hsphy
|
||||
}, {
|
||||
.compatible = "samsung,exynosautov920-usbdrd-phy",
|
||||
.data = &exynosautov920_usbdrd_phy
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ static const struct phy_ops uniphier_u2phy_ops = {
|
||||
static int uniphier_u2phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *parent, *child;
|
||||
struct device_node *parent;
|
||||
struct uniphier_u2phy_priv *priv = NULL, *next = NULL;
|
||||
struct phy_provider *phy_provider;
|
||||
struct regmap *regmap;
|
||||
@@ -129,34 +129,31 @@ static int uniphier_u2phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
for_each_child_of_node(dev->of_node, child) {
|
||||
for_each_child_of_node_scoped(dev->of_node, child) {
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_child;
|
||||
}
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->regmap = regmap;
|
||||
|
||||
priv->vbus = devm_regulator_get_optional(dev, "vbus");
|
||||
if (IS_ERR(priv->vbus)) {
|
||||
if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) {
|
||||
ret = PTR_ERR(priv->vbus);
|
||||
goto out_put_child;
|
||||
}
|
||||
if (PTR_ERR(priv->vbus) == -EPROBE_DEFER)
|
||||
return PTR_ERR(priv->vbus);
|
||||
|
||||
priv->vbus = NULL;
|
||||
}
|
||||
|
||||
priv->phy = devm_phy_create(dev, child, &uniphier_u2phy_ops);
|
||||
if (IS_ERR(priv->phy)) {
|
||||
dev_err(dev, "Failed to create phy\n");
|
||||
ret = PTR_ERR(priv->phy);
|
||||
goto out_put_child;
|
||||
return PTR_ERR(priv->phy);
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(child, "reg", &data_idx);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get reg property\n");
|
||||
goto out_put_child;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (data_idx < ndatas)
|
||||
@@ -174,11 +171,6 @@ static int uniphier_u2phy_probe(struct platform_device *pdev)
|
||||
phy_provider = devm_of_phy_provider_register(dev,
|
||||
uniphier_u2phy_xlate);
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
|
||||
out_put_child:
|
||||
of_node_put(child);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct uniphier_u2phy_soc_data uniphier_pro4_data[] = {
|
||||
|
||||
13
drivers/phy/spacemit/Kconfig
Normal file
13
drivers/phy/spacemit/Kconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Phy drivers for SpacemiT platforms
|
||||
#
|
||||
config PHY_SPACEMIT_K1_USB2
|
||||
tristate "SpacemiT K1 USB 2.0 PHY support"
|
||||
depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
|
||||
depends on COMMON_CLK
|
||||
depends on USB_COMMON
|
||||
select GENERIC_PHY
|
||||
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.
|
||||
2
drivers/phy/spacemit/Makefile
Normal file
2
drivers/phy/spacemit/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
|
||||
200
drivers/phy/spacemit/phy-k1-usb2.c
Normal file
200
drivers/phy/spacemit/phy-k1-usb2.c
Normal file
@@ -0,0 +1,200 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SpacemiT K1 USB 2.0 PHY driver
|
||||
*
|
||||
* Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd
|
||||
* Copyright (C) 2025 Ze Huang <huang.ze@linux.dev>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/usb/of.h>
|
||||
|
||||
#define PHY_RST_MODE_CTRL 0x04
|
||||
#define PHY_PLL_RDY BIT(0)
|
||||
#define PHY_CLK_CDR_EN BIT(1)
|
||||
#define PHY_CLK_PLL_EN BIT(2)
|
||||
#define PHY_CLK_MAC_EN BIT(3)
|
||||
#define PHY_MAC_RSTN BIT(5)
|
||||
#define PHY_CDR_RSTN BIT(6)
|
||||
#define PHY_PLL_RSTN BIT(7)
|
||||
/*
|
||||
* hs line state sel (Bit 13):
|
||||
* - 1 (Default): Internal HS line state is set to 01 when usb_hs_tx_en is valid.
|
||||
* - 0: Internal HS line state is always driven by usb_hs_lstate.
|
||||
*
|
||||
* fs line state sel (Bit 14):
|
||||
* - 1 (Default): FS line state is determined by the output data
|
||||
* (usb_fs_datain/b).
|
||||
* - 0: FS line state is always determined by the input data (dmo/dpo).
|
||||
*/
|
||||
#define PHY_HS_LINE_TX_MODE BIT(13)
|
||||
#define PHY_FS_LINE_TX_MODE BIT(14)
|
||||
|
||||
#define PHY_INIT_MODE_BITS (PHY_FS_LINE_TX_MODE | PHY_HS_LINE_TX_MODE)
|
||||
#define PHY_CLK_ENABLE_BITS (PHY_CLK_PLL_EN | PHY_CLK_CDR_EN | \
|
||||
PHY_CLK_MAC_EN)
|
||||
#define PHY_DEASSERT_RST_BITS (PHY_PLL_RSTN | PHY_CDR_RSTN | \
|
||||
PHY_MAC_RSTN)
|
||||
|
||||
#define PHY_TX_HOST_CTRL 0x10
|
||||
#define PHY_HST_DISC_AUTO_CLR BIT(2) /* autoclear hs host disc when re-connect */
|
||||
|
||||
#define PHY_HSTXP_HW_CTRL 0x34
|
||||
#define PHY_HSTXP_RSTN BIT(2) /* generate reset for clock hstxp */
|
||||
#define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */
|
||||
#define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */
|
||||
|
||||
#define PHY_PLL_DIV_CFG 0x98
|
||||
#define PHY_FDIV_FRACT_8_15 GENMASK(7, 0)
|
||||
#define PHY_FDIV_FRACT_16_19 GENMASK(11, 8)
|
||||
#define PHY_FDIV_FRACT_20_21 BIT(12) /* fdiv_reg<21>, <20>, bit21 == bit20 */
|
||||
/*
|
||||
* freq_sel<1:0>
|
||||
* if ref clk freq=24.0MHz-->freq_sel<2:0> == 3b'001, then internal divider value == 80
|
||||
*/
|
||||
#define PHY_FDIV_FRACT_0_1 GENMASK(14, 13)
|
||||
/*
|
||||
* pll divider value selection
|
||||
* 1: divider value will choose internal default value ,dependent on freq_sel<1:0>
|
||||
* 0: divider value will be over ride by fdiv_reg<21:0>
|
||||
*/
|
||||
#define PHY_DIV_LOCAL_EN BIT(15)
|
||||
|
||||
#define PHY_SEL_FREQ_24MHZ 0x01
|
||||
#define FDIV_REG_MASK (PHY_FDIV_FRACT_20_21 | PHY_FDIV_FRACT_16_19 | \
|
||||
PHY_FDIV_FRACT_8_15)
|
||||
#define FDIV_REG_VAL 0x1ec4 /* 0x100 selects 24MHz, rest are default */
|
||||
|
||||
#define K1_USB2PHY_RESET_TIME_MS 50
|
||||
|
||||
struct spacemit_usb2phy {
|
||||
struct phy *phy;
|
||||
struct clk *clk;
|
||||
struct regmap *regmap_base;
|
||||
};
|
||||
|
||||
static const struct regmap_config phy_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0x200,
|
||||
};
|
||||
|
||||
static int spacemit_usb2phy_init(struct phy *phy)
|
||||
{
|
||||
struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
|
||||
struct regmap *map = sphy->regmap_base;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = clk_enable(sphy->clk);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "failed to enable clock\n");
|
||||
clk_disable(sphy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure the usb controller is not under reset process before
|
||||
* any configuration
|
||||
*/
|
||||
usleep_range(150, 200);
|
||||
|
||||
/* 24M ref clk */
|
||||
val = FIELD_PREP(FDIV_REG_MASK, FDIV_REG_VAL) |
|
||||
FIELD_PREP(PHY_FDIV_FRACT_0_1, PHY_SEL_FREQ_24MHZ) |
|
||||
PHY_DIV_LOCAL_EN;
|
||||
regmap_write(map, PHY_PLL_DIV_CFG, val);
|
||||
|
||||
ret = regmap_read_poll_timeout(map, PHY_RST_MODE_CTRL, val,
|
||||
(val & PHY_PLL_RDY),
|
||||
500, K1_USB2PHY_RESET_TIME_MS * 1000);
|
||||
if (ret) {
|
||||
dev_err(&phy->dev, "wait PLLREADY timeout\n");
|
||||
clk_disable(sphy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* release usb2 phy internal reset and enable clock gating */
|
||||
val = (PHY_INIT_MODE_BITS | PHY_CLK_ENABLE_BITS | PHY_DEASSERT_RST_BITS);
|
||||
regmap_write(map, PHY_RST_MODE_CTRL, val);
|
||||
|
||||
val = (PHY_HSTXP_RSTN | PHY_CLK_HSTXP_EN | PHY_HSTXP_MODE);
|
||||
regmap_write(map, PHY_HSTXP_HW_CTRL, val);
|
||||
|
||||
/* auto clear host disc */
|
||||
regmap_update_bits(map, PHY_TX_HOST_CTRL, PHY_HST_DISC_AUTO_CLR,
|
||||
PHY_HST_DISC_AUTO_CLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spacemit_usb2phy_exit(struct phy *phy)
|
||||
{
|
||||
struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
|
||||
|
||||
clk_disable(sphy->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops spacemit_usb2phy_ops = {
|
||||
.init = spacemit_usb2phy_init,
|
||||
.exit = spacemit_usb2phy_exit,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int spacemit_usb2phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct spacemit_usb2phy *sphy;
|
||||
void __iomem *base;
|
||||
|
||||
sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
|
||||
if (!sphy)
|
||||
return -ENOMEM;
|
||||
|
||||
sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL);
|
||||
if (IS_ERR(sphy->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n");
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
sphy->regmap_base = devm_regmap_init_mmio(dev, base, &phy_regmap_config);
|
||||
if (IS_ERR(sphy->regmap_base))
|
||||
return dev_err_probe(dev, PTR_ERR(sphy->regmap_base), "Failed to init regmap\n");
|
||||
|
||||
sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops);
|
||||
if (IS_ERR(sphy->phy))
|
||||
return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n");
|
||||
|
||||
phy_set_drvdata(sphy->phy, sphy);
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id spacemit_usb2phy_dt_match[] = {
|
||||
{ .compatible = "spacemit,k1-usb2-phy", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match);
|
||||
|
||||
static struct platform_driver spacemit_usb2_phy_driver = {
|
||||
.probe = spacemit_usb2phy_probe,
|
||||
.driver = {
|
||||
.name = "spacemit-usb2-phy",
|
||||
.of_match_table = spacemit_usb2phy_dt_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(spacemit_usb2_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -69,7 +69,6 @@ struct tegra_xusb_usb2_lane {
|
||||
struct tegra_xusb_lane base;
|
||||
|
||||
u32 hs_curr_level_offset;
|
||||
bool powered_on;
|
||||
};
|
||||
|
||||
static inline struct tegra_xusb_usb2_lane *
|
||||
|
||||
@@ -393,6 +393,7 @@ struct wiz {
|
||||
struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS];
|
||||
struct clk_onecell_data clk_data;
|
||||
const struct wiz_data *data;
|
||||
int mux_sel_status[WIZ_MUX_NUM_CLOCKS];
|
||||
};
|
||||
|
||||
static int wiz_reset(struct wiz *wiz)
|
||||
@@ -934,12 +935,12 @@ static unsigned long wiz_clk_div_recalc_rate(struct clk_hw *hw,
|
||||
return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2);
|
||||
}
|
||||
|
||||
static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
static int wiz_clk_div_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct wiz_clk_divider *div = to_wiz_clk_div(hw);
|
||||
|
||||
return divider_round_rate(hw, rate, prate, div->table, 2, 0x0);
|
||||
return divider_determine_rate(hw, req, div->table, 2, 0x0);
|
||||
}
|
||||
|
||||
static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@@ -958,7 +959,7 @@ static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
static const struct clk_ops wiz_clk_div_ops = {
|
||||
.recalc_rate = wiz_clk_div_recalc_rate,
|
||||
.round_rate = wiz_clk_div_round_rate,
|
||||
.determine_rate = wiz_clk_div_determine_rate,
|
||||
.set_rate = wiz_clk_div_set_rate,
|
||||
};
|
||||
|
||||
@@ -1654,11 +1655,25 @@ static void wiz_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(dev);
|
||||
}
|
||||
|
||||
static int wiz_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct wiz *wiz = dev_get_drvdata(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++)
|
||||
regmap_field_read(wiz->mux_sel_field[i], &wiz->mux_sel_status[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wiz_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct wiz *wiz = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++)
|
||||
regmap_field_write(wiz->mux_sel_field[i], wiz->mux_sel_status[i]);
|
||||
|
||||
/* Enable supplemental Control override if available */
|
||||
if (wiz->sup_legacy_clk_override)
|
||||
@@ -1680,7 +1695,7 @@ static int wiz_resume_noirq(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq);
|
||||
static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, wiz_suspend_noirq, wiz_resume_noirq);
|
||||
|
||||
static struct platform_driver wiz_driver = {
|
||||
.probe = wiz_probe,
|
||||
|
||||
@@ -38,6 +38,10 @@ config APPLE_SART
|
||||
|
||||
Say 'y' here if you have an Apple SoC.
|
||||
|
||||
config APPLE_TUNABLE
|
||||
tristate
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
||||
@@ -8,3 +8,6 @@ apple-rtkit-y = rtkit.o rtkit-crashlog.o
|
||||
|
||||
obj-$(CONFIG_APPLE_SART) += apple-sart.o
|
||||
apple-sart-y = sart.o
|
||||
|
||||
obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o
|
||||
apple-tunable-y = tunable.o
|
||||
|
||||
80
drivers/soc/apple/tunable.c
Normal file
80
drivers/soc/apple/tunable.c
Normal file
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR MIT
|
||||
/*
|
||||
* Apple Silicon hardware tunable support
|
||||
*
|
||||
* Each tunable is a list with each entry containing a offset into the MMIO
|
||||
* region, a mask of bits to be cleared and a set of bits to be set. These
|
||||
* tunables are passed along by the previous boot stages and vary from device
|
||||
* to device such that they cannot be hardcoded in the individual drivers.
|
||||
*
|
||||
* Copyright (C) The Asahi Linux Contributors
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/soc/apple/tunable.h>
|
||||
|
||||
struct apple_tunable *devm_apple_tunable_parse(struct device *dev,
|
||||
struct device_node *np,
|
||||
const char *name,
|
||||
struct resource *res)
|
||||
{
|
||||
struct apple_tunable *tunable;
|
||||
struct property *prop;
|
||||
const __be32 *p;
|
||||
size_t sz;
|
||||
int i;
|
||||
|
||||
if (resource_size(res) < 4)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
prop = of_find_property(np, name, NULL);
|
||||
if (!prop)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
if (prop->length % (3 * sizeof(u32)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
sz = prop->length / (3 * sizeof(u32));
|
||||
|
||||
tunable = devm_kzalloc(dev, struct_size(tunable, values, sz), GFP_KERNEL);
|
||||
if (!tunable)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
tunable->sz = sz;
|
||||
|
||||
for (i = 0, p = NULL; i < tunable->sz; ++i) {
|
||||
p = of_prop_next_u32(prop, p, &tunable->values[i].offset);
|
||||
p = of_prop_next_u32(prop, p, &tunable->values[i].mask);
|
||||
p = of_prop_next_u32(prop, p, &tunable->values[i].value);
|
||||
|
||||
/* Sanity checks to catch bugs in our bootloader */
|
||||
if (tunable->values[i].offset % 4)
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (tunable->values[i].offset > (resource_size(res) - 4))
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return tunable;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_apple_tunable_parse);
|
||||
|
||||
void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < tunable->sz; ++i) {
|
||||
u32 val, old_val;
|
||||
|
||||
old_val = readl(regs + tunable->values[i].offset);
|
||||
val = old_val & ~tunable->values[i].mask;
|
||||
val |= tunable->values[i].value;
|
||||
if (val != old_val)
|
||||
writel(val, regs + tunable->values[i].offset);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(apple_tunable_apply);
|
||||
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
||||
MODULE_AUTHOR("Sven Peter <sven@kernel.org>");
|
||||
MODULE_DESCRIPTION("Apple Silicon hardware tunable support");
|
||||
@@ -23,6 +23,7 @@
|
||||
#define PHY_TYPE_DPHY 10
|
||||
#define PHY_TYPE_CPHY 11
|
||||
#define PHY_TYPE_USXGMII 12
|
||||
#define PHY_TYPE_XAUI 13
|
||||
|
||||
#define PHY_POL_NORMAL 0
|
||||
#define PHY_POL_INVERT 1
|
||||
|
||||
@@ -6,16 +6,31 @@
|
||||
#ifndef __PHY_HDMI_H_
|
||||
#define __PHY_HDMI_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum phy_hdmi_mode {
|
||||
PHY_HDMI_MODE_TMDS,
|
||||
PHY_HDMI_MODE_FRL,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct phy_configure_opts_hdmi - HDMI configuration set
|
||||
* @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
|
||||
* @bpc: Bits per color channel.
|
||||
* @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
|
||||
* @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
|
||||
* @frl.lanes: HDMI FRL lanes count.
|
||||
*
|
||||
* This structure is used to represent the configuration state of a HDMI phy.
|
||||
*/
|
||||
struct phy_configure_opts_hdmi {
|
||||
unsigned long long tmds_char_rate;
|
||||
unsigned int bpc;
|
||||
union {
|
||||
unsigned long long tmds_char_rate;
|
||||
struct {
|
||||
u8 rate_per_lane;
|
||||
u8 lanes;
|
||||
} frl;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* __PHY_HDMI_H_ */
|
||||
|
||||
@@ -243,7 +243,7 @@ static inline void *phy_get_drvdata(struct phy *phy)
|
||||
#if IS_ENABLED(CONFIG_GENERIC_PHY)
|
||||
int phy_pm_runtime_get(struct phy *phy);
|
||||
int phy_pm_runtime_get_sync(struct phy *phy);
|
||||
int phy_pm_runtime_put(struct phy *phy);
|
||||
void phy_pm_runtime_put(struct phy *phy);
|
||||
int phy_pm_runtime_put_sync(struct phy *phy);
|
||||
int phy_init(struct phy *phy);
|
||||
int phy_exit(struct phy *phy);
|
||||
@@ -324,11 +324,8 @@ static inline int phy_pm_runtime_get_sync(struct phy *phy)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int phy_pm_runtime_put(struct phy *phy)
|
||||
static inline void phy_pm_runtime_put(struct phy *phy)
|
||||
{
|
||||
if (!phy)
|
||||
return 0;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int phy_pm_runtime_put_sync(struct phy *phy)
|
||||
|
||||
62
include/linux/soc/apple/tunable.h
Normal file
62
include/linux/soc/apple/tunable.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
/*
|
||||
* Apple Silicon hardware tunable support
|
||||
*
|
||||
* Each tunable is a list with each entry containing a offset into the MMIO
|
||||
* region, a mask of bits to be cleared and a set of bits to be set. These
|
||||
* tunables are passed along by the previous boot stages and vary from device
|
||||
* to device such that they cannot be hardcoded in the individual drivers.
|
||||
*
|
||||
* Copyright (C) The Asahi Linux Contributors
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_SOC_APPLE_TUNABLE_H_
|
||||
#define _LINUX_SOC_APPLE_TUNABLE_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* Struct to store an Apple Silicon hardware tunable.
|
||||
*
|
||||
* Each tunable is a list with each entry containing a offset into the MMIO
|
||||
* region, a mask of bits to be cleared and a set of bits to be set. These
|
||||
* tunables are passed along by the previous boot stages and vary from device
|
||||
* to device such that they cannot be hardcoded in the individual drivers.
|
||||
*
|
||||
* @param sz Number of [offset, mask, value] tuples stored in values.
|
||||
* @param values [offset, mask, value] array.
|
||||
*/
|
||||
struct apple_tunable {
|
||||
size_t sz;
|
||||
struct {
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 value;
|
||||
} values[] __counted_by(sz);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse an array of hardware tunables from the device tree.
|
||||
*
|
||||
* @dev: Device node used for devm_kzalloc internally.
|
||||
* @np: Device node which contains the tunable array.
|
||||
* @name: Name of the device tree property which contains the tunables.
|
||||
* @res: Resource to which the tunables will be applied, used for bound checking
|
||||
*
|
||||
* @return: devres allocated struct on success or PTR_ERR on failure.
|
||||
*/
|
||||
struct apple_tunable *devm_apple_tunable_parse(struct device *dev,
|
||||
struct device_node *np,
|
||||
const char *name,
|
||||
struct resource *res);
|
||||
|
||||
/**
|
||||
* Apply a previously loaded hardware tunable.
|
||||
*
|
||||
* @param regs: MMIO to which the tunable will be applied.
|
||||
* @param tunable: Pointer to the tunable.
|
||||
*/
|
||||
void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable);
|
||||
|
||||
#endif
|
||||
@@ -1015,4 +1015,7 @@
|
||||
#define GS101_GRP2_INTR_BID_UPEND (0x0208)
|
||||
#define GS101_GRP2_INTR_BID_CLEAR (0x020c)
|
||||
|
||||
/* exynosautov920 */
|
||||
#define EXYNOSAUTOV920_PHY_CTRL_USB20 (0x0710)
|
||||
#define EXYNOSAUTOV920_PHY_CTRL_USB31 (0x0714)
|
||||
#endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
|
||||
|
||||
Reference in New Issue
Block a user