mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
phy-for-6.12
- New Support - Rcar usb2 support for RZ/G3S SoC - Nuvoton MA35 SoC USB 2.0 PHY driver - Removal - obsolete qcom,usb-8x16-phy bindings - Updates - 4 lane PCIe support for Qualcomm X1E80100 - Constify structure in subsystem update - Subsystem simplification with scoped for each OF child loop update - Yaml conversion for Qualcomm sata phy, Hiilicon hi3798cv200-combphy bindings -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmbv994ACgkQfBQHDyUj g0eefhAApn1pj3AVJE+YBBNcRAZncxt/KdZmS0U8ErwVqlVbFCDJGJtCHOaKbPK+ K8c/u7vcElMA+JsqXd2biidlKsCmrkrpqqpPGJ08RlVy5TCa5H3UNONShPxU13g6 rP90CDJ6LpkOuU+p4b2jCVLVmY4Nq0g02OWUvuZDhFvR9FmfSVbRArmqWk+TdUW+ qO0oxxasNbh3nzt5HBwPUM+K2zZIzC7kQeJch69v3ETHeHzdGOlTKWEonU1OGnE9 PoeXubeSYW+fYaUbOg4n2Wgqt8330W3Flrhkd5Qp9cMAJEOe4Lqso3ai3jFW+iN4 bHQDcH3hzSpPNmlt2x8NgDamx/BEMbyAPQdnfVh7x4esxv+Zy/Fmg3XPeGf5BzlT acis1nlAGnk/CpK+MurXgir8Si7gaiHH0n7lrginxr4QhBlT65Wzci0tPOYdivRH 4g8trmbLHX06Cji2XYvEjgm+Igekdyz892D6rSjOwYZS18CGgeJkdwVfyoMh984l OVaU2d8N73J5UrP4zfUQV/FoOpqS6r+CbI0+f2CyPG+u6/Lwm7PT33ZZFof2s8/4 IiefpuwAzlPr8DEWa0j90VIGmVaTgmdYq3gdfRiG6P6fXoMkKMPLUbmZ9vFFMqRI FiIe8K9gIyCRQadtUasUuVZ9vXr0jOHnbvCCbTmYSO/ceh+KU9I= =XJmz -----END PGP SIGNATURE----- Merge tag 'phy-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy Pull phy updates from Vinod Koul: "New hw support: - Rcar usb2 support for RZ/G3S SoC - Nuvoton MA35 SoC USB 2.0 PHY driver Removed: - obsolete qcom,usb-8x16-phy bindings Updates: - 4 lane PCIe support for Qualcomm X1E80100 - Constify structure in subsystem update - Subsystem simplification with scoped for each OF child loop update - Yaml conversion for Qualcomm sata phy, Hiilicon hi3798cv200-combphy bindings" * tag 'phy-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (40 commits) phy: renesas: rcar-gen3-usb2: Add support for the RZ/G3S SoC dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings phy: renesas: rcar-gen3-usb2: Add support to initialize the bus phy: ti: j721e-wiz: Simplify with scoped for each OF child loop phy: ti: j721e-wiz: Drop OF node reference earlier for simpler code phy: ti: gmii-sel: Simplify with dev_err_probe() phy: ti: am654-serdes: Use scoped device node handling to simplify error paths phy: qcom: qmp-pcie-msm8996: Simplify with scoped for each OF child loop phy: mediatek: xsphy: Simplify with scoped for each OF child loop phy: mediatek: tphy: Simplify with scoped for each OF child loop phy: hisilicon: usb2: Simplify with scoped for each OF child loop phy: cadence: sierra: Simplify with scoped for each OF child loop phy: broadcom: brcm-sata: Simplify with scoped for each OF child loop phy: broadcom: bcm-cygnus-pcie: Simplify with scoped for each OF child loop phy: nuvoton: add new driver for the Nuvoton MA35 SoC USB 2.0 PHY dt-bindings: phy: nuvoton,ma35-usb2-phy: add new bindings phy: qcom: qmp-pcie: Configure all tables on port B PHY phy: airoha: adjust initialization delay in airoha_pcie_phy_init() dt-bindings: phy: socionext,uniphier: add top-level constraints phy: qcom: qmp-pcie: Add Gen4 4-lanes mode for X1E80100 ...
This commit is contained in:
commit
fbb86b0d5f
@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/hisilicon,hi3798cv200-combphy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: HiSilicon STB PCIE/SATA/USB3 PHY
|
||||
|
||||
maintainers:
|
||||
- Shawn Guo <shawn.guo@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: hisilicon,hi3798cv200-combphy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#phy-cells':
|
||||
description: The cell contains the PHY mode
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
hisilicon,fixed-mode:
|
||||
description: If the phy device doesn't support mode select but a fixed mode
|
||||
setting, the property should be present to specify the particular mode.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 1, 2, 4] # SATA, PCIE, USB3
|
||||
|
||||
hisilicon,mode-select-bits:
|
||||
description: If the phy device support mode select, this property should be
|
||||
present to specify the register bits in peripheral controller.
|
||||
items:
|
||||
- description: register_offset
|
||||
- description: bit shift
|
||||
- description: bit mask
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#phy-cells'
|
||||
- clocks
|
||||
- resets
|
||||
|
||||
oneOf:
|
||||
- required: ['hisilicon,fixed-mode']
|
||||
- required: ['hisilicon,mode-select-bits']
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
...
|
@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/nuvoton,ma35d1-usb2-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Nuvoton MA35D1 USB2 phy
|
||||
|
||||
maintainers:
|
||||
- Hui-Ping Chen <hpchen0nvt@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nuvoton,ma35d1-usb2-phy
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
nuvoton,sys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
phandle to syscon for checking the PHY clock status.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#phy-cells"
|
||||
- clocks
|
||||
- nuvoton,sys
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
|
||||
|
||||
usb_phy: usb-phy {
|
||||
compatible = "nuvoton,ma35d1-usb2-phy";
|
||||
clocks = <&clk USBD_GATE>;
|
||||
nuvoton,sys = <&sys>;
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
HiSilicon STB PCIE/SATA/USB3 PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "hisilicon,hi3798cv200-combphy"
|
||||
- reg: Should be the address space for COMBPHY configuration and state
|
||||
registers in peripheral controller, e.g. PERI_COMBPHY0_CFG and
|
||||
PERI_COMBPHY0_STATE for COMBPHY0 Hi3798CV200 SoC.
|
||||
- #phy-cells: Should be 1. The cell number is used to select the phy mode
|
||||
as defined in <dt-bindings/phy/phy.h>.
|
||||
- clocks: The phandle to clock provider and clock specifier pair.
|
||||
- resets: The phandle to reset controller and reset specifier pair.
|
||||
|
||||
Refer to phy/phy-bindings.txt for the generic PHY binding properties.
|
||||
|
||||
Optional properties:
|
||||
- hisilicon,fixed-mode: If the phy device doesn't support mode select
|
||||
but a fixed mode setting, the property should be present to specify
|
||||
the particular mode.
|
||||
- hisilicon,mode-select-bits: If the phy device support mode select,
|
||||
this property should be present to specify the register bits in
|
||||
peripheral controller, as a 3 integers tuple:
|
||||
<register_offset bit_shift bit_mask>.
|
||||
|
||||
Notes:
|
||||
- Between hisilicon,fixed-mode and hisilicon,mode-select-bits, one and only
|
||||
one of them should be present.
|
||||
- The device node should be a child of peripheral controller that contains
|
||||
COMBPHY configuration/state and PERI_CTRL register used to select PHY mode.
|
||||
Refer to arm/hisilicon/hisilicon.txt for the parent peripheral controller
|
||||
bindings.
|
||||
|
||||
Examples:
|
||||
|
||||
perictrl: peripheral-controller@8a20000 {
|
||||
compatible = "hisilicon,hi3798cv200-perictrl", "syscon",
|
||||
"simple-mfd";
|
||||
reg = <0x8a20000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x8a20000 0x1000>;
|
||||
|
||||
combphy0: phy@850 {
|
||||
compatible = "hisilicon,hi3798cv200-combphy";
|
||||
reg = <0x850 0x8>;
|
||||
#phy-cells = <1>;
|
||||
clocks = <&crg HISTB_COMBPHY0_CLK>;
|
||||
resets = <&crg 0x188 4>;
|
||||
hisilicon,fixed-mode = <PHY_TYPE_USB3>;
|
||||
};
|
||||
|
||||
combphy1: phy@858 {
|
||||
compatible = "hisilicon,hi3798cv200-combphy";
|
||||
reg = <0x858 0x8>;
|
||||
#phy-cells = <1>;
|
||||
clocks = <&crg HISTB_COMBPHY1_CLK>;
|
||||
resets = <&crg 0x188 12>;
|
||||
hisilicon,mode-select-bits = <0x0008 11 (0x3 << 11)>;
|
||||
};
|
||||
};
|
55
Documentation/devicetree/bindings/phy/qcom,sata-phy.yaml
Normal file
55
Documentation/devicetree/bindings/phy/qcom,sata-phy.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sata-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SATA PHY Controller
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
- Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
|
||||
description:
|
||||
The Qualcomm SATA PHY describes on-chip SATA Physical layer controllers.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,ipq806x-sata-phy
|
||||
- qcom,apq8064-sata-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: cfg
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
|
||||
sata_phy: sata-phy@1b400000 {
|
||||
compatible = "qcom,ipq806x-sata-phy";
|
||||
reg = <0x1b400000 0x200>;
|
||||
|
||||
clocks = <&gcc SATA_PHY_CFG_CLK>;
|
||||
clock-names = "cfg";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
@ -40,6 +40,7 @@ properties:
|
||||
- qcom,sm8650-qmp-gen4x2-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen3x2-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen4x2-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen4x4-pcie-phy
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
@ -118,6 +119,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen4x4-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
@ -169,6 +171,7 @@ allOf:
|
||||
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
|
||||
- qcom,x1e80100-qmp-gen4x4-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -1,76 +0,0 @@
|
||||
Qualcomm's APQ8016/MSM8916 USB transceiver controller
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: Should contain "qcom,usb-8x16-phy".
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: USB PHY base address and length of the register map
|
||||
|
||||
- clocks:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: See clock-bindings.txt section "consumers". List of
|
||||
two clock specifiers for interface and core controller
|
||||
clocks.
|
||||
|
||||
- clock-names:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: Must contain "iface" and "core" strings.
|
||||
|
||||
- vddcx-supply:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: phandle to the regulator VDCCX supply node.
|
||||
|
||||
- v1p8-supply:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: phandle to the regulator 1.8V supply node.
|
||||
|
||||
- v3p3-supply:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: phandle to the regulator 3.3V supply node.
|
||||
|
||||
- resets:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: See reset.txt section "consumers". PHY reset specifier.
|
||||
|
||||
- reset-names:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: Must contain "phy" string.
|
||||
|
||||
- switch-gpio:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Some boards are using Dual SPDT USB Switch, witch is
|
||||
controlled by GPIO to de/multiplex D+/D- USB lines
|
||||
between connectors.
|
||||
|
||||
Example:
|
||||
usb_phy: phy@78d9000 {
|
||||
compatible = "qcom,usb-8x16-phy";
|
||||
reg = <0x78d9000 0x400>;
|
||||
|
||||
vddcx-supply = <&pm8916_s1_corner>;
|
||||
v1p8-supply = <&pm8916_l7>;
|
||||
v3p3-supply = <&pm8916_l13>;
|
||||
|
||||
clocks = <&gcc GCC_USB_HS_AHB_CLK>,
|
||||
<&gcc GCC_USB_HS_SYSTEM_CLK>;
|
||||
clock-names = "iface", "core";
|
||||
|
||||
resets = <&gcc GCC_USB2A_PHY_BCR>;
|
||||
reset-names = "phy";
|
||||
|
||||
// D+/D- lines: 1 - Routed to HUB, 0 - Device connector
|
||||
switch-gpio = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
@ -1,24 +0,0 @@
|
||||
Qualcomm APQ8064 SATA PHY Controller
|
||||
------------------------------------
|
||||
|
||||
SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
|
||||
Each SATA PHY controller should have its own node.
|
||||
|
||||
Required properties:
|
||||
- compatible: compatible list, contains "qcom,apq8064-sata-phy".
|
||||
- reg: offset and length of the SATA PHY register set;
|
||||
- #phy-cells: must be zero
|
||||
- clocks: a list of phandles and clock-specifier pairs, one for each entry in
|
||||
clock-names.
|
||||
- clock-names: must be "cfg" for phy config clock.
|
||||
|
||||
Example:
|
||||
sata_phy: sata-phy@1b400000 {
|
||||
compatible = "qcom,apq8064-sata-phy";
|
||||
reg = <0x1b400000 0x200>;
|
||||
|
||||
clocks = <&gcc SATA_PHY_CFG_CLK>;
|
||||
clock-names = "cfg";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
Qualcomm IPQ806x SATA PHY Controller
|
||||
------------------------------------
|
||||
|
||||
SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
|
||||
Each SATA PHY controller should have its own node.
|
||||
|
||||
Required properties:
|
||||
- compatible: compatible list, contains "qcom,ipq806x-sata-phy"
|
||||
- reg: offset and length of the SATA PHY register set;
|
||||
- #phy-cells: must be zero
|
||||
- clocks: must be exactly one entry
|
||||
- clock-names: must be "cfg"
|
||||
|
||||
Example:
|
||||
sata_phy: sata-phy@1b400000 {
|
||||
compatible = "qcom,ipq806x-sata-phy";
|
||||
reg = <0x1b400000 0x200>;
|
||||
|
||||
clocks = <&gcc SATA_PHY_CFG_CLK>;
|
||||
clock-names = "cfg";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -13,7 +13,9 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: renesas,usb2-phy-r8a77470 # RZ/G1C
|
||||
- enum:
|
||||
- renesas,usb2-phy-r8a77470 # RZ/G1C
|
||||
- renesas,usb2-phy-r9a08g045 # RZ/G3S
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
|
@ -27,6 +27,9 @@ properties:
|
||||
- const: ref
|
||||
- const: apb
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
|
@ -30,13 +30,17 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 6
|
||||
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
|
||||
reset-names: true
|
||||
reset-names:
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
|
@ -31,13 +31,17 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names: true
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
socionext,syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
@ -34,12 +34,15 @@ properties:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names: true
|
||||
reset-names:
|
||||
maxItems: 2
|
||||
|
||||
vbus-supply:
|
||||
description: A phandle to the regulator for USB VBUS
|
||||
|
@ -35,12 +35,15 @@ properties:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names: true
|
||||
reset-names:
|
||||
maxItems: 2
|
||||
|
||||
vbus-supply:
|
||||
description: A phandle to the regulator for USB VBUS, only for USB host
|
||||
|
@ -95,6 +95,7 @@ source "drivers/phy/mediatek/Kconfig"
|
||||
source "drivers/phy/microchip/Kconfig"
|
||||
source "drivers/phy/motorola/Kconfig"
|
||||
source "drivers/phy/mscc/Kconfig"
|
||||
source "drivers/phy/nuvoton/Kconfig"
|
||||
source "drivers/phy/qualcomm/Kconfig"
|
||||
source "drivers/phy/ralink/Kconfig"
|
||||
source "drivers/phy/realtek/Kconfig"
|
||||
|
@ -25,6 +25,7 @@ obj-y += allwinner/ \
|
||||
microchip/ \
|
||||
motorola/ \
|
||||
mscc/ \
|
||||
nuvoton/ \
|
||||
qualcomm/ \
|
||||
ralink/ \
|
||||
realtek/ \
|
||||
|
@ -113,11 +113,10 @@ static const struct phy_ops cygnus_pcie_phy_ops = {
|
||||
static int cygnus_pcie_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node, *child;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct cygnus_pcie_phy_core *core;
|
||||
struct phy_provider *provider;
|
||||
unsigned cnt = 0;
|
||||
int ret;
|
||||
|
||||
if (of_get_child_count(node) == 0) {
|
||||
dev_err(dev, "PHY no child node\n");
|
||||
@ -136,35 +135,31 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
|
||||
|
||||
mutex_init(&core->lock);
|
||||
|
||||
for_each_available_child_of_node(node, child) {
|
||||
for_each_available_child_of_node_scoped(node, child) {
|
||||
unsigned int id;
|
||||
struct cygnus_pcie_phy *p;
|
||||
|
||||
if (of_property_read_u32(child, "reg", &id)) {
|
||||
dev_err(dev, "missing reg property for %pOFn\n",
|
||||
child);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (id >= MAX_NUM_PHYS) {
|
||||
dev_err(dev, "invalid PHY id: %u\n", id);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (core->phys[id].phy) {
|
||||
dev_err(dev, "duplicated PHY id: %u\n", id);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p = &core->phys[id];
|
||||
p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
|
||||
if (IS_ERR(p->phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
ret = PTR_ERR(p->phy);
|
||||
goto put_child;
|
||||
return PTR_ERR(p->phy);
|
||||
}
|
||||
|
||||
p->core = core;
|
||||
@ -184,9 +179,6 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
|
||||
dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
|
||||
|
||||
return 0;
|
||||
put_child:
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id cygnus_pcie_phy_match_table[] = {
|
||||
|
@ -751,11 +751,11 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
const char *rxaeq_mode;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dn = dev->of_node, *child;
|
||||
struct device_node *dn = dev->of_node;
|
||||
const struct of_device_id *of_id;
|
||||
struct brcm_sata_phy *priv;
|
||||
struct phy_provider *provider;
|
||||
int ret, count = 0;
|
||||
int count = 0;
|
||||
|
||||
if (of_get_child_count(dn) == 0)
|
||||
return -ENODEV;
|
||||
@ -782,26 +782,23 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(priv->ctrl_base);
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(dn, child) {
|
||||
for_each_available_child_of_node_scoped(dn, child) {
|
||||
unsigned int id;
|
||||
struct brcm_sata_port *port;
|
||||
|
||||
if (of_property_read_u32(child, "reg", &id)) {
|
||||
dev_err(dev, "missing reg property in node %pOFn\n",
|
||||
child);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (id >= MAX_PORTS) {
|
||||
dev_err(dev, "invalid reg: %u\n", id);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (priv->phys[id].phy) {
|
||||
dev_err(dev, "already registered port %u\n", id);
|
||||
ret = -EINVAL;
|
||||
goto put_child;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
port = &priv->phys[id];
|
||||
@ -822,8 +819,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
|
||||
if (IS_ERR(port->phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
ret = PTR_ERR(port->phy);
|
||||
goto put_child;
|
||||
return PTR_ERR(port->phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(port->phy, port);
|
||||
@ -839,9 +835,6 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
dev_info(dev, "registered %d port(s)\n", count);
|
||||
|
||||
return 0;
|
||||
put_child:
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver brcm_sata_phy_driver = {
|
||||
|
@ -310,7 +310,7 @@ static const struct clk_parent_data pll_mux_parent_data[][SIERRA_NUM_CMN_PLLC_PA
|
||||
},
|
||||
};
|
||||
|
||||
static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
|
||||
static const u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
|
||||
[CMN_PLLLC] = { 0, 1 },
|
||||
[CMN_PLLLC1] = { 1, 0 },
|
||||
};
|
||||
@ -362,14 +362,14 @@ struct cdns_sierra_data {
|
||||
u32 id_value;
|
||||
u8 block_offset_shift;
|
||||
u8 reg_offset_shift;
|
||||
struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
const struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
const struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
const struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
const struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE]
|
||||
[NUM_SSC_MODE];
|
||||
};
|
||||
|
||||
struct cdns_regmap_cdb_context {
|
||||
@ -539,12 +539,12 @@ static int cdns_sierra_phy_init(struct phy *gphy)
|
||||
struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
|
||||
struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent);
|
||||
const struct cdns_sierra_data *init_data = phy->init_data;
|
||||
struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
|
||||
const struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
|
||||
enum cdns_sierra_phy_type phy_type = ins->phy_type;
|
||||
const struct cdns_sierra_vals *phy_pma_ln_vals;
|
||||
enum cdns_sierra_ssc_mode ssc = ins->ssc_mode;
|
||||
struct cdns_sierra_vals *phy_pma_ln_vals;
|
||||
const struct cdns_sierra_vals *pcs_cmn_vals;
|
||||
const struct cdns_reg_pairs *reg_pairs;
|
||||
struct cdns_sierra_vals *pcs_cmn_vals;
|
||||
struct regmap *regmap;
|
||||
u32 num_regs;
|
||||
int i, j;
|
||||
@ -1244,12 +1244,12 @@ static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
|
||||
|
||||
static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp)
|
||||
{
|
||||
const struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
|
||||
const struct cdns_sierra_data *init_data = sp->init_data;
|
||||
struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
|
||||
const struct cdns_sierra_vals *phy_pma_ln_vals;
|
||||
const struct cdns_sierra_vals *pcs_cmn_vals;
|
||||
enum cdns_sierra_phy_type phy_t1, phy_t2;
|
||||
struct cdns_sierra_vals *phy_pma_ln_vals;
|
||||
const struct cdns_reg_pairs *reg_pairs;
|
||||
struct cdns_sierra_vals *pcs_cmn_vals;
|
||||
int i, j, node, mlane, num_lanes, ret;
|
||||
enum cdns_sierra_ssc_mode ssc;
|
||||
struct regmap *regmap;
|
||||
@ -1366,7 +1366,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
unsigned int id_value;
|
||||
int ret, node = 0;
|
||||
void __iomem *base;
|
||||
struct device_node *dn = dev->of_node, *child;
|
||||
struct device_node *dn = dev->of_node;
|
||||
|
||||
if (of_get_child_count(dn) == 0)
|
||||
return -ENODEV;
|
||||
@ -1438,7 +1438,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
|
||||
sp->autoconf = of_property_read_bool(dn, "cdns,autoconf");
|
||||
|
||||
for_each_available_child_of_node(dn, child) {
|
||||
for_each_available_child_of_node_scoped(dn, child) {
|
||||
struct phy *gphy;
|
||||
|
||||
if (!(of_node_name_eq(child, "phy") ||
|
||||
@ -1452,7 +1452,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
dev_err(dev, "failed to get reset %s\n",
|
||||
child->full_name);
|
||||
ret = PTR_ERR(sp->phys[node].lnk_rst);
|
||||
of_node_put(child);
|
||||
goto put_control;
|
||||
}
|
||||
|
||||
@ -1461,7 +1460,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(dev, "missing property in node %s\n",
|
||||
child->name);
|
||||
of_node_put(child);
|
||||
reset_control_put(sp->phys[node].lnk_rst);
|
||||
goto put_control;
|
||||
}
|
||||
@ -1475,7 +1473,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
gphy = devm_phy_create(dev, child, &noop_ops);
|
||||
if (IS_ERR(gphy)) {
|
||||
ret = PTR_ERR(gphy);
|
||||
of_node_put(child);
|
||||
reset_control_put(sp->phys[node].lnk_rst);
|
||||
goto put_control;
|
||||
}
|
||||
@ -1544,11 +1541,11 @@ static void cdns_sierra_phy_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* SGMII PHY PMA lane configuration */
|
||||
static struct cdns_reg_pairs sgmii_phy_pma_ln_regs[] = {
|
||||
static const struct cdns_reg_pairs sgmii_phy_pma_ln_regs[] = {
|
||||
{0x9010, SIERRA_PHY_PMA_XCVR_CTRL}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals sgmii_phy_pma_ln_vals = {
|
||||
static const struct cdns_sierra_vals sgmii_phy_pma_ln_vals = {
|
||||
.reg_pairs = sgmii_phy_pma_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_phy_pma_ln_regs),
|
||||
};
|
||||
@ -1598,22 +1595,22 @@ static const struct cdns_reg_pairs sgmii_100_no_ssc_plllc1_opt3_ln_regs[] = {
|
||||
{0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_cmn_vals = {
|
||||
static const struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_cmn_vals = {
|
||||
.reg_pairs = sgmii_100_no_ssc_plllc1_opt3_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_ln_vals = {
|
||||
static const struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_ln_vals = {
|
||||
.reg_pairs = sgmii_100_no_ssc_plllc1_opt3_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_ln_regs),
|
||||
};
|
||||
|
||||
/* QSGMII PHY PMA lane configuration */
|
||||
static struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = {
|
||||
static const struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = {
|
||||
{0x9010, SIERRA_PHY_PMA_XCVR_CTRL}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = {
|
||||
static const struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = {
|
||||
.reg_pairs = qsgmii_phy_pma_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(qsgmii_phy_pma_ln_regs),
|
||||
};
|
||||
@ -1664,22 +1661,22 @@ static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_ln_regs[] = {
|
||||
{0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = {
|
||||
static const struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = {
|
||||
.reg_pairs = qsgmii_100_no_ssc_plllc1_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = {
|
||||
static const struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = {
|
||||
.reg_pairs = qsgmii_100_no_ssc_plllc1_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_ln_regs),
|
||||
};
|
||||
|
||||
/* PCIE PHY PCS common configuration */
|
||||
static struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = {
|
||||
static const struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = {
|
||||
{0x0430, SIERRA_PHY_PIPE_CMN_CTRL1}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = {
|
||||
.reg_pairs = pcie_phy_pcs_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs),
|
||||
};
|
||||
@ -1745,12 +1742,12 @@ static const struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = {
|
||||
.reg_pairs = pcie_100_no_ssc_plllc_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(pcie_100_no_ssc_plllc_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = {
|
||||
.reg_pairs = ml_pcie_100_no_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_ln_regs),
|
||||
};
|
||||
@ -1810,7 +1807,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_no_ssc_ln_regs[] = {
|
||||
{0x0002, SIERRA_TX_RCVDET_OVRD_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ti_ml_pcie_100_no_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ti_ml_pcie_100_no_ssc_ln_vals = {
|
||||
.reg_pairs = ti_ml_pcie_100_no_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ti_ml_pcie_100_no_ssc_ln_regs),
|
||||
};
|
||||
@ -1886,12 +1883,12 @@ static const struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = {
|
||||
.reg_pairs = pcie_100_int_ssc_plllc_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(pcie_100_int_ssc_plllc_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = {
|
||||
.reg_pairs = ml_pcie_100_int_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_ln_regs),
|
||||
};
|
||||
@ -1954,7 +1951,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_int_ssc_ln_regs[] = {
|
||||
{0x0002, SIERRA_TX_RCVDET_OVRD_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ti_ml_pcie_100_int_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ti_ml_pcie_100_int_ssc_ln_vals = {
|
||||
.reg_pairs = ti_ml_pcie_100_int_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ti_ml_pcie_100_int_ssc_ln_regs),
|
||||
};
|
||||
@ -2024,12 +2021,12 @@ static const struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = {
|
||||
.reg_pairs = pcie_100_ext_ssc_plllc_cmn_regs,
|
||||
.num_regs = ARRAY_SIZE(pcie_100_ext_ssc_plllc_cmn_regs),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = {
|
||||
.reg_pairs = ml_pcie_100_ext_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ml_pcie_100_ext_ssc_ln_regs),
|
||||
};
|
||||
@ -2092,7 +2089,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_ext_ssc_ln_regs[] = {
|
||||
{0x0002, SIERRA_TX_RCVDET_OVRD_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals ti_ml_pcie_100_ext_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals ti_ml_pcie_100_ext_ssc_ln_vals = {
|
||||
.reg_pairs = ti_ml_pcie_100_ext_ssc_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(ti_ml_pcie_100_ext_ssc_ln_regs),
|
||||
};
|
||||
@ -2152,12 +2149,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_no_ssc[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_no_ssc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_no_ssc_cmn_vals = {
|
||||
.reg_pairs = cdns_pcie_cmn_regs_no_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_no_ssc),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_no_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_no_ssc_ln_vals = {
|
||||
.reg_pairs = cdns_pcie_ln_regs_no_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_no_ssc),
|
||||
};
|
||||
@ -2227,12 +2224,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_int_ssc[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_int_ssc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_int_ssc_cmn_vals = {
|
||||
.reg_pairs = cdns_pcie_cmn_regs_int_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_int_ssc),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_int_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_int_ssc_ln_vals = {
|
||||
.reg_pairs = cdns_pcie_ln_regs_int_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_int_ssc),
|
||||
};
|
||||
@ -2296,12 +2293,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = {
|
||||
{0x4432, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = {
|
||||
.reg_pairs = cdns_pcie_cmn_regs_ext_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = {
|
||||
.reg_pairs = cdns_pcie_ln_regs_ext_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc),
|
||||
};
|
||||
@ -2413,12 +2410,12 @@ static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = {
|
||||
{0x4243, SIERRA_RXBUFFER_DFECTRL_PREG}
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = {
|
||||
static const struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = {
|
||||
.reg_pairs = cdns_usb_cmn_regs_ext_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc),
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = {
|
||||
static const struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = {
|
||||
.reg_pairs = cdns_usb_ln_regs_ext_ssc,
|
||||
.num_regs = ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc),
|
||||
};
|
||||
@ -2443,7 +2440,7 @@ static const struct cdns_reg_pairs sgmii_pma_cmn_vals[] = {
|
||||
{0x0013, SIERRA_CMN_PLLLC1_DCOCAL_CTRL_PREG},
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals sgmii_cmn_vals = {
|
||||
static const struct cdns_sierra_vals sgmii_cmn_vals = {
|
||||
.reg_pairs = sgmii_pma_cmn_vals,
|
||||
.num_regs = ARRAY_SIZE(sgmii_pma_cmn_vals),
|
||||
};
|
||||
@ -2489,7 +2486,7 @@ static const struct cdns_reg_pairs sgmii_ln_regs[] = {
|
||||
{0x321F, SIERRA_CPICAL_RES_STARTCODE_MODE01_PREG},
|
||||
};
|
||||
|
||||
static struct cdns_sierra_vals sgmii_pma_ln_vals = {
|
||||
static const struct cdns_sierra_vals sgmii_pma_ln_vals = {
|
||||
.reg_pairs = sgmii_ln_regs,
|
||||
.num_regs = ARRAY_SIZE(sgmii_ln_regs),
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -138,7 +138,6 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
|
||||
struct device_node *np = dev->of_node;
|
||||
struct hisi_inno_phy_priv *priv;
|
||||
struct phy_provider *provider;
|
||||
struct device_node *child;
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
@ -162,24 +161,20 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
|
||||
|
||||
priv->type = (uintptr_t) of_device_get_match_data(dev);
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
for_each_child_of_node_scoped(np, child) {
|
||||
struct reset_control *rst;
|
||||
struct phy *phy;
|
||||
|
||||
rst = of_reset_control_get_exclusive(child, NULL);
|
||||
if (IS_ERR(rst)) {
|
||||
of_node_put(child);
|
||||
if (IS_ERR(rst))
|
||||
return PTR_ERR(rst);
|
||||
}
|
||||
|
||||
priv->ports[i].utmi_rst = rst;
|
||||
priv->ports[i].priv = priv;
|
||||
|
||||
phy = devm_phy_create(dev, child, &hisi_inno_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
of_node_put(child);
|
||||
if (IS_ERR(phy))
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_bus_width(phy, 8);
|
||||
phy_set_drvdata(phy, &priv->ports[i]);
|
||||
@ -187,7 +182,6 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
|
||||
|
||||
if (i >= INNO_PHY_PORT_NUM) {
|
||||
dev_warn(dev, "Support %d ports in maximum\n", i);
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +244,8 @@ static const struct mvebu_comphy_conf mvebu_comphy_cp110_modes[] = {
|
||||
GEN_CONF(4, 1, PHY_MODE_USB_HOST_SS, COMPHY_FW_MODE_USB3H),
|
||||
GEN_CONF(4, 1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_SGMII, 0x1, COMPHY_FW_MODE_SGMII),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, -1, COMPHY_FW_MODE_2500BASEX),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_5GBASER, -1, COMPHY_FW_MODE_XFI),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_2500BASEX, 0x1, COMPHY_FW_MODE_2500BASEX),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_5GBASER, 0x1, COMPHY_FW_MODE_XFI),
|
||||
ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI),
|
||||
/* lane 5 */
|
||||
ETH_CONF(5, 1, PHY_INTERFACE_MODE_RXAUI, 0x2, COMPHY_FW_MODE_RXAUI),
|
||||
|
@ -1577,12 +1577,11 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *child_np;
|
||||
struct phy_provider *provider;
|
||||
struct resource *sif_res;
|
||||
struct mtk_tphy *tphy;
|
||||
struct resource res;
|
||||
int port, retval;
|
||||
int port;
|
||||
|
||||
tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
|
||||
if (!tphy)
|
||||
@ -1623,25 +1622,23 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
port = 0;
|
||||
for_each_child_of_node(np, child_np) {
|
||||
for_each_child_of_node_scoped(np, child_np) {
|
||||
struct mtk_phy_instance *instance;
|
||||
struct clk_bulk_data *clks;
|
||||
struct device *subdev;
|
||||
struct phy *phy;
|
||||
int retval;
|
||||
|
||||
instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
|
||||
if (!instance) {
|
||||
retval = -ENOMEM;
|
||||
goto put_child;
|
||||
}
|
||||
if (!instance)
|
||||
return -ENOMEM;
|
||||
|
||||
tphy->phys[port] = instance;
|
||||
|
||||
phy = devm_phy_create(dev, child_np, &mtk_tphy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create phy\n");
|
||||
retval = PTR_ERR(phy);
|
||||
goto put_child;
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
subdev = &phy->dev;
|
||||
@ -1649,14 +1646,12 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
||||
if (retval) {
|
||||
dev_err(subdev, "failed to get address resource(id-%d)\n",
|
||||
port);
|
||||
goto put_child;
|
||||
return retval;
|
||||
}
|
||||
|
||||
instance->port_base = devm_ioremap_resource(subdev, &res);
|
||||
if (IS_ERR(instance->port_base)) {
|
||||
retval = PTR_ERR(instance->port_base);
|
||||
goto put_child;
|
||||
}
|
||||
if (IS_ERR(instance->port_base))
|
||||
return PTR_ERR(instance->port_base);
|
||||
|
||||
instance->phy = phy;
|
||||
instance->index = port;
|
||||
@ -1668,19 +1663,16 @@ static int mtk_tphy_probe(struct platform_device *pdev)
|
||||
clks[1].id = "da_ref"; /* analog clock */
|
||||
retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
|
||||
if (retval)
|
||||
goto put_child;
|
||||
return retval;
|
||||
|
||||
retval = phy_type_syscon_get(instance, child_np);
|
||||
if (retval)
|
||||
goto put_child;
|
||||
return retval;
|
||||
}
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(provider);
|
||||
put_child:
|
||||
of_node_put(child_np);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct platform_driver mtk_tphy_driver = {
|
||||
|
@ -432,12 +432,11 @@ static int mtk_xsphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *child_np;
|
||||
struct phy_provider *provider;
|
||||
struct resource *glb_res;
|
||||
struct mtk_xsphy *xsphy;
|
||||
struct resource res;
|
||||
int port, retval;
|
||||
int port;
|
||||
|
||||
xsphy = devm_kzalloc(dev, sizeof(*xsphy), GFP_KERNEL);
|
||||
if (!xsphy)
|
||||
@ -471,37 +470,34 @@ static int mtk_xsphy_probe(struct platform_device *pdev)
|
||||
device_property_read_u32(dev, "mediatek,src-coef", &xsphy->src_coef);
|
||||
|
||||
port = 0;
|
||||
for_each_child_of_node(np, child_np) {
|
||||
for_each_child_of_node_scoped(np, child_np) {
|
||||
struct xsphy_instance *inst;
|
||||
struct phy *phy;
|
||||
int retval;
|
||||
|
||||
inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL);
|
||||
if (!inst) {
|
||||
retval = -ENOMEM;
|
||||
goto put_child;
|
||||
}
|
||||
if (!inst)
|
||||
return -ENOMEM;
|
||||
|
||||
xsphy->phys[port] = inst;
|
||||
|
||||
phy = devm_phy_create(dev, child_np, &mtk_xsphy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create phy\n");
|
||||
retval = PTR_ERR(phy);
|
||||
goto put_child;
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
retval = of_address_to_resource(child_np, 0, &res);
|
||||
if (retval) {
|
||||
dev_err(dev, "failed to get address resource(id-%d)\n",
|
||||
port);
|
||||
goto put_child;
|
||||
return retval;
|
||||
}
|
||||
|
||||
inst->port_base = devm_ioremap_resource(&phy->dev, &res);
|
||||
if (IS_ERR(inst->port_base)) {
|
||||
dev_err(dev, "failed to remap phy regs\n");
|
||||
retval = PTR_ERR(inst->port_base);
|
||||
goto put_child;
|
||||
return PTR_ERR(inst->port_base);
|
||||
}
|
||||
|
||||
inst->phy = phy;
|
||||
@ -512,17 +508,12 @@ static int mtk_xsphy_probe(struct platform_device *pdev)
|
||||
inst->ref_clk = devm_clk_get(&phy->dev, "ref");
|
||||
if (IS_ERR(inst->ref_clk)) {
|
||||
dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
|
||||
retval = PTR_ERR(inst->ref_clk);
|
||||
goto put_child;
|
||||
return PTR_ERR(inst->ref_clk);
|
||||
}
|
||||
}
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
|
||||
return PTR_ERR_OR_ZERO(provider);
|
||||
|
||||
put_child:
|
||||
of_node_put(child_np);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct platform_driver mtk_xsphy_driver = {
|
||||
|
12
drivers/phy/nuvoton/Kconfig
Normal file
12
drivers/phy/nuvoton/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# PHY drivers for Nuvoton MA35 platforms
|
||||
#
|
||||
config PHY_MA35_USB
|
||||
tristate "Nuvoton MA35 USB2.0 PHY driver"
|
||||
depends on ARCH_MA35 || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the USB2.0 PHY on the Nuvoton MA35
|
||||
series SoCs.
|
3
drivers/phy/nuvoton/Makefile
Normal file
3
drivers/phy/nuvoton/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_PHY_MA35_USB) += phy-ma35d1-usb2.o
|
143
drivers/phy/nuvoton/phy-ma35d1-usb2.c
Normal file
143
drivers/phy/nuvoton/phy-ma35d1-usb2.c
Normal file
@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2024 Nuvoton Technology Corp.
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* USB PHY Miscellaneous Control Register */
|
||||
#define MA35_SYS_REG_USBPMISCR 0x60
|
||||
#define PHY0POR BIT(0) /* PHY Power-On Reset Control Bit */
|
||||
#define PHY0SUSPEND BIT(1) /* PHY Suspend; 0: suspend, 1: operaion */
|
||||
#define PHY0COMN BIT(2) /* PHY Common Block Power-Down Control */
|
||||
#define PHY0DEVCKSTB BIT(10) /* PHY 60 MHz UTMI clock stable bit */
|
||||
|
||||
struct ma35_usb_phy {
|
||||
struct clk *clk;
|
||||
struct device *dev;
|
||||
struct regmap *sysreg;
|
||||
};
|
||||
|
||||
static int ma35_usb_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct ma35_usb_phy *p_phy = phy_get_drvdata(phy);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(p_phy->clk);
|
||||
if (ret < 0) {
|
||||
dev_err(p_phy->dev, "Failed to enable PHY clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_read(p_phy->sysreg, MA35_SYS_REG_USBPMISCR, &val);
|
||||
if (val & PHY0SUSPEND) {
|
||||
/*
|
||||
* USB PHY0 is in operation mode already
|
||||
* make sure USB PHY 60 MHz UTMI Interface Clock ready
|
||||
*/
|
||||
ret = regmap_read_poll_timeout(p_phy->sysreg, MA35_SYS_REG_USBPMISCR, val,
|
||||
val & PHY0DEVCKSTB, 10, 1000);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* reset USB PHY0.
|
||||
* wait until USB PHY0 60 MHz UTMI Interface Clock ready
|
||||
*/
|
||||
regmap_update_bits(p_phy->sysreg, MA35_SYS_REG_USBPMISCR, 0x7, (PHY0POR | PHY0SUSPEND));
|
||||
udelay(20);
|
||||
|
||||
/* make USB PHY0 enter operation mode */
|
||||
regmap_update_bits(p_phy->sysreg, MA35_SYS_REG_USBPMISCR, 0x7, PHY0SUSPEND);
|
||||
|
||||
/* make sure USB PHY 60 MHz UTMI Interface Clock ready */
|
||||
ret = regmap_read_poll_timeout(p_phy->sysreg, MA35_SYS_REG_USBPMISCR, val,
|
||||
val & PHY0DEVCKSTB, 10, 1000);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
dev_err(p_phy->dev, "Check PHY clock, Timeout: %d\n", ret);
|
||||
clk_disable_unprepare(p_phy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ma35_usb_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct ma35_usb_phy *p_phy = phy_get_drvdata(phy);
|
||||
|
||||
clk_disable_unprepare(p_phy->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops ma35_usb_phy_ops = {
|
||||
.power_on = ma35_usb_phy_power_on,
|
||||
.power_off = ma35_usb_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int ma35_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *provider;
|
||||
struct ma35_usb_phy *p_phy;
|
||||
struct phy *phy;
|
||||
|
||||
p_phy = devm_kzalloc(&pdev->dev, sizeof(*p_phy), GFP_KERNEL);
|
||||
if (!p_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
p_phy->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, p_phy);
|
||||
|
||||
p_phy->sysreg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "nuvoton,sys");
|
||||
if (IS_ERR(p_phy->sysreg))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(p_phy->sysreg),
|
||||
"Failed to get SYS registers\n");
|
||||
|
||||
p_phy->clk = of_clk_get(pdev->dev.of_node, 0);
|
||||
if (IS_ERR(p_phy->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(p_phy->clk),
|
||||
"failed to find usb_phy clock\n");
|
||||
|
||||
phy = devm_phy_create(&pdev->dev, NULL, &ma35_usb_phy_ops);
|
||||
if (IS_ERR(phy))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(phy), "Failed to create PHY\n");
|
||||
|
||||
phy_set_drvdata(phy, p_phy);
|
||||
|
||||
provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(provider),
|
||||
"Failed to register PHY provider\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ma35_usb_phy_of_match[] = {
|
||||
{ .compatible = "nuvoton,ma35d1-usb2-phy", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ma35_usb_phy_of_match);
|
||||
|
||||
static struct platform_driver ma35_usb_phy_driver = {
|
||||
.probe = ma35_usb_phy_probe,
|
||||
.driver = {
|
||||
.name = "ma35d1-usb2-phy",
|
||||
.of_match_table = ma35_usb_phy_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(ma35_usb_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Nuvoton ma35d1 USB2.0 PHY driver");
|
||||
MODULE_AUTHOR("Hui-Ping Chen <hpchen0nvt@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -18,6 +18,9 @@
|
||||
#define LEQ_LEN_CTRL_MAX_VAL 7
|
||||
#define FREQ_LOCK_MAX_ATTEMPT 10
|
||||
|
||||
/* PCIe-PHY initialization time in ms needed by the hw to complete */
|
||||
#define PHY_HW_INIT_TIME_MS 30
|
||||
|
||||
enum airoha_pcie_port_gen {
|
||||
PCIE_PORT_GEN1 = 1,
|
||||
PCIE_PORT_GEN2,
|
||||
@ -1181,7 +1184,8 @@ static int airoha_pcie_phy_init(struct phy *phy)
|
||||
airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0,
|
||||
PCIE_DA_XPON_CDR_PR_PWDB);
|
||||
|
||||
usleep_range(100, 200);
|
||||
/* Wait for the PCIe PHY to complete initialization before returning */
|
||||
msleep(PHY_HW_INIT_TIME_MS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2190,24 +2190,25 @@ static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
|
||||
void __iomem *serdes = qmp->dp_serdes;
|
||||
const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
|
||||
|
||||
qmp_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl,
|
||||
cfg->dp_serdes_tbl_num);
|
||||
|
||||
switch (dp_opts->link_rate) {
|
||||
case 1620:
|
||||
qmp_configure(serdes, cfg->serdes_tbl_rbr,
|
||||
cfg->serdes_tbl_rbr_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_rbr,
|
||||
cfg->serdes_tbl_rbr_num);
|
||||
break;
|
||||
case 2700:
|
||||
qmp_configure(serdes, cfg->serdes_tbl_hbr,
|
||||
cfg->serdes_tbl_hbr_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr,
|
||||
cfg->serdes_tbl_hbr_num);
|
||||
break;
|
||||
case 5400:
|
||||
qmp_configure(serdes, cfg->serdes_tbl_hbr2,
|
||||
cfg->serdes_tbl_hbr2_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr2,
|
||||
cfg->serdes_tbl_hbr2_num);
|
||||
break;
|
||||
case 8100:
|
||||
qmp_configure(serdes, cfg->serdes_tbl_hbr3,
|
||||
cfg->serdes_tbl_hbr3_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr3,
|
||||
cfg->serdes_tbl_hbr3_num);
|
||||
break;
|
||||
default:
|
||||
/* Other link rates aren't supported */
|
||||
@ -2807,8 +2808,8 @@ static int qmp_combo_dp_power_on(struct phy *phy)
|
||||
|
||||
qmp_combo_dp_serdes_init(qmp);
|
||||
|
||||
qmp_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1);
|
||||
qmp_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->dev, tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);
|
||||
|
||||
/* Configure special DP tx tunings */
|
||||
cfg->configure_dp_tx(qmp);
|
||||
@ -2850,7 +2851,7 @@ static int qmp_combo_usb_power_on(struct phy *phy)
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
qmp_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
|
||||
|
||||
ret = clk_prepare_enable(qmp->pipe_clk);
|
||||
if (ret) {
|
||||
@ -2859,16 +2860,17 @@ static int qmp_combo_usb_power_on(struct phy *phy)
|
||||
}
|
||||
|
||||
/* Tx, Rx, and PCS configurations */
|
||||
qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
|
||||
|
||||
qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
|
||||
qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
|
||||
if (pcs_usb)
|
||||
qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
|
||||
qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl,
|
||||
cfg->pcs_usb_tbl_num);
|
||||
|
||||
if (cfg->has_pwrdn_delay)
|
||||
usleep_range(10, 20);
|
||||
|
@ -9,6 +9,7 @@
|
||||
struct qmp_phy_init_tbl {
|
||||
unsigned int offset;
|
||||
unsigned int val;
|
||||
char *name;
|
||||
/*
|
||||
* mask of lanes for which this register is written
|
||||
* for cases when second lane needs different values
|
||||
@ -20,6 +21,7 @@ struct qmp_phy_init_tbl {
|
||||
{ \
|
||||
.offset = o, \
|
||||
.val = v, \
|
||||
.name = #o, \
|
||||
.lane_mask = 0xff, \
|
||||
}
|
||||
|
||||
@ -27,13 +29,13 @@ struct qmp_phy_init_tbl {
|
||||
{ \
|
||||
.offset = o, \
|
||||
.val = v, \
|
||||
.name = #o, \
|
||||
.lane_mask = l, \
|
||||
}
|
||||
|
||||
static inline void qmp_configure_lane(void __iomem *base,
|
||||
const struct qmp_phy_init_tbl tbl[],
|
||||
int num,
|
||||
u8 lane_mask)
|
||||
static inline void qmp_configure_lane(struct device *dev, void __iomem *base,
|
||||
const struct qmp_phy_init_tbl tbl[],
|
||||
int num, u8 lane_mask)
|
||||
{
|
||||
int i;
|
||||
const struct qmp_phy_init_tbl *t = tbl;
|
||||
@ -45,15 +47,16 @@ static inline void qmp_configure_lane(void __iomem *base,
|
||||
if (!(t->lane_mask & lane_mask))
|
||||
continue;
|
||||
|
||||
dev_dbg(dev, "Writing Reg: %s Offset: 0x%04x Val: 0x%02x\n",
|
||||
t->name, t->offset, t->val);
|
||||
writel(t->val, base + t->offset);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void qmp_configure(void __iomem *base,
|
||||
const struct qmp_phy_init_tbl tbl[],
|
||||
int num)
|
||||
static inline void qmp_configure(struct device *dev, void __iomem *base,
|
||||
const struct qmp_phy_init_tbl tbl[], int num)
|
||||
{
|
||||
qmp_configure_lane(base, tbl, num, 0xff);
|
||||
qmp_configure_lane(dev, base, tbl, num, 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -288,7 +288,7 @@ static int qmp_pcie_msm8996_serdes_init(struct qmp_phy *qphy)
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
qmp_configure(serdes, serdes_tbl, serdes_tbl_num);
|
||||
qmp_configure(qmp->dev, serdes, serdes_tbl, serdes_tbl_num);
|
||||
|
||||
qphy_clrbits(serdes, cfg->regs[QPHY_COM_SW_RESET], SW_RESET);
|
||||
qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL],
|
||||
@ -431,9 +431,9 @@ static int qmp_pcie_msm8996_power_on(struct phy *phy)
|
||||
}
|
||||
|
||||
/* Tx, Rx, and PCS configurations */
|
||||
qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
|
||||
/*
|
||||
* Pull out PHY from POWER DOWN state.
|
||||
@ -725,7 +725,6 @@ static int qmp_pcie_msm8996_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_qmp *qmp;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *child;
|
||||
struct phy_provider *phy_provider;
|
||||
void __iomem *serdes;
|
||||
const struct qmp_phy_cfg *cfg = NULL;
|
||||
@ -773,13 +772,13 @@ static int qmp_pcie_msm8996_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
id = 0;
|
||||
for_each_available_child_of_node(dev->of_node, child) {
|
||||
for_each_available_child_of_node_scoped(dev->of_node, child) {
|
||||
/* Create per-lane phy */
|
||||
ret = qmp_pcie_msm8996_create(dev, child, id, serdes, cfg);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to create lane%d phy, %d\n",
|
||||
id, ret);
|
||||
goto err_node_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -790,7 +789,7 @@ static int qmp_pcie_msm8996_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(qmp->dev,
|
||||
"failed to register pipe clock source\n");
|
||||
goto err_node_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
id++;
|
||||
@ -799,10 +798,6 @@ static int qmp_pcie_msm8996_probe(struct platform_device *pdev)
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
|
||||
err_node_put:
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver qmp_pcie_msm8996_driver = {
|
||||
|
@ -1242,6 +1242,10 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x4_pcie_serdes_4ln_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x1c),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88),
|
||||
@ -3654,6 +3658,41 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = {
|
||||
.ln_shrd = x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl,
|
||||
.ln_shrd_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl),
|
||||
},
|
||||
|
||||
.reset_list = sdm845_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
|
||||
.vreg_list = sm8550_qmp_phy_vreg_l,
|
||||
.num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l),
|
||||
.regs = pciephy_v6_regs_layout,
|
||||
|
||||
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
|
||||
.phy_status = PHYSTATUS_4_20,
|
||||
.has_nocsr_reset = true,
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = {
|
||||
.lanes = 4,
|
||||
|
||||
.offsets = &qmp_pcie_offsets_v6_20,
|
||||
|
||||
.tbls = {
|
||||
.serdes = x1e80100_qmp_gen4x2_pcie_serdes_tbl,
|
||||
.serdes_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_serdes_tbl),
|
||||
.tx = x1e80100_qmp_gen4x2_pcie_tx_tbl,
|
||||
.tx_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_tx_tbl),
|
||||
.rx = x1e80100_qmp_gen4x2_pcie_rx_tbl,
|
||||
.rx_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_rx_tbl),
|
||||
.pcs = x1e80100_qmp_gen4x2_pcie_pcs_tbl,
|
||||
.pcs_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_tbl),
|
||||
.pcs_misc = x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl),
|
||||
.ln_shrd = x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl,
|
||||
.ln_shrd_num = ARRAY_SIZE(x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl),
|
||||
},
|
||||
|
||||
.serdes_4ln_tbl = x1e80100_qmp_gen4x4_pcie_serdes_4ln_tbl,
|
||||
.serdes_4ln_num = ARRAY_SIZE(x1e80100_qmp_gen4x4_pcie_serdes_4ln_tbl),
|
||||
|
||||
.reset_list = sdm845_pciephy_reset_l,
|
||||
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
|
||||
.vreg_list = sm8550_qmp_phy_vreg_l,
|
||||
@ -3669,18 +3708,30 @@ static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_
|
||||
{
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
const struct qmp_pcie_offsets *offs = cfg->offsets;
|
||||
void __iomem *tx3, *rx3, *tx4, *rx4;
|
||||
void __iomem *serdes, *tx3, *rx3, *tx4, *rx4, *pcs, *pcs_misc, *ln_shrd;
|
||||
|
||||
serdes = qmp->port_b + offs->serdes;
|
||||
tx3 = qmp->port_b + offs->tx;
|
||||
rx3 = qmp->port_b + offs->rx;
|
||||
tx4 = qmp->port_b + offs->tx2;
|
||||
rx4 = qmp->port_b + offs->rx2;
|
||||
pcs = qmp->port_b + offs->pcs;
|
||||
pcs_misc = qmp->port_b + offs->pcs_misc;
|
||||
ln_shrd = qmp->port_b + offs->ln_shrd;
|
||||
|
||||
qmp_configure_lane(tx3, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(rx3, tbls->rx, tbls->rx_num, 1);
|
||||
qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
|
||||
|
||||
qmp_configure_lane(tx4, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(rx4, tbls->rx, tbls->rx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, tx3, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx3, tbls->rx, tbls->rx_num, 1);
|
||||
|
||||
qmp_configure_lane(qmp->dev, tx4, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, rx4, tbls->rx, tbls->rx_num, 2);
|
||||
|
||||
qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num);
|
||||
qmp_configure(qmp->dev, pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
|
||||
|
||||
qmp_configure(qmp->dev, ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
|
||||
}
|
||||
|
||||
static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
||||
@ -3698,25 +3749,26 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
|
||||
if (!tbls)
|
||||
return;
|
||||
|
||||
qmp_configure(serdes, tbls->serdes, tbls->serdes_num);
|
||||
qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
|
||||
|
||||
qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
|
||||
qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
|
||||
|
||||
if (cfg->lanes >= 2) {
|
||||
qmp_configure_lane(tx2, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, tx2, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, rx2, tbls->rx, tbls->rx_num, 2);
|
||||
}
|
||||
|
||||
qmp_configure(pcs, tbls->pcs, tbls->pcs_num);
|
||||
qmp_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
|
||||
qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num);
|
||||
qmp_configure(qmp->dev, pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
|
||||
|
||||
if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
|
||||
qmp_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
|
||||
qmp_configure(qmp->dev, serdes, cfg->serdes_4ln_tbl,
|
||||
cfg->serdes_4ln_num);
|
||||
qmp_pcie_init_port_b(qmp, tbls);
|
||||
}
|
||||
|
||||
qmp_configure(ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
|
||||
qmp_configure(qmp->dev, ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
|
||||
}
|
||||
|
||||
static int qmp_pcie_init(struct phy *phy)
|
||||
@ -4423,6 +4475,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy",
|
||||
.data = &x1e80100_qmp_gen4x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,x1e80100-qmp-gen4x4-pcie-phy",
|
||||
.data = &x1e80100_qmp_gen4x4_pciephy_cfg,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
@ -1527,7 +1527,7 @@ static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tb
|
||||
{
|
||||
void __iomem *serdes = qmp->serdes;
|
||||
|
||||
qmp_configure(serdes, tbls->serdes, tbls->serdes_num);
|
||||
qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num);
|
||||
}
|
||||
|
||||
static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
|
||||
@ -1536,12 +1536,12 @@ static void qmp_ufs_lanes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbl
|
||||
void __iomem *tx = qmp->tx;
|
||||
void __iomem *rx = qmp->rx;
|
||||
|
||||
qmp_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
|
||||
qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1);
|
||||
|
||||
if (cfg->lanes >= 2) {
|
||||
qmp_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, qmp->tx2, tbls->tx, tbls->tx_num, 2);
|
||||
qmp_configure_lane(qmp->dev, qmp->rx2, tbls->rx, tbls->rx_num, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1549,7 +1549,7 @@ static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls
|
||||
{
|
||||
void __iomem *pcs = qmp->pcs;
|
||||
|
||||
qmp_configure(pcs, tbls->pcs, tbls->pcs_num);
|
||||
qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num);
|
||||
}
|
||||
|
||||
static int qmp_ufs_get_gear_overlay(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
|
||||
|
@ -1649,7 +1649,7 @@ static int qmp_usb_serdes_init(struct qmp_usb *qmp)
|
||||
const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
|
||||
int serdes_tbl_num = cfg->serdes_tbl_num;
|
||||
|
||||
qmp_configure(serdes, serdes_tbl, serdes_tbl_num);
|
||||
qmp_configure(qmp->dev, serdes, serdes_tbl, serdes_tbl_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1730,13 +1730,13 @@ static int qmp_usb_power_on(struct phy *phy)
|
||||
}
|
||||
|
||||
/* Tx, Rx, and PCS configurations */
|
||||
qmp_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
|
||||
qmp_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
|
||||
if (pcs_usb)
|
||||
qmp_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
|
||||
qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num);
|
||||
|
||||
if (cfg->has_pwrdn_delay)
|
||||
usleep_range(10, 20);
|
||||
|
@ -526,7 +526,8 @@ static int qmp_usbc_power_on(struct phy *phy)
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
qmp_configure(qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
|
||||
qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl,
|
||||
cfg->serdes_tbl_num);
|
||||
|
||||
ret = clk_prepare_enable(qmp->pipe_clk);
|
||||
if (ret) {
|
||||
@ -535,13 +536,13 @@ static int qmp_usbc_power_on(struct phy *phy)
|
||||
}
|
||||
|
||||
/* Tx, Rx, and PCS configurations */
|
||||
qmp_configure_lane(qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
qmp_configure_lane(qmp->dev, qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
|
||||
qmp_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->dev, qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
|
||||
qmp_configure_lane(qmp->dev, qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
|
||||
qmp_configure(qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
qmp_configure(qmp->dev, qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
|
||||
/* Pull PHY out of reset state */
|
||||
qphy_clrbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
|
||||
|
@ -19,12 +19,14 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/usb/of.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/******* USB2.0 Host registers (original offset is +0x200) *******/
|
||||
#define USB2_INT_ENABLE 0x000
|
||||
#define USB2_AHB_BUS_CTR 0x008
|
||||
#define USB2_USBCTR 0x00c
|
||||
#define USB2_SPD_RSM_TIMSET 0x10c
|
||||
#define USB2_OC_TIMSET 0x110
|
||||
@ -40,6 +42,10 @@
|
||||
#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) /* For EHCI */
|
||||
#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) /* For OHCI */
|
||||
|
||||
/* AHB_BUS_CTR */
|
||||
#define USB2_AHB_BUS_CTR_MBL_MASK GENMASK(1, 0)
|
||||
#define USB2_AHB_BUS_CTR_MBL_INCR4 2
|
||||
|
||||
/* USBCTR */
|
||||
#define USB2_USBCTR_DIRPD BIT(2)
|
||||
#define USB2_USBCTR_PLL_RST BIT(1)
|
||||
@ -111,6 +117,7 @@ struct rcar_gen3_chan {
|
||||
struct extcon_dev *extcon;
|
||||
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
|
||||
struct regulator *vbus;
|
||||
struct reset_control *rstc;
|
||||
struct work_struct work;
|
||||
struct mutex lock; /* protects rphys[...].powered */
|
||||
enum usb_dr_mode dr_mode;
|
||||
@ -125,6 +132,7 @@ struct rcar_gen3_chan {
|
||||
struct rcar_gen3_phy_drv_data {
|
||||
const struct phy_ops *phy_usb2_ops;
|
||||
bool no_adp_ctrl;
|
||||
bool init_bus;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -575,6 +583,12 @@ static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = {
|
||||
.no_adp_ctrl = true,
|
||||
};
|
||||
|
||||
static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
|
||||
.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
|
||||
.no_adp_ctrl = true,
|
||||
.init_bus = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
|
||||
{
|
||||
.compatible = "renesas,usb2-phy-r8a77470",
|
||||
@ -596,6 +610,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
|
||||
.compatible = "renesas,rzg2l-usb2-phy",
|
||||
.data = &rz_g2l_phy_usb2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,usb2-phy-r9a08g045",
|
||||
.data = &rz_g3s_phy_usb2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,rcar-gen3-usb2-phy",
|
||||
.data = &rcar_gen3_phy_usb2_data,
|
||||
@ -650,6 +668,35 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
|
||||
{
|
||||
struct device *dev = channel->dev;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
channel->rstc = devm_reset_control_array_get_shared(dev);
|
||||
if (IS_ERR(channel->rstc))
|
||||
return PTR_ERR(channel->rstc);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(channel->rstc);
|
||||
if (ret)
|
||||
goto rpm_put;
|
||||
|
||||
val = readl(channel->base + USB2_AHB_BUS_CTR);
|
||||
val &= ~USB2_AHB_BUS_CTR_MBL_MASK;
|
||||
val |= USB2_AHB_BUS_CTR_MBL_INCR4;
|
||||
writel(val, channel->base + USB2_AHB_BUS_CTR);
|
||||
|
||||
rpm_put:
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct rcar_gen3_phy_drv_data *phy_data;
|
||||
@ -703,6 +750,15 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, channel);
|
||||
channel->dev = dev;
|
||||
|
||||
if (phy_data->init_bus) {
|
||||
ret = rcar_gen3_phy_usb2_init_bus(channel);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
|
||||
channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
|
||||
if (phy_data->no_adp_ctrl)
|
||||
channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
|
||||
@ -733,9 +789,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
channel->vbus = NULL;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, channel);
|
||||
channel->dev = dev;
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "Failed to register PHY provider\n");
|
||||
@ -762,6 +815,7 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
|
||||
if (channel->is_otg_channel)
|
||||
device_remove_file(&pdev->dev, &dev_attr_role);
|
||||
|
||||
reset_control_assert(channel->rstc);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
@ -15,6 +16,7 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/rational.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
@ -190,6 +192,8 @@
|
||||
#define LN3_TX_SER_RATE_SEL_HBR2 BIT(3)
|
||||
#define LN3_TX_SER_RATE_SEL_HBR3 BIT(2)
|
||||
|
||||
#define HDMI20_MAX_RATE 600000000
|
||||
|
||||
struct lcpll_config {
|
||||
u32 bit_rate;
|
||||
u8 lcvco_mode_en;
|
||||
@ -272,6 +276,12 @@ struct rk_hdptx_phy {
|
||||
struct clk_bulk_data *clks;
|
||||
int nr_clks;
|
||||
struct reset_control_bulk_data rsts[RST_MAX];
|
||||
|
||||
/* clk provider */
|
||||
struct clk_hw hw;
|
||||
unsigned long rate;
|
||||
|
||||
atomic_t usage_count;
|
||||
};
|
||||
|
||||
static const struct ropll_config ropll_tmds_cfg[] = {
|
||||
@ -759,6 +769,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
|
||||
struct ropll_config rc = {0};
|
||||
int i;
|
||||
|
||||
hdptx->rate = rate * 100;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
if (rate == ropll_tmds_cfg[i].bit_rate) {
|
||||
cfg = &ropll_tmds_cfg[i];
|
||||
@ -822,19 +834,6 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
|
||||
static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
|
||||
unsigned int rate)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(val & HDPTX_O_PLL_LOCK_DONE)) {
|
||||
ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
|
||||
|
||||
regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
|
||||
@ -856,10 +855,68 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
|
||||
return rk_hdptx_post_enable_lane(hdptx);
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx,
|
||||
unsigned int rate)
|
||||
{
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
if (atomic_inc_return(&hdptx->usage_count) > 1)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);
|
||||
if (ret)
|
||||
goto dec_usage;
|
||||
|
||||
if (status & HDPTX_O_PLL_LOCK_DONE)
|
||||
dev_warn(hdptx->dev, "PLL locked by unknown consumer!\n");
|
||||
|
||||
if (rate) {
|
||||
ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
|
||||
if (ret)
|
||||
goto dec_usage;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
dec_usage:
|
||||
atomic_dec(&hdptx->usage_count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)
|
||||
{
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
ret = atomic_dec_return(&hdptx->usage_count);
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
|
||||
if (ret < 0) {
|
||||
dev_warn(hdptx->dev, "Usage count underflow!\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);
|
||||
if (!ret) {
|
||||
if (status & HDPTX_O_PLL_LOCK_DONE)
|
||||
rk_hdptx_phy_disable(hdptx);
|
||||
return 0;
|
||||
} else if (force) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&hdptx->usage_count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
|
||||
int ret, bus_width = phy_get_bus_width(hdptx->phy);
|
||||
int bus_width = phy_get_bus_width(hdptx->phy);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* FIXME: Temporary workaround to pass pixel_clk_rate
|
||||
* from the HDMI bridge driver until phy_configure_opts_hdmi
|
||||
@ -870,15 +927,13 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
|
||||
__func__, bus_width, rate);
|
||||
|
||||
ret = pm_runtime_resume_and_get(hdptx->dev);
|
||||
if (ret) {
|
||||
dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
|
||||
ret = rk_hdptx_phy_consumer_get(hdptx, rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
|
||||
if (ret)
|
||||
pm_runtime_put(hdptx->dev);
|
||||
rk_hdptx_phy_consumer_put(hdptx, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -886,16 +941,8 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
|
||||
static int rk_hdptx_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
|
||||
if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
|
||||
rk_hdptx_phy_disable(hdptx);
|
||||
|
||||
pm_runtime_put(hdptx->dev);
|
||||
|
||||
return ret;
|
||||
return rk_hdptx_phy_consumer_put(hdptx, false);
|
||||
}
|
||||
|
||||
static const struct phy_ops rk_hdptx_phy_ops = {
|
||||
@ -904,6 +951,99 @@ static const struct phy_ops rk_hdptx_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct rk_hdptx_phy *to_rk_hdptx_phy(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct rk_hdptx_phy, hw);
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_clk_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
|
||||
return rk_hdptx_phy_consumer_get(hdptx, hdptx->rate / 100);
|
||||
}
|
||||
|
||||
static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
|
||||
rk_hdptx_phy_consumer_put(hdptx, true);
|
||||
}
|
||||
|
||||
static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
|
||||
return hdptx->rate;
|
||||
}
|
||||
|
||||
static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
u32 bit_rate = rate / 100;
|
||||
int i;
|
||||
|
||||
if (rate > HDMI20_MAX_RATE)
|
||||
return rate;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
if (bit_rate == ropll_tmds_cfg[i].bit_rate)
|
||||
break;
|
||||
|
||||
if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
|
||||
!rk_hdptx_phy_clk_pll_calc(bit_rate, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
|
||||
|
||||
return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);
|
||||
}
|
||||
|
||||
static const struct clk_ops hdptx_phy_clk_ops = {
|
||||
.prepare = rk_hdptx_phy_clk_prepare,
|
||||
.unprepare = rk_hdptx_phy_clk_unprepare,
|
||||
.recalc_rate = rk_hdptx_phy_clk_recalc_rate,
|
||||
.round_rate = rk_hdptx_phy_clk_round_rate,
|
||||
.set_rate = rk_hdptx_phy_clk_set_rate,
|
||||
};
|
||||
|
||||
static int rk_hdptx_phy_clk_register(struct rk_hdptx_phy *hdptx)
|
||||
{
|
||||
struct device *dev = hdptx->dev;
|
||||
const char *name, *pname;
|
||||
struct clk *refclk;
|
||||
int ret, id;
|
||||
|
||||
refclk = devm_clk_get(dev, "ref");
|
||||
if (IS_ERR(refclk))
|
||||
return dev_err_probe(dev, PTR_ERR(refclk),
|
||||
"Failed to get ref clock\n");
|
||||
|
||||
id = of_alias_get_id(dev->of_node, "hdptxphy");
|
||||
name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
|
||||
pname = __clk_get_name(refclk);
|
||||
|
||||
hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops,
|
||||
CLK_GET_RATE_NOCACHE);
|
||||
|
||||
ret = devm_clk_hw_register(dev, &hdptx->hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to register clock\n");
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &hdptx->hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register clk provider\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_hdptx_phy_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
|
||||
@ -976,6 +1116,10 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(hdptx->grf),
|
||||
"Could not get GRF syscon\n");
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
|
||||
|
||||
hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops);
|
||||
if (IS_ERR(hdptx->phy))
|
||||
return dev_err_probe(dev, PTR_ERR(hdptx->phy),
|
||||
@ -985,10 +1129,6 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
phy_set_drvdata(hdptx->phy, hdptx);
|
||||
phy_set_bus_width(hdptx->phy, 8);
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return dev_err_probe(dev, PTR_ERR(phy_provider),
|
||||
@ -998,7 +1138,7 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
|
||||
reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
|
||||
reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
|
||||
|
||||
return 0;
|
||||
return rk_hdptx_phy_clk_register(hdptx);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
|
||||
|
@ -607,7 +607,7 @@ exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(struct exynos5_usbdrd_phy *phy_drd)
|
||||
|
||||
reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL);
|
||||
reg &= ~SECPMACTL_PMA_REF_FREQ_SEL;
|
||||
reg |= FIELD_PREP_CONST(SECPMACTL_PMA_REF_FREQ_SEL, 1);
|
||||
reg |= FIELD_PREP(SECPMACTL_PMA_REF_FREQ_SEL, 1);
|
||||
/* SFR reset */
|
||||
reg |= (SECPMACTL_PMA_LOW_PWR | SECPMACTL_PMA_APB_SW_RST);
|
||||
reg &= ~(SECPMACTL_PMA_ROPLL_REF_CLK_SEL |
|
||||
@ -1123,19 +1123,19 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
|
||||
reg &= ~SSPPLLCTL_FSEL;
|
||||
switch (phy_drd->extrefclk) {
|
||||
case EXYNOS5_FSEL_50MHZ:
|
||||
reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 7);
|
||||
reg |= FIELD_PREP(SSPPLLCTL_FSEL, 7);
|
||||
break;
|
||||
case EXYNOS5_FSEL_26MHZ:
|
||||
reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 6);
|
||||
reg |= FIELD_PREP(SSPPLLCTL_FSEL, 6);
|
||||
break;
|
||||
case EXYNOS5_FSEL_24MHZ:
|
||||
reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 2);
|
||||
reg |= FIELD_PREP(SSPPLLCTL_FSEL, 2);
|
||||
break;
|
||||
case EXYNOS5_FSEL_20MHZ:
|
||||
reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 1);
|
||||
reg |= FIELD_PREP(SSPPLLCTL_FSEL, 1);
|
||||
break;
|
||||
case EXYNOS5_FSEL_19MHZ2:
|
||||
reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 0);
|
||||
reg |= FIELD_PREP(SSPPLLCTL_FSEL, 0);
|
||||
break;
|
||||
default:
|
||||
dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
@ -644,7 +645,6 @@ static int serdes_am654_clk_register(struct serdes_am654 *am654_phy,
|
||||
struct device_node *node = am654_phy->of_node;
|
||||
struct device *dev = am654_phy->dev;
|
||||
struct serdes_am654_clk_mux *mux;
|
||||
struct device_node *regmap_node;
|
||||
const char **parent_names;
|
||||
struct clk_init_data *init;
|
||||
unsigned int num_parents;
|
||||
@ -652,7 +652,6 @@ static int serdes_am654_clk_register(struct serdes_am654 *am654_phy,
|
||||
const __be32 *addr;
|
||||
unsigned int reg;
|
||||
struct clk *clk;
|
||||
int ret = 0;
|
||||
|
||||
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
@ -660,41 +659,30 @@ static int serdes_am654_clk_register(struct serdes_am654 *am654_phy,
|
||||
|
||||
init = &mux->clk_data;
|
||||
|
||||
regmap_node = of_parse_phandle(node, "ti,serdes-clk", 0);
|
||||
if (!regmap_node) {
|
||||
dev_err(dev, "Fail to get serdes-clk node\n");
|
||||
ret = -ENODEV;
|
||||
goto out_put_node;
|
||||
}
|
||||
struct device_node *regmap_node __free(device_node) =
|
||||
of_parse_phandle(node, "ti,serdes-clk", 0);
|
||||
if (!regmap_node)
|
||||
return dev_err_probe(dev, -ENODEV, "Fail to get serdes-clk node\n");
|
||||
|
||||
regmap = syscon_node_to_regmap(regmap_node->parent);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "Fail to get Syscon regmap\n");
|
||||
ret = PTR_ERR(regmap);
|
||||
goto out_put_node;
|
||||
}
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"Fail to get Syscon regmap\n");
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (num_parents < 2) {
|
||||
dev_err(dev, "SERDES clock must have parents\n");
|
||||
ret = -EINVAL;
|
||||
goto out_put_node;
|
||||
}
|
||||
if (num_parents < 2)
|
||||
return dev_err_probe(dev, -EINVAL, "SERDES clock must have parents\n");
|
||||
|
||||
parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents),
|
||||
GFP_KERNEL);
|
||||
if (!parent_names) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put_node;
|
||||
}
|
||||
if (!parent_names)
|
||||
return -ENOMEM;
|
||||
|
||||
of_clk_parent_fill(node, parent_names, num_parents);
|
||||
|
||||
addr = of_get_address(regmap_node, 0, NULL, NULL);
|
||||
if (!addr) {
|
||||
ret = -EINVAL;
|
||||
goto out_put_node;
|
||||
}
|
||||
if (!addr)
|
||||
return -EINVAL;
|
||||
|
||||
reg = be32_to_cpu(*addr);
|
||||
|
||||
@ -710,16 +698,12 @@ static int serdes_am654_clk_register(struct serdes_am654 *am654_phy,
|
||||
mux->hw.init = init;
|
||||
|
||||
clk = devm_clk_register(dev, &mux->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto out_put_node;
|
||||
}
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
am654_phy->clks[clock_num] = clk;
|
||||
|
||||
out_put_node:
|
||||
of_node_put(regmap_node);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id serdes_am654_id_table[] = {
|
||||
|
@ -468,11 +468,9 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
|
||||
priv->regmap = syscon_node_to_regmap(node->parent);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
priv->regmap = device_node_to_regmap(node);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
ret = PTR_ERR(priv->regmap);
|
||||
dev_err(dev, "Failed to get syscon %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(priv->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->regmap),
|
||||
"Failed to get syscon\n");
|
||||
priv->no_offset = true;
|
||||
}
|
||||
|
||||
@ -485,11 +483,9 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
|
||||
priv->phy_provider =
|
||||
devm_of_phy_provider_register(dev,
|
||||
phy_gmii_sel_of_xlate);
|
||||
if (IS_ERR(priv->phy_provider)) {
|
||||
ret = PTR_ERR(priv->phy_provider);
|
||||
dev_err(dev, "Failed to create phy provider %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(priv->phy_provider))
|
||||
return dev_err_probe(dev, PTR_ERR(priv->phy_provider),
|
||||
"Failed to create phy provider\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1179,14 +1179,13 @@ static int wiz_clock_probe(struct wiz *wiz, struct device_node *node)
|
||||
|
||||
ret = wiz_mux_of_clk_register(wiz, clk_node, wiz->mux_sel_field[i],
|
||||
clk_mux_sel[i].table);
|
||||
of_node_put(clk_node);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
of_node_put(clk_node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
of_node_put(clk_node);
|
||||
}
|
||||
|
||||
for (i = 0; i < wiz->clk_div_sel_num; i++) {
|
||||
@ -1199,14 +1198,12 @@ static int wiz_clock_probe(struct wiz *wiz, struct device_node *node)
|
||||
|
||||
ret = wiz_div_clk_register(wiz, clk_node, wiz->div_sel_field[i],
|
||||
clk_div_sel[i].table);
|
||||
of_node_put(clk_node);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Failed to register %s clock\n",
|
||||
node_name);
|
||||
of_node_put(clk_node);
|
||||
goto err;
|
||||
}
|
||||
|
||||
of_node_put(clk_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1407,7 +1404,7 @@ MODULE_DEVICE_TABLE(of, wiz_id_table);
|
||||
|
||||
static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
|
||||
{
|
||||
struct device_node *serdes, *subnode;
|
||||
struct device_node *serdes;
|
||||
|
||||
serdes = of_get_child_by_name(dev->of_node, "serdes");
|
||||
if (!serdes) {
|
||||
@ -1415,7 +1412,7 @@ static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_child_of_node(serdes, subnode) {
|
||||
for_each_child_of_node_scoped(serdes, subnode) {
|
||||
u32 reg, num_lanes = 1, phy_type = PHY_NONE;
|
||||
int ret, i;
|
||||
|
||||
@ -1425,7 +1422,6 @@ static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
|
||||
|
||||
ret = of_property_read_u32(subnode, "reg", ®);
|
||||
if (ret) {
|
||||
of_node_put(subnode);
|
||||
dev_err(dev,
|
||||
"%s: Reading \"reg\" from \"%s\" failed: %d\n",
|
||||
__func__, subnode->name, ret);
|
||||
@ -1578,8 +1574,8 @@ static int wiz_probe(struct platform_device *pdev)
|
||||
|
||||
phy_reset_dev = &wiz->wiz_phy_reset_dev;
|
||||
phy_reset_dev->dev = dev;
|
||||
phy_reset_dev->ops = &wiz_phy_reset_ops,
|
||||
phy_reset_dev->owner = THIS_MODULE,
|
||||
phy_reset_dev->ops = &wiz_phy_reset_ops;
|
||||
phy_reset_dev->owner = THIS_MODULE;
|
||||
phy_reset_dev->of_node = node;
|
||||
/* Reset for each of the lane and one for the entire SERDES */
|
||||
phy_reset_dev->nr_resets = num_lanes + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user