phy-for-5.14 version 2
- Updates: - Yaml conversion for renesas,rcar-gen3 pcie phy and rockchip-usb-phy bindings - Support for devm_phy_get() taking NULL phy name - New support: - PCIe phy for Qualcomm IPQ60xx - PCIe phy for Qualcomm SDX55 - USB phy for RK3308 - CAN transceivers phy for TI TCAN104x - Innosilicon-based CSI dphy for rockchip -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmDS5/MACgkQfBQHDyUj g0cMZhAAjtAeYe7R8r2M8NACd2HRnBMBcHFJtz6Os7ZZa4dRMLyq6TkStZ8k1Mat 2dEUb3Wb8G18WqECXUlcJp/CYlK1ea1GDwgTLd09tGo7PAn6p3RBG7ujf+aCWoil TLhsE9Sb7d3pr8qVsy6DQc/TIWxfCTeqZrIRzt2UQXxK6P/3CtdN1g/TEdq1r/h9 A/xkDnyT2QQOJTgFMUh9RF85vXfptm9+gVxNdgyHGVvdaEhSURUytEfubrQYjd1P sM5BhsNPEKHqL/kYlgMAgnENtQBrXBwfEzP02M32zyhTLvaZMcV87Z8LXxmrPDn/ jtYLlSYTQTDKA9tHBw1W8NogaLS9INeTjDhqt0hBsT/lh1vL5KMk0IGsSxUaJ27h 6on3NmjsxI/HKosdrQzRizURS0xixOWDnZN7UPFaHFJbA8GMIlQlDidZOJTl87cc inIuSdB29YA0FNGbXOq/HR3y1qChlwAewxFYCzFtKfuHmZWJNy7osUvQNHodEAGl BGjerYgJUNNiWlxmoggUcLtAdbqYVH8fvvz3WUyClUePVqioX8gS6UDRx8LrgGV2 FvLSKgetbqH3iQtRO+2RtwMJEMmC3eW7esjUv/fEgKym+2JvORpE0p2n5sWTgRMc VWFDVqOp5JJXmarRkly2MMppO5x25d3wE9DLR0/Re7hNPGUsz4M= =Col+ -----END PGP SIGNATURE----- Merge tag 'phy-for-5.14_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy into char-misc-next Vinod writes: phy-for-5.14 version 2 - Updates: - Yaml conversion for renesas,rcar-gen3 pcie phy and rockchip-usb-phy bindings - Support for devm_phy_get() taking NULL phy name - New support: - PCIe phy for Qualcomm IPQ60xx - PCIe phy for Qualcomm SDX55 - USB phy for RK3308 - CAN transceivers phy for TI TCAN104x - Innosilicon-based CSI dphy for rockchip * tag 'phy-for-5.14_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (36 commits) phy: Revert "phy: ralink: Kconfig: convert mt7621-pci-phy into 'bool'" phy: ti: dm816x: Fix the error handling path in 'dm816x_usb_phy_probe() phy: uniphier-pcie: Fix updating phy parameters phy/rockchip: add Innosilicon-based CSI dphy dt-bindings: phy: add yaml binding for rockchip-inno-csi-dphy phy: rockchip: remove redundant initialization of pointer cfg phy: phy-can-transceiver: Add support for generic CAN transceiver driver dt-bindings: phy: Add binding for TI TCAN104x CAN transceivers phy: core: Reword the comment specifying the units of max_link_rate to be Mbps phy: phy-mtk-hdmi: Remove redundant dev_err call in mtk_hdmi_phy_probe() phy: phy-mtk-mipi-dsi: Remove redundant dev_err call in mtk_mipi_tx_probe() phy: phy-mmp3-hsic: Remove redundant dev_err call in mmp3_hsic_phy_probe() phy: bcm-ns-usb3: Remove redundant dev_err call in bcm_ns_usb3_mdio_probe() MAINTAINERS: update marvell,armada-3700-utmi-phy.yaml reference phy: phy-twl4030-usb: use DEVICE_ATTR_RO macro dt-bindings: phy: convert rockchip-usb-phy.txt to YAML phy: phy-rockchip-inno-usb2: add support for RK3308 USB phy dt-bindings: phy: rockchip-inno-usb2: add compatible for rk3308 USB phy phy: stm32: manage optional vbus regulator on phy_power_on/off dt-bindings: phy: add vbus-supply optional property to phy-stm32-usbphyc ...
This commit is contained in:
commit
5471a81235
@ -14,6 +14,7 @@
|
||||
- "qcom,pcie-qcs404" for qcs404
|
||||
- "qcom,pcie-sdm845" for sdm845
|
||||
- "qcom,pcie-sm8250" for sm8250
|
||||
- "qcom,pcie-ipq6018" for ipq6018
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
@ -123,6 +124,16 @@
|
||||
- "ahb" AHB clock
|
||||
- "aux" Auxiliary clock
|
||||
|
||||
- clock-names:
|
||||
Usage: required for ipq6018
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries
|
||||
- "iface" PCIe to SysNOC BIU clock
|
||||
- "axi_m" AXI Master clock
|
||||
- "axi_s" AXI Slave clock
|
||||
- "axi_bridge" AXI bridge clock
|
||||
- "rchng"
|
||||
|
||||
- clock-names:
|
||||
Usage: required for qcs404
|
||||
Value type: <stringlist>
|
||||
@ -209,6 +220,19 @@
|
||||
- "ahb" AHB Reset
|
||||
- "axi_m_sticky" AXI Master Sticky reset
|
||||
|
||||
- reset-names:
|
||||
Usage: required for ipq6018
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries
|
||||
- "pipe" PIPE reset
|
||||
- "sleep" Sleep reset
|
||||
- "sticky" Core Sticky reset
|
||||
- "axi_m" AXI Master reset
|
||||
- "axi_s" AXI Slave reset
|
||||
- "ahb" AHB Reset
|
||||
- "axi_m_sticky" AXI Master Sticky reset
|
||||
- "axi_s_sticky" AXI Slave Sticky reset
|
||||
|
||||
- reset-names:
|
||||
Usage: required for qcs404
|
||||
Value type: <stringlist>
|
||||
|
@ -16,6 +16,9 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description: selects if the phy is dual-ported
|
||||
@ -23,6 +26,7 @@ properties:
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
@ -32,5 +36,6 @@ examples:
|
||||
pcie0_phy: pcie-phy@1e149000 {
|
||||
compatible = "mediatek,mt7621-pci-phy";
|
||||
reg = <0x1e149000 0x0700>;
|
||||
clocks = <&sysc 0>;
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@ properties:
|
||||
enum:
|
||||
- rockchip,px30-usb2phy
|
||||
- rockchip,rk3228-usb2phy
|
||||
- rockchip,rk3308-usb2phy
|
||||
- rockchip,rk3328-usb2phy
|
||||
- rockchip,rk3366-usb2phy
|
||||
- rockchip,rk3399-usb2phy
|
||||
|
@ -74,6 +74,13 @@ patternProperties:
|
||||
"#phy-cells":
|
||||
enum: [ 0x0, 0x1 ]
|
||||
|
||||
connector:
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: ../connector/usb-connector.yaml
|
||||
properties:
|
||||
vbus-supply: true
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
@ -130,6 +137,10 @@ examples:
|
||||
reg = <0>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
#phy-cells = <0>;
|
||||
connector {
|
||||
compatible = "usb-a-connector";
|
||||
vbus-supply = <&vbus_sw>;
|
||||
};
|
||||
};
|
||||
|
||||
usbphyc_port1: usb-phy@1 {
|
||||
|
@ -17,6 +17,7 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,ipq6018-qmp-pcie-phy
|
||||
- qcom,ipq8074-qmp-pcie-phy
|
||||
- qcom,ipq8074-qmp-usb3-phy
|
||||
- qcom,msm8996-qmp-pcie-phy
|
||||
@ -45,6 +46,7 @@ properties:
|
||||
- qcom,sm8350-qmp-ufs-phy
|
||||
- qcom,sm8350-qmp-usb3-phy
|
||||
- qcom,sm8350-qmp-usb3-uni-phy
|
||||
- qcom,sdx55-qmp-pcie-phy
|
||||
- qcom,sdx55-qmp-usb3-uni-phy
|
||||
|
||||
reg:
|
||||
@ -296,6 +298,30 @@ allOf:
|
||||
items:
|
||||
- const: phy
|
||||
- const: common
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,ipq6018-qmp-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Phy aux clock.
|
||||
- description: Phy config clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg_ahb
|
||||
resets:
|
||||
items:
|
||||
- description: reset of phy block.
|
||||
- description: phy common block reset.
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: common
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -303,6 +329,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,sdm845-qhp-pcie-phy
|
||||
- qcom,sdm845-qmp-pcie-phy
|
||||
- qcom,sdx55-qmp-pcie-phy
|
||||
- qcom,sm8250-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8250-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8250-qmp-modem-pcie-phy
|
||||
|
@ -1,24 +0,0 @@
|
||||
* Renesas R-Car generation 3 PCIe PHY
|
||||
|
||||
This file provides information on what the device node for the R-Car
|
||||
generation 3 PCIe PHY contains.
|
||||
|
||||
Required properties:
|
||||
- compatible: "renesas,r8a77980-pcie-phy" if the device is a part of the
|
||||
R8A77980 SoC.
|
||||
- reg: offset and length of the register block.
|
||||
- clocks: clock phandle and specifier pair.
|
||||
- power-domains: power domain phandle and specifier pair.
|
||||
- resets: reset phandle and specifier pair.
|
||||
- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
|
||||
|
||||
Example (R-Car V3H):
|
||||
|
||||
pcie-phy@e65d0000 {
|
||||
compatible = "renesas,r8a77980-pcie-phy";
|
||||
reg = <0 0xe65d0000 0 0x8000>;
|
||||
#phy-cells = <0>;
|
||||
clocks = <&cpg CPG_MOD 319>;
|
||||
power-domains = <&sysc 32>;
|
||||
resets = <&cpg 319>;
|
||||
};
|
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/renesas,rcar-gen3-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas R-Car Generation 3 PCIe PHY
|
||||
|
||||
maintainers:
|
||||
- Sergei Shtylyov <sergei.shtylyov@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r8a77980-pcie-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- power-domains
|
||||
- resets
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a77980-cpg-mssr.h>
|
||||
#include <dt-bindings/power/r8a77980-sysc.h>
|
||||
|
||||
pcie-phy@e65d0000 {
|
||||
compatible = "renesas,r8a77980-pcie-phy";
|
||||
reg = <0xe65d0000 0x8000>;
|
||||
#phy-cells = <0>;
|
||||
clocks = <&cpg CPG_MOD 319>;
|
||||
power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 319>;
|
||||
};
|
@ -0,0 +1,79 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/rockchip-inno-csi-dphy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip SoC MIPI RX0 D-PHY Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
description: |
|
||||
The Rockchip SoC has a MIPI CSI D-PHY based on an Innosilicon IP wich
|
||||
connects to the ISP1 (Image Signal Processing unit v1.0) for CSI cameras.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,px30-csi-dphy
|
||||
- rockchip,rk1808-csi-dphy
|
||||
- rockchip,rk3326-csi-dphy
|
||||
- rockchip,rk3368-csi-dphy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: pclk
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
power-domains:
|
||||
description: Video in/out power domain.
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: exclusive PHY reset line
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: apb
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Some additional phy settings are access through GRF regs.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#phy-cells'
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- rockchip,grf
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
csi_dphy: phy@ff2f0000 {
|
||||
compatible = "rockchip,px30-csi-dphy";
|
||||
reg = <0xff2f0000 0x4000>;
|
||||
clocks = <&cru 1>;
|
||||
clock-names = "pclk";
|
||||
#phy-cells = <0>;
|
||||
power-domains = <&power 1>;
|
||||
resets = <&cru 1>;
|
||||
reset-names = "apb";
|
||||
rockchip,grf = <&grf>;
|
||||
};
|
@ -1,52 +0,0 @@
|
||||
ROCKCHIP USB2 PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: matching the soc type, one of
|
||||
"rockchip,rk3066a-usb-phy"
|
||||
"rockchip,rk3188-usb-phy"
|
||||
"rockchip,rk3288-usb-phy"
|
||||
- #address-cells: should be 1
|
||||
- #size-cells: should be 0
|
||||
|
||||
Deprecated properties:
|
||||
- rockchip,grf : phandle to the syscon managing the "general
|
||||
register files" - phy should be a child of the GRF instead
|
||||
|
||||
Sub-nodes:
|
||||
Each PHY should be represented as a sub-node.
|
||||
|
||||
Sub-nodes
|
||||
required properties:
|
||||
- #phy-cells: should be 0
|
||||
- reg: PHY configure reg address offset in GRF
|
||||
"0x320" - for PHY attach to OTG controller
|
||||
"0x334" - for PHY attach to HOST0 controller
|
||||
"0x348" - for PHY attach to HOST1 controller
|
||||
|
||||
Optional Properties:
|
||||
- clocks : phandle + clock specifier for the phy clocks
|
||||
- clock-names: string, clock name, must be "phyclk"
|
||||
- #clock-cells: for users of the phy-pll, should be 0
|
||||
- reset-names: Only allow the following entries:
|
||||
- phy-reset
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
- vbus-supply: power-supply phandle for vbus power source
|
||||
|
||||
Example:
|
||||
|
||||
grf: syscon@ff770000 {
|
||||
compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd";
|
||||
|
||||
...
|
||||
|
||||
usbphy: phy {
|
||||
compatible = "rockchip,rk3288-usb-phy";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usbphy0: usb-phy0 {
|
||||
#phy-cells = <0>;
|
||||
reg = <0x320>;
|
||||
};
|
||||
};
|
||||
};
|
81
Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
Normal file
81
Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
Normal file
@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/rockchip-usb-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip USB2.0 phy
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: rockchip,rk3288-usb-phy
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,rk3066a-usb-phy
|
||||
- rockchip,rk3188-usb-phy
|
||||
- const: rockchip,rk3288-usb-phy
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"usb-phy@[0-9a-f]+$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: phyclk
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: phy-reset
|
||||
|
||||
vbus-supply:
|
||||
description: phandle for vbus power source
|
||||
|
||||
required:
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
usbphy: usbphy {
|
||||
compatible = "rockchip,rk3288-usb-phy";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usbphy0: usb-phy@320 {
|
||||
reg = <0x320>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
56
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
Normal file
56
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
Normal file
@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/ti,tcan104x-can.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: TCAN104x CAN TRANSCEIVER PHY
|
||||
|
||||
maintainers:
|
||||
- Aswath Govindraju <a-govindraju@ti.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^can-phy"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tcan1042
|
||||
- ti,tcan1043
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
standby-gpios:
|
||||
description:
|
||||
gpio node to toggle standby signal on transceiver
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
description:
|
||||
gpio node to toggle enable signal on transceiver
|
||||
maxItems: 1
|
||||
|
||||
max-bitrate:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
max bit rate supported in bps
|
||||
minimum: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
transceiver1: can-phy {
|
||||
compatible = "ti,tcan1043";
|
||||
#phy-cells = <0>;
|
||||
max-bitrate = <5000000>;
|
||||
standby-gpios = <&wakeup_gpio1 16 GPIO_ACTIVE_LOW>;
|
||||
enable-gpios = <&main_gpio1 67 GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -4041,7 +4041,9 @@ W: https://github.com/linux-can
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
|
||||
F: Documentation/devicetree/bindings/net/can/
|
||||
F: Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
|
||||
F: drivers/net/can/
|
||||
F: drivers/phy/phy-can-transceiver.c
|
||||
F: include/linux/can/bittiming.h
|
||||
F: include/linux/can/dev.h
|
||||
F: include/linux/can/led.h
|
||||
@ -10897,7 +10899,7 @@ MARVELL ARMADA 3700 PHY DRIVERS
|
||||
M: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt
|
||||
F: Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt
|
||||
F: Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml
|
||||
F: drivers/phy/marvell/phy-mvebu-a3700-comphy.c
|
||||
F: drivers/phy/marvell/phy-mvebu-a3700-utmi.c
|
||||
|
||||
|
@ -61,6 +61,15 @@ config USB_LGM_PHY
|
||||
interface to interact with USB GEN-II and USB 3.x PHY that is part
|
||||
of the Intel network SOC.
|
||||
|
||||
config PHY_CAN_TRANSCEIVER
|
||||
tristate "CAN transceiver PHY"
|
||||
select GENERIC_PHY
|
||||
help
|
||||
This option enables support for CAN transceivers as a PHY. This
|
||||
driver provides function for putting the transceivers in various
|
||||
functional modes using gpios and sets the attribute max link
|
||||
rate, for CAN drivers.
|
||||
|
||||
source "drivers/phy/allwinner/Kconfig"
|
||||
source "drivers/phy/amlogic/Kconfig"
|
||||
source "drivers/phy/broadcom/Kconfig"
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
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_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
|
||||
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
|
||||
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
|
||||
|
@ -215,10 +215,8 @@ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
|
||||
return err;
|
||||
|
||||
usb3->dmp = devm_ioremap_resource(dev, &res);
|
||||
if (IS_ERR(usb3->dmp)) {
|
||||
dev_err(dev, "Failed to map DMP regs\n");
|
||||
if (IS_ERR(usb3->dmp))
|
||||
return PTR_ERR(usb3->dmp);
|
||||
}
|
||||
|
||||
usb3->phy = devm_phy_create(dev, NULL, &ops);
|
||||
if (IS_ERR(usb3->phy)) {
|
||||
|
@ -47,10 +47,8 @@ static int mmp3_hsic_phy_probe(struct platform_device *pdev)
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, resource);
|
||||
if (IS_ERR(base)) {
|
||||
dev_err(dev, "failed to remap PHY regs\n");
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
|
@ -119,9 +119,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
hdmi_phy->regs = devm_ioremap_resource(dev, mem);
|
||||
if (IS_ERR(hdmi_phy->regs)) {
|
||||
ret = PTR_ERR(hdmi_phy->regs);
|
||||
dev_err(dev, "Failed to get memory resource: %d\n", ret);
|
||||
return ret;
|
||||
return PTR_ERR(hdmi_phy->regs);
|
||||
}
|
||||
|
||||
ref_clk = devm_clk_get(dev, "pll_ref");
|
||||
|
@ -151,9 +151,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mipi_tx->regs = devm_ioremap_resource(dev, mem);
|
||||
if (IS_ERR(mipi_tx->regs)) {
|
||||
ret = PTR_ERR(mipi_tx->regs);
|
||||
dev_err(dev, "Failed to get memory resource: %d\n", ret);
|
||||
return ret;
|
||||
return PTR_ERR(mipi_tx->regs);
|
||||
}
|
||||
|
||||
ref_clk = devm_clk_get(dev, NULL);
|
||||
|
146
drivers/phy/phy-can-transceiver.c
Normal file
146
drivers/phy/phy-can-transceiver.c
Normal file
@ -0,0 +1,146 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* phy-can-transceiver.c - phy driver for CAN transceivers
|
||||
*
|
||||
* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com
|
||||
*
|
||||
*/
|
||||
#include<linux/phy/phy.h>
|
||||
#include<linux/platform_device.h>
|
||||
#include<linux/module.h>
|
||||
#include<linux/gpio.h>
|
||||
#include<linux/gpio/consumer.h>
|
||||
|
||||
struct can_transceiver_data {
|
||||
u32 flags;
|
||||
#define CAN_TRANSCEIVER_STB_PRESENT BIT(0)
|
||||
#define CAN_TRANSCEIVER_EN_PRESENT BIT(1)
|
||||
};
|
||||
|
||||
struct can_transceiver_phy {
|
||||
struct phy *generic_phy;
|
||||
struct gpio_desc *standby_gpio;
|
||||
struct gpio_desc *enable_gpio;
|
||||
};
|
||||
|
||||
/* Power on function */
|
||||
static int can_transceiver_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
|
||||
|
||||
if (can_transceiver_phy->standby_gpio)
|
||||
gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 0);
|
||||
if (can_transceiver_phy->enable_gpio)
|
||||
gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Power off function */
|
||||
static int can_transceiver_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
|
||||
|
||||
if (can_transceiver_phy->standby_gpio)
|
||||
gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
|
||||
if (can_transceiver_phy->enable_gpio)
|
||||
gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops can_transceiver_phy_ops = {
|
||||
.power_on = can_transceiver_phy_power_on,
|
||||
.power_off = can_transceiver_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct can_transceiver_data tcan1042_drvdata = {
|
||||
.flags = CAN_TRANSCEIVER_STB_PRESENT,
|
||||
};
|
||||
|
||||
static const struct can_transceiver_data tcan1043_drvdata = {
|
||||
.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
|
||||
};
|
||||
|
||||
static const struct of_device_id can_transceiver_phy_ids[] = {
|
||||
{
|
||||
.compatible = "ti,tcan1042",
|
||||
.data = &tcan1042_drvdata
|
||||
},
|
||||
{
|
||||
.compatible = "ti,tcan1043",
|
||||
.data = &tcan1043_drvdata
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
|
||||
|
||||
static int can_transceiver_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct can_transceiver_phy *can_transceiver_phy;
|
||||
const struct can_transceiver_data *drvdata;
|
||||
const struct of_device_id *match;
|
||||
struct phy *phy;
|
||||
struct gpio_desc *standby_gpio;
|
||||
struct gpio_desc *enable_gpio;
|
||||
u32 max_bitrate = 0;
|
||||
|
||||
can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
|
||||
if (!can_transceiver_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
|
||||
drvdata = match->data;
|
||||
|
||||
phy = devm_phy_create(dev, dev->of_node,
|
||||
&can_transceiver_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create can transceiver phy\n");
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
device_property_read_u32(dev, "max-bitrate", &max_bitrate);
|
||||
if (!max_bitrate)
|
||||
dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
|
||||
phy->attrs.max_link_rate = max_bitrate;
|
||||
|
||||
can_transceiver_phy->generic_phy = phy;
|
||||
|
||||
if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
|
||||
standby_gpio = devm_gpiod_get(dev, "standby", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(standby_gpio))
|
||||
return PTR_ERR(standby_gpio);
|
||||
can_transceiver_phy->standby_gpio = standby_gpio;
|
||||
}
|
||||
|
||||
if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
|
||||
enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(enable_gpio))
|
||||
return PTR_ERR(enable_gpio);
|
||||
can_transceiver_phy->enable_gpio = enable_gpio;
|
||||
}
|
||||
|
||||
phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static struct platform_driver can_transceiver_phy_driver = {
|
||||
.probe = can_transceiver_phy_probe,
|
||||
.driver = {
|
||||
.name = "can-transceiver-phy",
|
||||
.of_match_table = can_transceiver_phy_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(can_transceiver_phy_driver);
|
||||
|
||||
MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>");
|
||||
MODULE_AUTHOR("Aswath Govindraju <a-govindraju@ti.com>");
|
||||
MODULE_DESCRIPTION("CAN TRANSCEIVER PHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -15,7 +15,7 @@
|
||||
/*
|
||||
* Minimum D-PHY timings based on MIPI D-PHY specification. Derived
|
||||
* from the valid ranges specified in Section 6.9, Table 14, Page 41
|
||||
* of the D-PHY specification (v2.1).
|
||||
* of the D-PHY specification (v1.2).
|
||||
*/
|
||||
int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
|
||||
unsigned int bpp,
|
||||
|
@ -697,16 +697,18 @@ struct phy *phy_get(struct device *dev, const char *string)
|
||||
struct phy *phy;
|
||||
struct device_link *link;
|
||||
|
||||
if (string == NULL) {
|
||||
dev_WARN(dev, "missing string\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (dev->of_node) {
|
||||
index = of_property_match_string(dev->of_node, "phy-names",
|
||||
string);
|
||||
if (string)
|
||||
index = of_property_match_string(dev->of_node, "phy-names",
|
||||
string);
|
||||
else
|
||||
index = 0;
|
||||
phy = _of_phy_get(dev->of_node, index);
|
||||
} else {
|
||||
if (string == NULL) {
|
||||
dev_WARN(dev, "missing string\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
phy = phy_find(dev, string);
|
||||
}
|
||||
if (IS_ERR(phy))
|
||||
|
@ -961,7 +961,8 @@ static void xgene_phy_sata_cfg_lanes(struct xgene_phy_ctx *ctx)
|
||||
serdes_wr(ctx, lane, RXTX_REG1, val);
|
||||
|
||||
/* Latch VTT value based on the termination to ground and
|
||||
enable TX FIFO */
|
||||
* enable TX FIFO
|
||||
*/
|
||||
serdes_rd(ctx, lane, RXTX_REG2, &val);
|
||||
val = RXTX_REG2_VTT_ENA_SET(val, 0x1);
|
||||
val = RXTX_REG2_VTT_SEL_SET(val, 0x1);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#define PLL_READY_GATE_EN BIT(3)
|
||||
/* QPHY_PCS_STATUS bit */
|
||||
#define PHYSTATUS BIT(6)
|
||||
#define PHYSTATUS_4_20 BIT(7)
|
||||
/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
|
||||
#define PCS_READY BIT(0)
|
||||
|
||||
@ -143,6 +144,13 @@ static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_READY_STATUS] = 0x168,
|
||||
};
|
||||
|
||||
static const unsigned int ipq_pciephy_gen3_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_SW_RESET] = 0x00,
|
||||
[QPHY_START_CTRL] = 0x44,
|
||||
[QPHY_PCS_STATUS] = 0x14,
|
||||
[QPHY_PCS_POWER_DOWN_CONTROL] = 0x40,
|
||||
};
|
||||
|
||||
static const unsigned int pciephy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_COM_SW_RESET] = 0x400,
|
||||
[QPHY_COM_POWER_DOWN_CONTROL] = 0x404,
|
||||
@ -614,6 +622,113 @@ static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq6018_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq6018_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
|
||||
QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq6018_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_COM_EQ_CONFIG5, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_PRE, 0x00),
|
||||
QMP_PHY_INIT_CFG(PCS_PCIE_PRESET_P10_POST, 0x58),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
|
||||
@ -2110,6 +2225,101 @@ static const struct qmp_phy_init_tbl sdx55_usb3_uniphy_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x19),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x50),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_2, 0xf6),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_LANE_MODE_3, 0x13),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_VMODE_CTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_TX_PI_QEC_CTRL, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_FO_GAIN_RATE2, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_UCDR_PI_CONTROLS, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_3, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_DAC_ENABLE2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_VGA_CAL_CNTRL2, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2, 0x5a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3, 0x09),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4, 0x37),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B0, 0xbd),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B1, 0xf9),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B2, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B3, 0xce),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE2_B4, 0x62),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B0, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B1, 0x7d),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B2, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B3, 0xcf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_RX_MODE_RATE3_B4, 0xd6),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_PHPRE_CTRL, 0xa0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_20_RX_MARG_COARSE_CTRL2, 0x12),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_RX_SIGDET_LVL, 0x77),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG4, 0x16),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_EQ_CONFIG5, 0x02),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_EQ_CONFIG1, 0x17),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
|
||||
@ -2411,6 +2621,8 @@ struct qmp_phy_cfg {
|
||||
unsigned int start_ctrl;
|
||||
unsigned int pwrdn_ctrl;
|
||||
unsigned int mask_com_pcs_ready;
|
||||
/* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
|
||||
unsigned int phy_status;
|
||||
|
||||
/* true, if PHY has a separate PHY_COM control block */
|
||||
bool has_phy_com_ctrl;
|
||||
@ -2624,6 +2836,7 @@ static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
|
||||
@ -2649,6 +2862,7 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
|
||||
.start_ctrl = PCS_START | PLL_READY_GATE_EN,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.mask_com_pcs_ready = PCS_READY,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_phy_com_ctrl = true,
|
||||
.has_lane_rst = true,
|
||||
@ -2678,6 +2892,7 @@ static const struct qmp_phy_cfg msm8996_ufs_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.no_pcs_sw_reset = true,
|
||||
};
|
||||
@ -2704,6 +2919,7 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const char * const ipq8074_pciephy_clk_l[] = {
|
||||
@ -2734,6 +2950,37 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
|
||||
.num_vregs = 0,
|
||||
.regs = pciephy_regs_layout,
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_phy_com_ctrl = false,
|
||||
.has_lane_rst = false,
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
.pwrdn_delay_max = 1005, /* us */
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
|
||||
.type = PHY_TYPE_PCIE,
|
||||
.nlanes = 1,
|
||||
|
||||
.serdes_tbl = ipq6018_pcie_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
|
||||
.tx_tbl = ipq6018_pcie_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
|
||||
.rx_tbl = ipq6018_pcie_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(ipq6018_pcie_rx_tbl),
|
||||
.pcs_tbl = ipq6018_pcie_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
|
||||
.clk_list = ipq8074_pciephy_clk_l,
|
||||
.num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l),
|
||||
.reset_list = ipq8074_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
|
||||
.vreg_list = NULL,
|
||||
.num_vregs = 0,
|
||||
.regs = ipq_pciephy_gen3_regs_layout,
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
|
||||
@ -2768,6 +3015,7 @@ static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
|
||||
|
||||
.start_ctrl = PCS_START | SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
@ -2796,6 +3044,7 @@ static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
|
||||
|
||||
.start_ctrl = PCS_START | SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
@ -2834,6 +3083,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
|
||||
|
||||
.start_ctrl = PCS_START | SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
@ -2872,6 +3122,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
|
||||
|
||||
.start_ctrl = PCS_START | SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
.has_pwrdn_delay = true,
|
||||
@ -2901,6 +3152,7 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -2932,6 +3184,7 @@ static const struct qmp_phy_cfg sc7180_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3003,6 +3256,7 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3029,6 +3283,7 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
.no_pcs_sw_reset = true,
|
||||
@ -3056,6 +3311,7 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
|
||||
@ -3080,6 +3336,7 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
};
|
||||
@ -3104,6 +3361,7 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
};
|
||||
@ -3130,6 +3388,8 @@ static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3161,6 +3421,7 @@ static const struct qmp_phy_cfg sm8150_usb3_uniphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3189,6 +3450,7 @@ static const struct qmp_phy_cfg sm8250_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3220,6 +3482,7 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3288,12 +3551,45 @@ static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
.pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
|
||||
.type = PHY_TYPE_PCIE,
|
||||
.nlanes = 2,
|
||||
|
||||
.serdes_tbl = sdx55_qmp_pcie_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
|
||||
.tx_tbl = sdx55_qmp_pcie_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(sdx55_qmp_pcie_tx_tbl),
|
||||
.rx_tbl = sdx55_qmp_pcie_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(sdx55_qmp_pcie_rx_tbl),
|
||||
.pcs_tbl = sdx55_qmp_pcie_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(sdx55_qmp_pcie_pcs_tbl),
|
||||
.pcs_misc_tbl = sdx55_qmp_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl),
|
||||
.clk_list = sdm845_pciephy_clk_l,
|
||||
.num_clks = ARRAY_SIZE(sdm845_pciephy_clk_l),
|
||||
.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 = sm8250_pcie_regs_layout,
|
||||
|
||||
.start_ctrl = PCS_START | SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
.pwrdn_delay_max = 1005, /* us */
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
|
||||
.type = PHY_TYPE_UFS,
|
||||
.nlanes = 2,
|
||||
@ -3314,6 +3610,7 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.is_dual_lane_phy = true,
|
||||
};
|
||||
@ -3340,6 +3637,7 @@ static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3371,6 +3669,7 @@ static const struct qmp_phy_cfg sm8350_usb3_uniphy_cfg = {
|
||||
|
||||
.start_ctrl = SERDES_START | PCS_START,
|
||||
.pwrdn_ctrl = SW_PWRDN,
|
||||
.phy_status = PHYSTATUS,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = POWER_DOWN_DELAY_US_MIN,
|
||||
@ -3993,10 +4292,8 @@ static int qcom_qmp_phy_com_init(struct qmp_phy *qphy)
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
|
||||
if (ret)
|
||||
goto err_rst;
|
||||
}
|
||||
|
||||
if (cfg->has_phy_dp_com_ctrl) {
|
||||
qphy_setbits(dp_com, QPHY_V3_DP_COM_POWER_DOWN_CTRL,
|
||||
@ -4238,7 +4535,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
|
||||
ready = PCS_READY;
|
||||
} else {
|
||||
status = pcs + cfg->regs[QPHY_PCS_STATUS];
|
||||
mask = PHYSTATUS;
|
||||
mask = cfg->phy_status;
|
||||
ready = 0;
|
||||
}
|
||||
|
||||
@ -4430,10 +4727,8 @@ static int __maybe_unused qcom_qmp_phy_runtime_resume(struct device *dev)
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
|
||||
if (ret) {
|
||||
dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(qphy->pipe_clk);
|
||||
if (ret) {
|
||||
@ -4927,6 +5222,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,ipq8074-qmp-pcie-phy",
|
||||
.data = &ipq8074_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,ipq6018-qmp-pcie-phy",
|
||||
.data = &ipq6018_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sc7180-qmp-usb3-phy",
|
||||
.data = &sc7180_usb3phy_cfg,
|
||||
@ -4990,6 +5288,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sm8250-qmp-modem-pcie-phy",
|
||||
.data = &sm8250_qmp_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sdx55-qmp-pcie-phy",
|
||||
.data = &sdx55_qmp_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sdx55-qmp-usb3-uni-phy",
|
||||
.data = &sdx55_usb3_uniphy_cfg,
|
||||
|
@ -6,6 +6,138 @@
|
||||
#ifndef QCOM_PHY_QMP_H_
|
||||
#define QCOM_PHY_QMP_H_
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - QSERDES PLL registers */
|
||||
|
||||
#define QSERDES_PLL_BG_TIMER 0x00c
|
||||
#define QSERDES_PLL_SSC_PER1 0x01c
|
||||
#define QSERDES_PLL_SSC_PER2 0x020
|
||||
#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
|
||||
#define QSERDES_PLL_SSC_STEP_SIZE2_MODE0 0x028
|
||||
#define QSERDES_PLL_SSC_STEP_SIZE1_MODE1 0x02c
|
||||
#define QSERDES_PLL_SSC_STEP_SIZE2_MODE1 0x030
|
||||
#define QSERDES_PLL_BIAS_EN_CLKBUFLR_EN 0x03c
|
||||
#define QSERDES_PLL_CLK_ENABLE1 0x040
|
||||
#define QSERDES_PLL_SYS_CLK_CTRL 0x044
|
||||
#define QSERDES_PLL_SYSCLK_BUF_ENABLE 0x048
|
||||
#define QSERDES_PLL_PLL_IVCO 0x050
|
||||
#define QSERDES_PLL_LOCK_CMP1_MODE0 0x054
|
||||
#define QSERDES_PLL_LOCK_CMP2_MODE0 0x058
|
||||
#define QSERDES_PLL_LOCK_CMP1_MODE1 0x060
|
||||
#define QSERDES_PLL_LOCK_CMP2_MODE1 0x064
|
||||
#define QSERDES_PLL_BG_TRIM 0x074
|
||||
#define QSERDES_PLL_CLK_EP_DIV_MODE0 0x078
|
||||
#define QSERDES_PLL_CLK_EP_DIV_MODE1 0x07c
|
||||
#define QSERDES_PLL_CP_CTRL_MODE0 0x080
|
||||
#define QSERDES_PLL_CP_CTRL_MODE1 0x084
|
||||
#define QSERDES_PLL_PLL_RCTRL_MODE0 0x088
|
||||
#define QSERDES_PLL_PLL_RCTRL_MODE1 0x08C
|
||||
#define QSERDES_PLL_PLL_CCTRL_MODE0 0x090
|
||||
#define QSERDES_PLL_PLL_CCTRL_MODE1 0x094
|
||||
#define QSERDES_PLL_BIAS_EN_CTRL_BY_PSM 0x0a4
|
||||
#define QSERDES_PLL_SYSCLK_EN_SEL 0x0a8
|
||||
#define QSERDES_PLL_RESETSM_CNTRL 0x0b0
|
||||
#define QSERDES_PLL_LOCK_CMP_EN 0x0c4
|
||||
#define QSERDES_PLL_DEC_START_MODE0 0x0cc
|
||||
#define QSERDES_PLL_DEC_START_MODE1 0x0d0
|
||||
#define QSERDES_PLL_DIV_FRAC_START1_MODE0 0x0d8
|
||||
#define QSERDES_PLL_DIV_FRAC_START2_MODE0 0x0dc
|
||||
#define QSERDES_PLL_DIV_FRAC_START3_MODE0 0x0e0
|
||||
#define QSERDES_PLL_DIV_FRAC_START1_MODE1 0x0e4
|
||||
#define QSERDES_PLL_DIV_FRAC_START2_MODE1 0x0e8
|
||||
#define QSERDES_PLL_DIV_FRAC_START3_MODE1 0x0eC
|
||||
#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE0 0x100
|
||||
#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE0 0x104
|
||||
#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE1 0x108
|
||||
#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE1 0x10c
|
||||
#define QSERDES_PLL_VCO_TUNE_MAP 0x120
|
||||
#define QSERDES_PLL_VCO_TUNE1_MODE0 0x124
|
||||
#define QSERDES_PLL_VCO_TUNE2_MODE0 0x128
|
||||
#define QSERDES_PLL_VCO_TUNE1_MODE1 0x12c
|
||||
#define QSERDES_PLL_VCO_TUNE2_MODE1 0x130
|
||||
#define QSERDES_PLL_VCO_TUNE_TIMER1 0x13c
|
||||
#define QSERDES_PLL_VCO_TUNE_TIMER2 0x140
|
||||
#define QSERDES_PLL_CLK_SELECT 0x16c
|
||||
#define QSERDES_PLL_HSCLK_SEL 0x170
|
||||
#define QSERDES_PLL_CORECLK_DIV 0x17c
|
||||
#define QSERDES_PLL_CORE_CLK_EN 0x184
|
||||
#define QSERDES_PLL_CMN_CONFIG 0x18c
|
||||
#define QSERDES_PLL_SVS_MODE_CLK_SEL 0x194
|
||||
#define QSERDES_PLL_CORECLK_DIV_MODE1 0x1b4
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - QSERDES TX registers */
|
||||
|
||||
#define QSERDES_TX0_RES_CODE_LANE_OFFSET_TX 0x03c
|
||||
#define QSERDES_TX0_HIGHZ_DRVR_EN 0x058
|
||||
#define QSERDES_TX0_LANE_MODE_1 0x084
|
||||
#define QSERDES_TX0_RCV_DETECT_LVL_2 0x09c
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - QSERDES RX registers */
|
||||
|
||||
#define QSERDES_RX0_UCDR_FO_GAIN 0x008
|
||||
#define QSERDES_RX0_UCDR_SO_GAIN 0x014
|
||||
#define QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE 0x034
|
||||
#define QSERDES_RX0_UCDR_PI_CONTROLS 0x044
|
||||
#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2 0x0ec
|
||||
#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3 0x0f0
|
||||
#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4 0x0f4
|
||||
#define QSERDES_RX0_RX_IDAC_TSETTLE_LOW 0x0f8
|
||||
#define QSERDES_RX0_RX_IDAC_TSETTLE_HIGH 0x0fc
|
||||
#define QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
|
||||
#define QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2 0x114
|
||||
#define QSERDES_RX0_SIGDET_ENABLES 0x118
|
||||
#define QSERDES_RX0_SIGDET_CNTRL 0x11c
|
||||
#define QSERDES_RX0_SIGDET_DEGLITCH_CNTRL 0x124
|
||||
#define QSERDES_RX0_RX_MODE_00_LOW 0x170
|
||||
#define QSERDES_RX0_RX_MODE_00_HIGH 0x174
|
||||
#define QSERDES_RX0_RX_MODE_00_HIGH2 0x178
|
||||
#define QSERDES_RX0_RX_MODE_00_HIGH3 0x17c
|
||||
#define QSERDES_RX0_RX_MODE_00_HIGH4 0x180
|
||||
#define QSERDES_RX0_RX_MODE_01_LOW 0x184
|
||||
#define QSERDES_RX0_RX_MODE_01_HIGH 0x188
|
||||
#define QSERDES_RX0_RX_MODE_01_HIGH2 0x18c
|
||||
#define QSERDES_RX0_RX_MODE_01_HIGH3 0x190
|
||||
#define QSERDES_RX0_RX_MODE_01_HIGH4 0x194
|
||||
#define QSERDES_RX0_RX_MODE_10_LOW 0x198
|
||||
#define QSERDES_RX0_RX_MODE_10_HIGH 0x19c
|
||||
#define QSERDES_RX0_RX_MODE_10_HIGH2 0x1a0
|
||||
#define QSERDES_RX0_RX_MODE_10_HIGH3 0x1a4
|
||||
#define QSERDES_RX0_RX_MODE_10_HIGH4 0x1a8
|
||||
#define QSERDES_RX0_DFE_EN_TIMER 0x1b4
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - PCS registers */
|
||||
|
||||
#define PCS_COM_FLL_CNTRL1 0x098
|
||||
#define PCS_COM_FLL_CNTRL2 0x09c
|
||||
#define PCS_COM_FLL_CNT_VAL_L 0x0a0
|
||||
#define PCS_COM_FLL_CNT_VAL_H_TOL 0x0a4
|
||||
#define PCS_COM_FLL_MAN_CODE 0x0a8
|
||||
#define PCS_COM_REFGEN_REQ_CONFIG1 0x0dc
|
||||
#define PCS_COM_G12S1_TXDEEMPH_M3P5DB 0x16c
|
||||
#define PCS_COM_RX_SIGDET_LVL 0x188
|
||||
#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x1a4
|
||||
#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x1a8
|
||||
#define PCS_COM_RX_DCC_CAL_CONFIG 0x1d8
|
||||
#define PCS_COM_EQ_CONFIG5 0x1ec
|
||||
|
||||
/* QMP V2 PHY for PCIE gen3 ports - PCS Misc registers */
|
||||
|
||||
#define PCS_PCIE_POWER_STATE_CONFIG2 0x40c
|
||||
#define PCS_PCIE_POWER_STATE_CONFIG4 0x414
|
||||
#define PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x41c
|
||||
#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x440
|
||||
#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0x444
|
||||
#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x448
|
||||
#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0x44c
|
||||
#define PCS_PCIE_OSC_DTCT_CONFIG2 0x45c
|
||||
#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0x478
|
||||
#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0x480
|
||||
#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0x484
|
||||
#define PCS_PCIE_OSC_DTCT_ACTIONS 0x490
|
||||
#define PCS_PCIE_EQ_CONFIG1 0x4a0
|
||||
#define PCS_PCIE_EQ_CONFIG2 0x4a4
|
||||
#define PCS_PCIE_PRESET_P10_PRE 0x4bc
|
||||
#define PCS_PCIE_PRESET_P10_POST 0x4e0
|
||||
|
||||
/* Only for QMP V2 PHY - QSERDES COM registers */
|
||||
#define QSERDES_COM_BG_TIMER 0x00c
|
||||
#define QSERDES_COM_SSC_EN_CENTER 0x010
|
||||
@ -420,6 +552,7 @@
|
||||
#define QSERDES_V4_COM_SYSCLK_EN_SEL 0x094
|
||||
#define QSERDES_V4_COM_RESETSM_CNTRL 0x09c
|
||||
#define QSERDES_V4_COM_LOCK_CMP_EN 0x0a4
|
||||
#define QSERDES_V4_COM_LOCK_CMP_CFG 0x0a8
|
||||
#define QSERDES_V4_COM_LOCK_CMP1_MODE0 0x0ac
|
||||
#define QSERDES_V4_COM_LOCK_CMP2_MODE0 0x0b0
|
||||
#define QSERDES_V4_COM_LOCK_CMP1_MODE1 0x0b4
|
||||
@ -434,6 +567,8 @@
|
||||
#define QSERDES_V4_COM_DIV_FRAC_START3_MODE1 0x0e0
|
||||
#define QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0 0x0ec
|
||||
#define QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0 0x0f0
|
||||
#define QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1 0x0f4
|
||||
#define QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1 0x0f8
|
||||
#define QSERDES_V4_COM_VCO_TUNE_CTRL 0x108
|
||||
#define QSERDES_V4_COM_VCO_TUNE_MAP 0x10c
|
||||
#define QSERDES_V4_COM_VCO_TUNE1_MODE0 0x110
|
||||
@ -451,11 +586,15 @@
|
||||
#define QSERDES_V4_COM_C_READY_STATUS 0x178
|
||||
#define QSERDES_V4_COM_CMN_CONFIG 0x17c
|
||||
#define QSERDES_V4_COM_SVS_MODE_CLK_SEL 0x184
|
||||
#define QSERDES_V4_COM_CMN_MISC1 0x19c
|
||||
#define QSERDES_V4_COM_INTERNAL_DIG_CORECLK_DIV 0x1a0
|
||||
#define QSERDES_V4_COM_CMN_MODE 0x1a4
|
||||
#define QSERDES_V4_COM_VCO_DC_LEVEL_CTRL 0x1a8
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x1b4
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL 0x1bc
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x1b8
|
||||
#define QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL 0x1bc
|
||||
|
||||
/* Only for QMP V4 PHY - TX registers */
|
||||
#define QSERDES_V4_TX_CLKBUF_ENABLE 0x08
|
||||
@ -485,6 +624,13 @@
|
||||
#define QSERDES_V4_TX_VMODE_CTRL1 0xe8
|
||||
#define QSERDES_V4_TX_PI_QEC_CTRL 0x104
|
||||
|
||||
/* Only for QMP V4_20 PHY - TX registers */
|
||||
#define QSERDES_V4_20_TX_LANE_MODE_1 0x88
|
||||
#define QSERDES_V4_20_TX_LANE_MODE_2 0x8c
|
||||
#define QSERDES_V4_20_TX_LANE_MODE_3 0x90
|
||||
#define QSERDES_V4_20_TX_VMODE_CTRL1 0xc4
|
||||
#define QSERDES_V4_20_TX_PI_QEC_CTRL 0xe0
|
||||
|
||||
/* Only for QMP V4 PHY - RX registers */
|
||||
#define QSERDES_V4_RX_UCDR_FO_GAIN 0x008
|
||||
#define QSERDES_V4_RX_UCDR_SO_GAIN 0x014
|
||||
@ -551,6 +697,33 @@
|
||||
#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS 0x0d8
|
||||
#define QSERDES_V4_DP_PHY_STATUS 0x0dc
|
||||
|
||||
/* Only for QMP V4_20 PHY - RX registers */
|
||||
#define QSERDES_V4_20_RX_FO_GAIN_RATE2 0x008
|
||||
#define QSERDES_V4_20_RX_UCDR_PI_CONTROLS 0x058
|
||||
#define QSERDES_V4_20_RX_AUX_DATA_TCOARSE_TFINE 0x0ac
|
||||
#define QSERDES_V4_20_RX_DFE_3 0x110
|
||||
#define QSERDES_V4_20_RX_DFE_DAC_ENABLE1 0x134
|
||||
#define QSERDES_V4_20_RX_DFE_DAC_ENABLE2 0x138
|
||||
#define QSERDES_V4_20_RX_VGA_CAL_CNTRL2 0x150
|
||||
#define QSERDES_V4_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x178
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B1 0x1c8
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B2 0x1cc
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B3 0x1d0
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE_0_1_B4 0x1d4
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE2_B0 0x1d8
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE2_B1 0x1dc
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE2_B2 0x1e0
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE2_B3 0x1e4
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE2_B4 0x1e8
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE3_B0 0x1ec
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE3_B1 0x1f0
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE3_B2 0x1f4
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE3_B3 0x1f8
|
||||
#define QSERDES_V4_20_RX_RX_MODE_RATE3_B4 0x1fc
|
||||
#define QSERDES_V4_20_RX_PHPRE_CTRL 0x200
|
||||
#define QSERDES_V4_20_RX_DFE_CTLE_POST_CAL_OFFSET 0x20c
|
||||
#define QSERDES_V4_20_RX_MARG_COARSE_CTRL2 0x23c
|
||||
|
||||
/* Only for QMP V4 PHY - UFS PCS registers */
|
||||
#define QPHY_V4_PCS_UFS_PHY_START 0x000
|
||||
#define QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL 0x004
|
||||
@ -836,6 +1009,12 @@
|
||||
#define QPHY_V4_PCS_USB3_SIGDET_STARTUP_TIMER_VAL 0x354
|
||||
#define QPHY_V4_PCS_USB3_TEST_CONTROL 0x358
|
||||
|
||||
/* Only for QMP V4_20 PHY - USB/PCIe PCS registers */
|
||||
#define QPHY_V4_20_PCS_RX_SIGDET_LVL 0x188
|
||||
#define QPHY_V4_20_PCS_EQ_CONFIG2 0x1d8
|
||||
#define QPHY_V4_20_PCS_EQ_CONFIG4 0x1e0
|
||||
#define QPHY_V4_20_PCS_EQ_CONFIG5 0x1e4
|
||||
|
||||
/* Only for QMP V4 PHY - UNI has 0x300 offset for PCS_USB3 regs */
|
||||
#define QPHY_V4_PCS_USB3_UNI_LFPS_DET_HIGH_COUNT_VAL 0x618
|
||||
#define QPHY_V4_PCS_USB3_UNI_RXEQTRAINING_DFE_TIME_S2 0x638
|
||||
@ -861,6 +1040,14 @@
|
||||
#define QPHY_V4_PCS_PCIE_PRESET_P10_PRE 0xbc
|
||||
#define QPHY_V4_PCS_PCIE_PRESET_P10_POST 0xe0
|
||||
|
||||
#define QPHY_V4_20_PCS_PCIE_EQ_CONFIG1 0x0a0
|
||||
#define QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME 0x0f0
|
||||
#define QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME 0x0f4
|
||||
#define QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2 0x0fc
|
||||
#define QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5 0x108
|
||||
#define QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2 0x824
|
||||
#define QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2 0x828
|
||||
|
||||
/* Only for QMP V5 PHY - QSERDES COM registers */
|
||||
#define QSERDES_V5_COM_PLL_IVCO 0x058
|
||||
#define QSERDES_V5_COM_CP_CTRL_MODE0 0x074
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
config PHY_MT7621_PCI
|
||||
tristate "MediaTek MT7621 PCI PHY Driver"
|
||||
depends on RALINK && OF
|
||||
depends on (RALINK && OF) || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
@ -14,8 +15,6 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <mt7621.h>
|
||||
#include <ralink_regs.h>
|
||||
|
||||
#define RG_PE1_PIPE_REG 0x02c
|
||||
#define RG_PE1_PIPE_RST BIT(12)
|
||||
@ -62,8 +61,6 @@
|
||||
|
||||
#define RG_PE1_FRC_MSTCKDIV BIT(5)
|
||||
|
||||
#define XTAL_MASK GENMASK(8, 6)
|
||||
|
||||
#define MAX_PHYS 2
|
||||
|
||||
/**
|
||||
@ -71,6 +68,7 @@
|
||||
* @dev: pointer to device
|
||||
* @regmap: kernel regmap pointer
|
||||
* @phy: pointer to the kernel PHY device
|
||||
* @sys_clk: pointer to the system XTAL clock
|
||||
* @port_base: base register
|
||||
* @has_dual_port: if the phy has dual ports.
|
||||
* @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst'
|
||||
@ -80,6 +78,7 @@ struct mt7621_pci_phy {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct phy *phy;
|
||||
struct clk *sys_clk;
|
||||
void __iomem *port_base;
|
||||
bool has_dual_port;
|
||||
bool bypass_pipe_rst;
|
||||
@ -116,12 +115,14 @@ static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
|
||||
}
|
||||
}
|
||||
|
||||
static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
static int mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
{
|
||||
struct device *dev = phy->dev;
|
||||
u32 xtal_mode;
|
||||
unsigned long clk_rate;
|
||||
|
||||
xtal_mode = FIELD_GET(XTAL_MASK, rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0));
|
||||
clk_rate = clk_get_rate(phy->sys_clk);
|
||||
if (!clk_rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Set PCIe Port PHY to disable SSC */
|
||||
/* Debug Xtal Type */
|
||||
@ -139,13 +140,13 @@ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
|
||||
}
|
||||
|
||||
if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
|
||||
if (clk_rate == 40000000) { /* 40MHz Xtal */
|
||||
/* Set Pre-divider ratio (for host mode) */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
|
||||
FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x01));
|
||||
|
||||
dev_dbg(dev, "Xtal is 40MHz\n");
|
||||
} else if (xtal_mode >= 6) { /* 25MHz Xal */
|
||||
} else if (clk_rate == 25000000) { /* 25MHz Xal */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
|
||||
FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00));
|
||||
|
||||
@ -196,13 +197,15 @@ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, RG_PE1_H_PLL_BR,
|
||||
FIELD_PREP(RG_PE1_H_PLL_BR, 0x00));
|
||||
|
||||
if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
|
||||
if (clk_rate == 40000000) { /* 40MHz Xtal */
|
||||
/* set force mode enable of da_pe1_mstckdiv */
|
||||
mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
|
||||
RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
|
||||
FIELD_PREP(RG_PE1_MSTCKDIV, 0x01) |
|
||||
RG_PE1_FRC_MSTCKDIV);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_pci_phy_init(struct phy *phy)
|
||||
@ -212,9 +215,7 @@ static int mt7621_pci_phy_init(struct phy *phy)
|
||||
if (mphy->bypass_pipe_rst)
|
||||
mt7621_bypass_pipe_rst(mphy);
|
||||
|
||||
mt7621_set_phy_for_ssc(mphy);
|
||||
|
||||
return 0;
|
||||
return mt7621_set_phy_for_ssc(mphy);
|
||||
}
|
||||
|
||||
static int mt7621_pci_phy_power_on(struct phy *phy)
|
||||
@ -272,8 +273,8 @@ static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
|
||||
|
||||
mt7621_phy->has_dual_port = args->args[0];
|
||||
|
||||
dev_info(dev, "PHY for 0x%08x (dual port = %d)\n",
|
||||
(unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port);
|
||||
dev_dbg(dev, "PHY for 0x%px (dual port = %d)\n",
|
||||
mt7621_phy->port_base, mt7621_phy->has_dual_port);
|
||||
|
||||
return mt7621_phy->phy;
|
||||
}
|
||||
@ -324,6 +325,12 @@ static int mt7621_pci_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(phy->phy);
|
||||
}
|
||||
|
||||
phy->sys_clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(phy->sys_clk)) {
|
||||
dev_err(dev, "failed to get phy clock\n");
|
||||
return PTR_ERR(phy->sys_clk);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy->phy, phy);
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate);
|
||||
|
@ -48,6 +48,15 @@ config PHY_ROCKCHIP_INNO_USB2
|
||||
help
|
||||
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
|
||||
|
||||
config PHY_ROCKCHIP_INNO_CSIDPHY
|
||||
tristate "Rockchip Innosilicon MIPI CSI PHY driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
select GENERIC_PHY
|
||||
select GENERIC_PHY_MIPI_DPHY
|
||||
help
|
||||
Enable this to support the Rockchip MIPI CSI PHY with
|
||||
Innosilicon IP block.
|
||||
|
||||
config PHY_ROCKCHIP_INNO_DSIDPHY
|
||||
tristate "Rockchip Innosilicon MIPI/LVDS/TTL PHY driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
|
@ -2,6 +2,7 @@
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY) += phy-rockchip-inno-csidphy.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
|
||||
|
459
drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
Normal file
459
drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
Normal file
@ -0,0 +1,459 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Rockchip MIPI RX Innosilicon DPHY driver
|
||||
*
|
||||
* Copyright (C) 2021 Fuzhou Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/phy/phy-mipi-dphy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
/* GRF */
|
||||
#define RK1808_GRF_PD_VI_CON_OFFSET 0x0430
|
||||
|
||||
#define RK3326_GRF_PD_VI_CON_OFFSET 0x0430
|
||||
|
||||
#define RK3368_GRF_SOC_CON6_OFFSET 0x0418
|
||||
|
||||
/* PHY */
|
||||
#define CSIDPHY_CTRL_LANE_ENABLE 0x00
|
||||
#define CSIDPHY_CTRL_LANE_ENABLE_CK BIT(6)
|
||||
#define CSIDPHY_CTRL_LANE_ENABLE_MASK GENMASK(5, 2)
|
||||
#define CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED BIT(0)
|
||||
|
||||
/* not present on all variants */
|
||||
#define CSIDPHY_CTRL_PWRCTL 0x04
|
||||
#define CSIDPHY_CTRL_PWRCTL_UNDEFINED GENMASK(7, 5)
|
||||
#define CSIDPHY_CTRL_PWRCTL_SYNCRST BIT(2)
|
||||
#define CSIDPHY_CTRL_PWRCTL_LDO_PD BIT(1)
|
||||
#define CSIDPHY_CTRL_PWRCTL_PLL_PD BIT(0)
|
||||
|
||||
#define CSIDPHY_CTRL_DIG_RST 0x80
|
||||
#define CSIDPHY_CTRL_DIG_RST_UNDEFINED 0x1e
|
||||
#define CSIDPHY_CTRL_DIG_RST_RESET BIT(0)
|
||||
|
||||
/* offset after ths_settle_offset */
|
||||
#define CSIDPHY_CLK_THS_SETTLE 0
|
||||
#define CSIDPHY_LANE_THS_SETTLE(n) (((n) + 1) * 0x80)
|
||||
#define CSIDPHY_THS_SETTLE_MASK GENMASK(6, 0)
|
||||
|
||||
/* offset after calib_offset */
|
||||
#define CSIDPHY_CLK_CALIB_EN 0
|
||||
#define CSIDPHY_LANE_CALIB_EN(n) (((n) + 1) * 0x80)
|
||||
#define CSIDPHY_CALIB_EN BIT(7)
|
||||
|
||||
/* Configure the count time of the THS-SETTLE by protocol. */
|
||||
#define RK1808_CSIDPHY_CLK_WR_THS_SETTLE 0x160
|
||||
#define RK3326_CSIDPHY_CLK_WR_THS_SETTLE 0x100
|
||||
#define RK3368_CSIDPHY_CLK_WR_THS_SETTLE 0x100
|
||||
|
||||
/* Calibration reception enable */
|
||||
#define RK1808_CSIDPHY_CLK_CALIB_EN 0x168
|
||||
|
||||
/*
|
||||
* The higher 16-bit of this register is used for write protection
|
||||
* only if BIT(x + 16) set to 1 the BIT(x) can be written.
|
||||
*/
|
||||
#define HIWORD_UPDATE(val, mask, shift) \
|
||||
((val) << (shift) | (mask) << ((shift) + 16))
|
||||
|
||||
#define HZ_TO_MHZ(freq) div_u64(freq, 1000 * 1000)
|
||||
|
||||
enum dphy_reg_id {
|
||||
/* rk1808 & rk3326 */
|
||||
GRF_DPHY_CSIPHY_FORCERXMODE,
|
||||
GRF_DPHY_CSIPHY_CLKLANE_EN,
|
||||
GRF_DPHY_CSIPHY_DATALANE_EN,
|
||||
};
|
||||
|
||||
struct dphy_reg {
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 shift;
|
||||
};
|
||||
|
||||
#define PHY_REG(_offset, _width, _shift) \
|
||||
{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
|
||||
|
||||
static const struct dphy_reg rk1808_grf_dphy_regs[] = {
|
||||
[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0),
|
||||
[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 1, 8),
|
||||
[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 4),
|
||||
};
|
||||
|
||||
static const struct dphy_reg rk3326_grf_dphy_regs[] = {
|
||||
[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 0),
|
||||
[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 1, 8),
|
||||
[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 4),
|
||||
};
|
||||
|
||||
static const struct dphy_reg rk3368_grf_dphy_regs[] = {
|
||||
[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3368_GRF_SOC_CON6_OFFSET, 4, 8),
|
||||
};
|
||||
|
||||
struct hsfreq_range {
|
||||
u32 range_h;
|
||||
u8 cfg_bit;
|
||||
};
|
||||
|
||||
struct dphy_drv_data {
|
||||
int pwrctl_offset;
|
||||
int ths_settle_offset;
|
||||
int calib_offset;
|
||||
const struct hsfreq_range *hsfreq_ranges;
|
||||
int num_hsfreq_ranges;
|
||||
const struct dphy_reg *grf_regs;
|
||||
};
|
||||
|
||||
struct rockchip_inno_csidphy {
|
||||
struct device *dev;
|
||||
void __iomem *phy_base;
|
||||
struct clk *pclk;
|
||||
struct regmap *grf;
|
||||
struct reset_control *rst;
|
||||
const struct dphy_drv_data *drv_data;
|
||||
struct phy_configure_opts_mipi_dphy config;
|
||||
u8 hsfreq;
|
||||
};
|
||||
|
||||
static inline void write_grf_reg(struct rockchip_inno_csidphy *priv,
|
||||
int index, u8 value)
|
||||
{
|
||||
const struct dphy_drv_data *drv_data = priv->drv_data;
|
||||
const struct dphy_reg *reg = &drv_data->grf_regs[index];
|
||||
|
||||
if (reg->offset)
|
||||
regmap_write(priv->grf, reg->offset,
|
||||
HIWORD_UPDATE(value, reg->mask, reg->shift));
|
||||
}
|
||||
|
||||
/* These tables must be sorted by .range_h ascending. */
|
||||
static const struct hsfreq_range rk1808_mipidphy_hsfreq_ranges[] = {
|
||||
{ 109, 0x02}, { 149, 0x03}, { 199, 0x06}, { 249, 0x06},
|
||||
{ 299, 0x06}, { 399, 0x08}, { 499, 0x0b}, { 599, 0x0e},
|
||||
{ 699, 0x10}, { 799, 0x12}, { 999, 0x16}, {1199, 0x1e},
|
||||
{1399, 0x23}, {1599, 0x2d}, {1799, 0x32}, {1999, 0x37},
|
||||
{2199, 0x3c}, {2399, 0x41}, {2499, 0x46}
|
||||
};
|
||||
|
||||
static const struct hsfreq_range rk3326_mipidphy_hsfreq_ranges[] = {
|
||||
{ 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03},
|
||||
{ 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07},
|
||||
{ 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b},
|
||||
{1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e}
|
||||
};
|
||||
|
||||
static const struct hsfreq_range rk3368_mipidphy_hsfreq_ranges[] = {
|
||||
{ 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03},
|
||||
{ 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07},
|
||||
{ 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b},
|
||||
{1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e}
|
||||
};
|
||||
|
||||
static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv,
|
||||
int hsfreq, int offset)
|
||||
{
|
||||
const struct dphy_drv_data *drv_data = priv->drv_data;
|
||||
u32 val;
|
||||
|
||||
val = readl(priv->phy_base + drv_data->ths_settle_offset + offset);
|
||||
val &= ~CSIDPHY_THS_SETTLE_MASK;
|
||||
val |= hsfreq;
|
||||
writel(val, priv->phy_base + drv_data->ths_settle_offset + offset);
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_configure(struct phy *phy,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
|
||||
const struct dphy_drv_data *drv_data = priv->drv_data;
|
||||
struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy;
|
||||
unsigned int hsfreq = 0;
|
||||
unsigned int i;
|
||||
u64 data_rate_mbps;
|
||||
int ret;
|
||||
|
||||
/* pass with phy_mipi_dphy_get_default_config (with pixel rate?) */
|
||||
ret = phy_mipi_dphy_config_validate(config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data_rate_mbps = HZ_TO_MHZ(config->hs_clk_rate);
|
||||
|
||||
dev_dbg(priv->dev, "lanes %d - data_rate_mbps %llu\n",
|
||||
config->lanes, data_rate_mbps);
|
||||
for (i = 0; i < drv_data->num_hsfreq_ranges; i++) {
|
||||
if (drv_data->hsfreq_ranges[i].range_h >= data_rate_mbps) {
|
||||
hsfreq = drv_data->hsfreq_ranges[i].cfg_bit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hsfreq)
|
||||
return -EINVAL;
|
||||
|
||||
priv->hsfreq = hsfreq;
|
||||
priv->config = *config;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_power_on(struct phy *phy)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
|
||||
const struct dphy_drv_data *drv_data = priv->drv_data;
|
||||
u64 data_rate_mbps = HZ_TO_MHZ(priv->config.hs_clk_rate);
|
||||
u32 val;
|
||||
int ret, i;
|
||||
|
||||
ret = clk_enable(priv->pclk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(priv->dev);
|
||||
if (ret < 0) {
|
||||
clk_disable(priv->pclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* phy start */
|
||||
if (drv_data->pwrctl_offset >= 0)
|
||||
writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED |
|
||||
CSIDPHY_CTRL_PWRCTL_SYNCRST,
|
||||
priv->phy_base + drv_data->pwrctl_offset);
|
||||
|
||||
/* set data lane num and enable clock lane */
|
||||
val = FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_MASK, GENMASK(priv->config.lanes - 1, 0)) |
|
||||
FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_CK, 1) |
|
||||
FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED, 1);
|
||||
writel(val, priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE);
|
||||
|
||||
/* Reset dphy analog part */
|
||||
if (drv_data->pwrctl_offset >= 0)
|
||||
writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED,
|
||||
priv->phy_base + drv_data->pwrctl_offset);
|
||||
usleep_range(500, 1000);
|
||||
|
||||
/* Reset dphy digital part */
|
||||
writel(CSIDPHY_CTRL_DIG_RST_UNDEFINED,
|
||||
priv->phy_base + CSIDPHY_CTRL_DIG_RST);
|
||||
writel(CSIDPHY_CTRL_DIG_RST_UNDEFINED + CSIDPHY_CTRL_DIG_RST_RESET,
|
||||
priv->phy_base + CSIDPHY_CTRL_DIG_RST);
|
||||
|
||||
/* not into receive mode/wait stopstate */
|
||||
write_grf_reg(priv, GRF_DPHY_CSIPHY_FORCERXMODE, 0x0);
|
||||
|
||||
/* enable calibration */
|
||||
if (data_rate_mbps > 1500 && drv_data->calib_offset >= 0) {
|
||||
writel(CSIDPHY_CALIB_EN,
|
||||
priv->phy_base + drv_data->calib_offset +
|
||||
CSIDPHY_CLK_CALIB_EN);
|
||||
for (i = 0; i < priv->config.lanes; i++)
|
||||
writel(CSIDPHY_CALIB_EN,
|
||||
priv->phy_base + drv_data->calib_offset +
|
||||
CSIDPHY_LANE_CALIB_EN(i));
|
||||
}
|
||||
|
||||
rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq,
|
||||
CSIDPHY_CLK_THS_SETTLE);
|
||||
for (i = 0; i < priv->config.lanes; i++)
|
||||
rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq,
|
||||
CSIDPHY_LANE_THS_SETTLE(i));
|
||||
|
||||
write_grf_reg(priv, GRF_DPHY_CSIPHY_CLKLANE_EN, 0x1);
|
||||
write_grf_reg(priv, GRF_DPHY_CSIPHY_DATALANE_EN,
|
||||
GENMASK(priv->config.lanes - 1, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_power_off(struct phy *phy)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
|
||||
const struct dphy_drv_data *drv_data = priv->drv_data;
|
||||
|
||||
/* disable all lanes */
|
||||
writel(CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED,
|
||||
priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE);
|
||||
|
||||
/* disable pll and ldo */
|
||||
if (drv_data->pwrctl_offset >= 0)
|
||||
writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED |
|
||||
CSIDPHY_CTRL_PWRCTL_LDO_PD |
|
||||
CSIDPHY_CTRL_PWRCTL_PLL_PD,
|
||||
priv->phy_base + drv_data->pwrctl_offset);
|
||||
usleep_range(500, 1000);
|
||||
|
||||
pm_runtime_put(priv->dev);
|
||||
clk_disable(priv->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_init(struct phy *phy)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
|
||||
|
||||
return clk_prepare(priv->pclk);
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_exit(struct phy *phy)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
|
||||
|
||||
clk_unprepare(priv->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops rockchip_inno_csidphy_ops = {
|
||||
.power_on = rockchip_inno_csidphy_power_on,
|
||||
.power_off = rockchip_inno_csidphy_power_off,
|
||||
.init = rockchip_inno_csidphy_init,
|
||||
.exit = rockchip_inno_csidphy_exit,
|
||||
.configure = rockchip_inno_csidphy_configure,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct dphy_drv_data rk1808_mipidphy_drv_data = {
|
||||
.pwrctl_offset = -1,
|
||||
.ths_settle_offset = RK1808_CSIDPHY_CLK_WR_THS_SETTLE,
|
||||
.calib_offset = RK1808_CSIDPHY_CLK_CALIB_EN,
|
||||
.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
|
||||
.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
|
||||
.grf_regs = rk1808_grf_dphy_regs,
|
||||
};
|
||||
|
||||
static const struct dphy_drv_data rk3326_mipidphy_drv_data = {
|
||||
.pwrctl_offset = CSIDPHY_CTRL_PWRCTL,
|
||||
.ths_settle_offset = RK3326_CSIDPHY_CLK_WR_THS_SETTLE,
|
||||
.calib_offset = -1,
|
||||
.hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges,
|
||||
.num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges),
|
||||
.grf_regs = rk3326_grf_dphy_regs,
|
||||
};
|
||||
|
||||
static const struct dphy_drv_data rk3368_mipidphy_drv_data = {
|
||||
.pwrctl_offset = CSIDPHY_CTRL_PWRCTL,
|
||||
.ths_settle_offset = RK3368_CSIDPHY_CLK_WR_THS_SETTLE,
|
||||
.calib_offset = -1,
|
||||
.hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges,
|
||||
.num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges),
|
||||
.grf_regs = rk3368_grf_dphy_regs,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_inno_csidphy_match_id[] = {
|
||||
{
|
||||
.compatible = "rockchip,px30-csi-dphy",
|
||||
.data = &rk3326_mipidphy_drv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk1808-csi-dphy",
|
||||
.data = &rk1808_mipidphy_drv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3326-csi-dphy",
|
||||
.data = &rk3326_mipidphy_drv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3368-csi-dphy",
|
||||
.data = &rk3368_mipidphy_drv_data,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id);
|
||||
|
||||
static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct phy *phy;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
priv->drv_data = of_device_get_match_data(dev);
|
||||
if (!priv->drv_data) {
|
||||
dev_err(dev, "Can't find device data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"rockchip,grf");
|
||||
if (IS_ERR(priv->grf)) {
|
||||
dev_err(dev, "Can't find GRF syscon\n");
|
||||
return PTR_ERR(priv->grf);
|
||||
}
|
||||
|
||||
priv->phy_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->phy_base))
|
||||
return PTR_ERR(priv->phy_base);
|
||||
|
||||
priv->pclk = devm_clk_get(dev, "pclk");
|
||||
if (IS_ERR(priv->pclk)) {
|
||||
dev_err(dev, "failed to get pclk\n");
|
||||
return PTR_ERR(priv->pclk);
|
||||
}
|
||||
|
||||
priv->rst = devm_reset_control_get(dev, "apb");
|
||||
if (IS_ERR(priv->rst)) {
|
||||
dev_err(dev, "failed to get system reset control\n");
|
||||
return PTR_ERR(priv->rst);
|
||||
}
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create phy\n");
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, priv);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
dev_err(dev, "failed to register phy provider\n");
|
||||
return PTR_ERR(phy_provider);
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_inno_csidphy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_inno_csidphy *priv = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_disable(priv->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rockchip_inno_csidphy_driver = {
|
||||
.driver = {
|
||||
.name = "rockchip-inno-csidphy",
|
||||
.of_match_table = rockchip_inno_csidphy_match_id,
|
||||
},
|
||||
.probe = rockchip_inno_csidphy_probe,
|
||||
.remove = rockchip_inno_csidphy_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(rockchip_inno_csidphy_driver);
|
||||
MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>");
|
||||
MODULE_DESCRIPTION("Rockchip MIPI Innosilicon CSI-DPHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -620,7 +620,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
|
||||
const struct pre_pll_config *cfg = pre_pll_cfg_table;
|
||||
const struct pre_pll_config *cfg;
|
||||
unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
|
||||
u32 v;
|
||||
int ret;
|
||||
@ -774,7 +774,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
|
||||
const struct pre_pll_config *cfg = pre_pll_cfg_table;
|
||||
const struct pre_pll_config *cfg;
|
||||
unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
@ -1256,6 +1256,49 @@ static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
|
||||
{
|
||||
.reg = 0x100,
|
||||
.num_ports = 2,
|
||||
.clkout_ctl = { 0x108, 4, 4, 1, 0 },
|
||||
.port_cfgs = {
|
||||
[USB2PHY_PORT_OTG] = {
|
||||
.phy_sus = { 0x0100, 8, 0, 0, 0x1d1 },
|
||||
.bvalid_det_en = { 0x3020, 2, 2, 0, 1 },
|
||||
.bvalid_det_st = { 0x3024, 2, 2, 0, 1 },
|
||||
.bvalid_det_clr = { 0x3028, 2, 2, 0, 1 },
|
||||
.ls_det_en = { 0x3020, 0, 0, 0, 1 },
|
||||
.ls_det_st = { 0x3024, 0, 0, 0, 1 },
|
||||
.ls_det_clr = { 0x3028, 0, 0, 0, 1 },
|
||||
.utmi_avalid = { 0x0120, 10, 10, 0, 1 },
|
||||
.utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
|
||||
.utmi_ls = { 0x0120, 5, 4, 0, 1 },
|
||||
},
|
||||
[USB2PHY_PORT_HOST] = {
|
||||
.phy_sus = { 0x0104, 8, 0, 0, 0x1d1 },
|
||||
.ls_det_en = { 0x3020, 1, 1, 0, 1 },
|
||||
.ls_det_st = { 0x3024, 1, 1, 0, 1 },
|
||||
.ls_det_clr = { 0x3028, 1, 1, 0, 1 },
|
||||
.utmi_ls = { 0x0120, 17, 16, 0, 1 },
|
||||
.utmi_hstdet = { 0x0120, 19, 19, 0, 1 }
|
||||
}
|
||||
},
|
||||
.chg_det = {
|
||||
.opmode = { 0x0100, 3, 0, 5, 1 },
|
||||
.cp_det = { 0x0120, 24, 24, 0, 1 },
|
||||
.dcp_det = { 0x0120, 23, 23, 0, 1 },
|
||||
.dp_det = { 0x0120, 25, 25, 0, 1 },
|
||||
.idm_sink_en = { 0x0108, 8, 8, 0, 1 },
|
||||
.idp_sink_en = { 0x0108, 7, 7, 0, 1 },
|
||||
.idp_src_en = { 0x0108, 9, 9, 0, 1 },
|
||||
.rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
|
||||
.vdm_src_en = { 0x0108, 12, 12, 0, 1 },
|
||||
.vdp_src_en = { 0x0108, 11, 11, 0, 1 },
|
||||
},
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
|
||||
{
|
||||
.reg = 0x100,
|
||||
@ -1425,6 +1468,7 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
|
||||
static const struct of_device_id rockchip_usb2phy_dt_match[] = {
|
||||
{ .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
|
||||
|
@ -24,11 +24,13 @@
|
||||
#define PORT_SEL_1 FIELD_PREP(PORT_SEL_MASK, 1)
|
||||
|
||||
#define PCL_PHY_TEST_I 0x2000
|
||||
#define PCL_PHY_TEST_O 0x2004
|
||||
#define TESTI_DAT_MASK GENMASK(13, 6)
|
||||
#define TESTI_ADR_MASK GENMASK(5, 1)
|
||||
#define TESTI_WR_EN BIT(0)
|
||||
|
||||
#define PCL_PHY_TEST_O 0x2004
|
||||
#define TESTO_DAT_MASK GENMASK(7, 0)
|
||||
|
||||
#define PCL_PHY_RESET 0x200c
|
||||
#define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */
|
||||
#define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */
|
||||
@ -77,11 +79,12 @@ static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv,
|
||||
val = FIELD_PREP(TESTI_DAT_MASK, 1);
|
||||
val |= FIELD_PREP(TESTI_ADR_MASK, reg);
|
||||
uniphier_pciephy_testio_write(priv, val);
|
||||
val = readl(priv->base + PCL_PHY_TEST_O);
|
||||
val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK;
|
||||
|
||||
/* update value */
|
||||
val &= ~FIELD_PREP(TESTI_DAT_MASK, mask);
|
||||
val = FIELD_PREP(TESTI_DAT_MASK, mask & param);
|
||||
val &= ~mask;
|
||||
val |= mask & param;
|
||||
val = FIELD_PREP(TESTI_DAT_MASK, val);
|
||||
val |= FIELD_PREP(TESTI_ADR_MASK, reg);
|
||||
uniphier_pciephy_testio_write(priv, val);
|
||||
uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN);
|
||||
|
@ -57,6 +57,7 @@ struct pll_params {
|
||||
struct stm32_usbphyc_phy {
|
||||
struct phy *phy;
|
||||
struct stm32_usbphyc *usbphyc;
|
||||
struct regulator *vbus;
|
||||
u32 index;
|
||||
bool active;
|
||||
};
|
||||
@ -291,9 +292,31 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
|
||||
return stm32_usbphyc_pll_disable(usbphyc);
|
||||
}
|
||||
|
||||
static int stm32_usbphyc_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
|
||||
|
||||
if (usbphyc_phy->vbus)
|
||||
return regulator_enable(usbphyc_phy->vbus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_usbphyc_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct stm32_usbphyc_phy *usbphyc_phy = phy_get_drvdata(phy);
|
||||
|
||||
if (usbphyc_phy->vbus)
|
||||
return regulator_disable(usbphyc_phy->vbus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops stm32_usbphyc_phy_ops = {
|
||||
.init = stm32_usbphyc_phy_init,
|
||||
.exit = stm32_usbphyc_phy_exit,
|
||||
.power_on = stm32_usbphyc_phy_power_on,
|
||||
.power_off = stm32_usbphyc_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
@ -519,6 +542,14 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
|
||||
usbphyc->phys[port]->index = index;
|
||||
usbphyc->phys[port]->active = false;
|
||||
|
||||
usbphyc->phys[port]->vbus = devm_regulator_get_optional(&phy->dev, "vbus");
|
||||
if (IS_ERR(usbphyc->phys[port]->vbus)) {
|
||||
ret = PTR_ERR(usbphyc->phys[port]->vbus);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto put_child;
|
||||
usbphyc->phys[port]->vbus = NULL;
|
||||
}
|
||||
|
||||
port++;
|
||||
}
|
||||
|
||||
|
@ -242,19 +242,28 @@ static int dm816x_usb_phy_probe(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_enable(phy->dev);
|
||||
generic_phy = devm_phy_create(phy->dev, NULL, &ops);
|
||||
if (IS_ERR(generic_phy))
|
||||
return PTR_ERR(generic_phy);
|
||||
if (IS_ERR(generic_phy)) {
|
||||
error = PTR_ERR(generic_phy);
|
||||
goto clk_unprepare;
|
||||
}
|
||||
|
||||
phy_set_drvdata(generic_phy, phy);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(phy->dev,
|
||||
of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return PTR_ERR(phy_provider);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
error = PTR_ERR(phy_provider);
|
||||
goto clk_unprepare;
|
||||
}
|
||||
|
||||
usb_add_phy_dev(&phy->phy);
|
||||
|
||||
return 0;
|
||||
|
||||
clk_unprepare:
|
||||
pm_runtime_disable(phy->dev);
|
||||
clk_unprepare(phy->refclk);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int dm816x_usb_phy_remove(struct platform_device *pdev)
|
||||
|
@ -544,8 +544,8 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t twl4030_usb_vbus_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t vbus_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct twl4030_usb *twl = dev_get_drvdata(dev);
|
||||
int ret = -EINVAL;
|
||||
@ -557,7 +557,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev,
|
||||
|
||||
return ret;
|
||||
}
|
||||
static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
|
||||
static DEVICE_ATTR_RO(vbus);
|
||||
|
||||
static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
|
||||
{
|
||||
|
@ -125,7 +125,7 @@ struct phy_ops {
|
||||
/**
|
||||
* struct phy_attrs - represents phy attributes
|
||||
* @bus_width: Data path width implemented by PHY
|
||||
* @max_link_rate: Maximum link rate supported by PHY (in Mbps)
|
||||
* @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
|
||||
* @mode: PHY mode
|
||||
*/
|
||||
struct phy_attrs {
|
||||
|
Loading…
Reference in New Issue
Block a user