mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-02 20:59:30 +00:00
phy-for-5.11
- New phy drivers: - Mediatek MT7621 PCIe PHY (promoted from staging) - Ingenic USB phy driver supporting JZ4775 and X2000 - Intel Keem Bay USB PHY driver - Marvell USB HSIC PHY driver supporting MMP3 SoC - AXG MIPI D-PHY driver - Updates: - Conversion to YAML binding for: - Broadcom SATA PHY - Cadence Sierra PHY bindings - STM32 USBC Phy - Support for Exynos5433 PCIe PHY - Support for Qualcomm SM8250 PCIe QMP PHY - Support for Exynos5420 USB2 phy - devm_platform_ioremap_resource conversion for bunch of drivers -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAl/QyKEACgkQfBQHDyUj g0dlsQ/9FR80zeSI/9+DPmnTLu4GvK80dybhk5qOCKenmWeiVsNq2j7s0HQ1nCm9 khKZ1FysKlx1Bg1DBr3OEdM9TxLG0+An4w/rjo48gTvR+6o/YStAU1tC9ZYT76Dh Qnx0jx5QxTu9mimYSDQdJs8u74iKsNKAkQIXrVuFgNnABgPxOm0ysCJomGth/9zl p5hj+21g519+DMzivzkjXcMA2mmIjaWtKKnZQatrRjLIuSpcbgjZMjjNdeUfJ+m0 N/89L9w5uuM9cu0JKs8MNBDN/WSNEwZw7bot6lA2JaG/Wnhmm/qLuIDCeFCr0Ado jJkuunDidbel7FAE4O+ViMOmCaN0mDBm+fohZGT+kDUuv3d8w0ID+z1x1hj11SLQ ejF855dfLpvmDkh8XVPTb1+euJB04Msm3LMy9puBqxittEJyRvIcX/d1IL1EZ1sN Y0KYcY7HtN9QwUjUCWO2zU1xuFJ7CiJLCnvbIUzTPL5Em1be5cqaujsBGdHJpfeH cQGTqLC8NcgK+eTalLbvXmDG62kllr6EWRy5KNkkP0VfIwsfaGYzdYGJZ4waUXCp MAa500XOufzIrGakYWqIttUbA3EimMKrLakvPV6VCH+qATe2xLRRHNEY1cBQH6tK FzEZzmS1H0mA8TtDhSKFTaciG3gBLmQDRMEeVJY6GFlel6N0Kg8= =EFMp -----END PGP SIGNATURE----- Merge tag 'phy-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy into char-misc-next Vinod writes: phy-for-5.11 - New phy drivers: - Mediatek MT7621 PCIe PHY (promoted from staging) - Ingenic USB phy driver supporting JZ4775 and X2000 - Intel Keem Bay USB PHY driver - Marvell USB HSIC PHY driver supporting MMP3 SoC - AXG MIPI D-PHY driver - Updates: - Conversion to YAML binding for: - Broadcom SATA PHY - Cadence Sierra PHY bindings - STM32 USBC Phy - Support for Exynos5433 PCIe PHY - Support for Qualcomm SM8250 PCIe QMP PHY - Support for Exynos5420 USB2 phy - devm_platform_ioremap_resource conversion for bunch of drivers * tag 'phy-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (72 commits) drm/mediatek: avoid dereferencing a null hdmi_phy on an error message phy: ingenic: depend on HAS_IOMEM phy: mediatek: statify mtk_hdmi_phy_driver dt-bindings: phy: Convert Broadcom SATA PHY to YAML devicetree: phy: rockchip-emmc add output-tapdelay-select phy: rockchip-emmc: output tap delay dt property PHY: Ingenic: Add USB PHY driver using generic PHY framework. dt-bindings: USB: Add bindings for Ingenic JZ4775 and X2000. USB: PHY: JZ4770: Remove unnecessary function calls. devicetree: phy: rockchip-emmc: pulldown property phy: rockchip: set pulldown for strobe line in dts phy: renesas: rcar-gen3-usb2: disable runtime pm in case of failure phy: mediatek: allow compile-testing the hdmi phy phy/rockchip: Make PHY_ROCKCHIP_INNO_HDMI depend on HAS_IOMEM to fix build error phy: samsung: Merge Kconfig for Exynos5420 and Exynos5250 phy: ralink: phy-mt7621-pci: set correct name in MODULE_DEVICE_TABLE macro phy: ralink: phy-mt7621-pci: drop 'COMPILE_TEST' from Kconfig phy: mediatek: Make PHY_MTK_{XSPHY, TPHY} depend on HAS_IOMEM and OF_ADDRESS to fix build errors phy: tegra: xusb: Fix usb_phy device driver field phy: amlogic: replace devm_reset_control_array_get() ...
This commit is contained in:
commit
54bf54c859
@ -92,7 +92,7 @@ required:
|
||||
|
||||
patternProperties:
|
||||
"^usb-phy@[a-f0-9]+$":
|
||||
allOf: [ $ref: "../usb/ingenic,jz4770-phy.yaml#" ]
|
||||
allOf: [ $ref: "../phy/ingenic,phy-usb.yaml#" ]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright 2020 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/amlogic,axg-mipi-dphy.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Amlogic AXG MIPI D-PHY
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <narmstrong@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,axg-mipi-dphy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
items:
|
||||
- const: analog
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- phys
|
||||
- phy-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@ff640000 {
|
||||
compatible = "amlogic,axg-mipi-dphy";
|
||||
reg = <0xff640000 0x100>;
|
||||
clocks = <&clk_mipi_dsi_phy>;
|
||||
clock-names = "pclk";
|
||||
resets = <&reset_phy>;
|
||||
reset-names = "phy";
|
||||
phys = <&mipi_pcie_analog_dphy>;
|
||||
phy-names = "analog";
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -9,27 +9,32 @@ title: Amlogic AXG shared MIPI/PCIE analog PHY
|
||||
maintainers:
|
||||
- Remi Pommarel <repk@triplefau.lt>
|
||||
|
||||
description: |+
|
||||
The Everything-Else Power Domains node should be the child of a syscon
|
||||
node with the required property:
|
||||
|
||||
- compatible: Should be the following:
|
||||
"amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon"
|
||||
|
||||
Refer to the the bindings described in
|
||||
Documentation/devicetree/bindings/mfd/syscon.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: amlogic,axg-mipi-pcie-analog-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mpphy: phy@0 {
|
||||
mpphy: phy {
|
||||
compatible = "amlogic,axg-mipi-pcie-analog-phy";
|
||||
reg = <0x0 0xc>;
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
148
Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml
Normal file
148
Documentation/devicetree/bindings/phy/brcm,sata-phy.yaml
Normal file
@ -0,0 +1,148 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/brcm,sata-phy.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Broadcom SATA3 PHY
|
||||
|
||||
maintainers:
|
||||
- Florian Fainelli <f.fainelli@gmail.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^sata[-|_]phy(@.*)?$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm7216-sata-phy
|
||||
- brcm,bcm7425-sata-phy
|
||||
- brcm,bcm7445-sata-phy
|
||||
- brcm,bcm63138-sata-phy
|
||||
- const: brcm,phy-sata3
|
||||
- items:
|
||||
- const: brcm,iproc-nsp-sata-phy
|
||||
- items:
|
||||
- const: brcm,iproc-ns2-sata-phy
|
||||
- items:
|
||||
- const: brcm,iproc-sr-sata-phy
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: phy
|
||||
- const: phy-ctrl
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^sata-phy@[0-9]+$":
|
||||
type: object
|
||||
description: |
|
||||
Each port's PHY should be represented as a sub-node.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: The SATA PHY port number
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
"brcm,enable-ssc":
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: |
|
||||
Use spread spectrum clocking (SSC) on this port
|
||||
This property is not applicable for "brcm,iproc-ns2-sata-phy",
|
||||
"brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy".
|
||||
|
||||
"brcm,rxaeq-mode":
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
String that indicates the desired RX equalizer mode.
|
||||
enum:
|
||||
- off
|
||||
- auto
|
||||
- manual
|
||||
|
||||
"brcm,rxaeq-value":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
When 'brcm,rxaeq-mode' is set to "manual", provides the RX
|
||||
equalizer value that should be used.
|
||||
minimum: 0
|
||||
maximum: 63
|
||||
|
||||
"brcm,tx-amplitude-millivolt":
|
||||
description: |
|
||||
Transmit amplitude voltage in millivolt.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [400, 500, 600, 800]
|
||||
|
||||
required:
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: brcm,iproc-ns2-sata-phy
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 2
|
||||
reg-names:
|
||||
items:
|
||||
- const: "phy"
|
||||
- const: "phy-ctrl"
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
items:
|
||||
- const: "phy"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- reg
|
||||
- reg-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sata_phy@f0458100 {
|
||||
compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3";
|
||||
reg = <0xf0458100 0x1e00>;
|
||||
reg-names = "phy";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
sata-phy@0 {
|
||||
reg = <0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
sata-phy@1 {
|
||||
reg = <1>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
* Broadcom SATA3 PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one or more of
|
||||
"brcm,bcm7216-sata-phy"
|
||||
"brcm,bcm7425-sata-phy"
|
||||
"brcm,bcm7445-sata-phy"
|
||||
"brcm,iproc-ns2-sata-phy"
|
||||
"brcm,iproc-nsp-sata-phy"
|
||||
"brcm,phy-sata3"
|
||||
"brcm,iproc-sr-sata-phy"
|
||||
"brcm,bcm63138-sata-phy"
|
||||
- address-cells: should be 1
|
||||
- size-cells: should be 0
|
||||
- reg: register ranges for the PHY PCB interface
|
||||
- reg-names: should be "phy" and "phy-ctrl"
|
||||
The "phy-ctrl" registers are only required for
|
||||
"brcm,iproc-ns2-sata-phy" and "brcm,iproc-sr-sata-phy".
|
||||
|
||||
Sub-nodes:
|
||||
Each port's PHY should be represented as a sub-node.
|
||||
|
||||
Sub-nodes required properties:
|
||||
- reg: the PHY number
|
||||
- phy-cells: generic PHY binding; must be 0
|
||||
|
||||
Sub-nodes optional properties:
|
||||
- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
|
||||
This property is not applicable for "brcm,iproc-ns2-sata-phy",
|
||||
"brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy".
|
||||
|
||||
- brcm,rxaeq-mode: string that indicates the desired RX equalizer
|
||||
mode, possible values are:
|
||||
"off" (equivalent to not specifying the property)
|
||||
"auto"
|
||||
"manual" (brcm,rxaeq-value is used in that case)
|
||||
|
||||
- brcm,rxaeq-value: when 'rxaeq-mode' is set to "manual", provides the RX
|
||||
equalizer value that should be used. Allowed range is 0..63.
|
||||
|
||||
Example
|
||||
sata-phy@f0458100 {
|
||||
compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3";
|
||||
reg = <0xf0458100 0x1e00>, <0xf045804c 0x10>;
|
||||
reg-names = "phy";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
sata-phy@0 {
|
||||
reg = <0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
sata-phy@1 {
|
||||
reg = <1>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/usb/ingenic,jz4770-phy.yaml#
|
||||
$id: http://devicetree.org/schemas/phy/ingenic,phy-usb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Ingenic SoCs USB PHY devicetree bindings
|
||||
@ -17,9 +17,11 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ingenic,jz4770-phy
|
||||
- ingenic,jz4775-phy
|
||||
- ingenic,jz4780-phy
|
||||
- ingenic,x1000-phy
|
||||
- ingenic,x1830-phy
|
||||
- ingenic,x2000-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/intel,phy-keembay-usb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Intel Keem Bay USB PHY bindings
|
||||
|
||||
maintainers:
|
||||
- Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: intel,keembay-usb-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: USB APB CPR (clock, power, reset) register
|
||||
- description: USB APB slave register
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: cpr-apb-base
|
||||
- const: slv-apb-base
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
usb-phy@20400000 {
|
||||
compatible = "intel,keembay-usb-phy";
|
||||
reg = <0x20400000 0x1c>,
|
||||
<0x20480000 0xd0>;
|
||||
reg-names = "cpr-apb-base", "slv-apb-base";
|
||||
#phy-cells = <0>;
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
|
||||
# Copyright 2019 Lubomir Rintel <lkundrak@v3.sk>
|
||||
%YAML 1.2
|
||||
---
|
||||
@ -18,27 +18,20 @@ properties:
|
||||
maxItems: 1
|
||||
description: base address of the device
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description: GPIO connected to reset
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
hsic-phy@f0001800 {
|
||||
compatible = "marvell,mmp3-hsic-phy";
|
||||
reg = <0xf0001800 0x40>;
|
||||
reset-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/mediatek,mt7621-pci-phy.yaml#"
|
@ -1,70 +0,0 @@
|
||||
Cadence Sierra PHY
|
||||
-----------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "cdns,sierra-phy-t0" for Sierra in Cadence platform
|
||||
Must be "ti,sierra-phy-t0" for Sierra in TI's J721E SoC.
|
||||
- resets: Must contain an entry for each in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include "sierra_reset" and "sierra_apb".
|
||||
"sierra_reset" must control the reset line to the PHY.
|
||||
"sierra_apb" must control the reset line to the APB PHY
|
||||
interface ("sierra_apb" is optional).
|
||||
- reg: register range for the PHY.
|
||||
- #address-cells: Must be 1
|
||||
- #size-cells: Must be 0
|
||||
|
||||
Optional properties:
|
||||
- clocks: Must contain an entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must contain "cmn_refclk_dig_div" and
|
||||
"cmn_refclk1_dig_div" for configuring the frequency of
|
||||
the clock to the lanes. "phy_clk" is deprecated.
|
||||
- cdns,autoconf: A boolean property whose presence indicates that the
|
||||
PHY registers will be configured by hardware. If not
|
||||
present, all sub-node optional properties must be
|
||||
provided.
|
||||
|
||||
Sub-nodes:
|
||||
Each group of PHY lanes with a single master lane should be represented as
|
||||
a sub-node. Note that the actual configuration of each lane is determined by
|
||||
hardware strapping, and must match the configuration specified here.
|
||||
|
||||
Sub-node required properties:
|
||||
- #phy-cells: Generic PHY binding; must be 0.
|
||||
- reg: The master lane number. This is the lowest numbered lane
|
||||
in the lane group.
|
||||
- resets: Must contain one entry which controls the reset line for the
|
||||
master lane of the sub-node.
|
||||
See ../reset/reset.txt for details.
|
||||
|
||||
Sub-node optional properties:
|
||||
- cdns,num-lanes: Number of lanes in this group. From 1 to 4. The
|
||||
group is made up of consecutive lanes.
|
||||
- cdns,phy-type: Can be PHY_TYPE_PCIE or PHY_TYPE_USB3, depending on
|
||||
configuration of lanes.
|
||||
|
||||
Example:
|
||||
pcie_phy4: pcie-phy@fd240000 {
|
||||
compatible = "cdns,sierra-phy-t0";
|
||||
reg = <0x0 0xfd240000 0x0 0x40000>;
|
||||
resets = <&phyrst 0>, <&phyrst 1>;
|
||||
reset-names = "sierra_reset", "sierra_apb";
|
||||
clocks = <&phyclock>;
|
||||
clock-names = "phy_clk";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pcie0_phy0: pcie-phy@0 {
|
||||
reg = <0>;
|
||||
resets = <&phyrst 2>;
|
||||
cdns,num-lanes = <2>;
|
||||
#phy-cells = <0>;
|
||||
cdns,phy-type = <PHY_TYPE_PCIE>;
|
||||
};
|
||||
pcie0_phy1: pcie-phy@2 {
|
||||
reg = <2>;
|
||||
resets = <&phyrst 4>;
|
||||
cdns,num-lanes = <1>;
|
||||
#phy-cells = <0>;
|
||||
cdns,phy-type = <PHY_TYPE_PCIE>;
|
||||
};
|
152
Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
Normal file
152
Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
Normal file
@ -0,0 +1,152 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/phy-cadence-sierra.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Cadence Sierra PHY binding
|
||||
|
||||
description:
|
||||
This binding describes the Cadence Sierra PHY. Sierra PHY supports multilink
|
||||
multiprotocol combinations including protocols such as PCIe, USB etc.
|
||||
|
||||
maintainers:
|
||||
- Swapnil Jakhade <sjakhade@cadence.com>
|
||||
- Yuti Amonkar <yamonkar@cadence.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- cdns,sierra-phy-t0
|
||||
- ti,sierra-phy-t0
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Sierra PHY reset.
|
||||
- description: Sierra APB reset. This is optional.
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: sierra_reset
|
||||
- const: sierra_apb
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description:
|
||||
Offset of the Sierra PHY configuration registers.
|
||||
|
||||
reg-names:
|
||||
const: serdes
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cmn_refclk_dig_div
|
||||
- const: cmn_refclk1_dig_div
|
||||
|
||||
cdns,autoconf:
|
||||
type: boolean
|
||||
description:
|
||||
A boolean property whose presence indicates that the PHY registers will be
|
||||
configured by hardware. If not present, all sub-node optional properties
|
||||
must be provided.
|
||||
|
||||
patternProperties:
|
||||
'^phy@[0-9a-f]$':
|
||||
type: object
|
||||
description:
|
||||
Each group of PHY lanes with a single master lane should be represented as
|
||||
a sub-node. Note that the actual configuration of each lane is determined
|
||||
by hardware strapping, and must match the configuration specified here.
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
The master lane number. This is the lowest numbered lane in the lane group.
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
description:
|
||||
Contains list of resets, one per lane, to get all the link lanes out of reset.
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
cdns,phy-type:
|
||||
description:
|
||||
Specifies the type of PHY for which the group of PHY lanes is used.
|
||||
Refer include/dt-bindings/phy/phy.h. Constants from the header should be used.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [2, 4]
|
||||
|
||||
cdns,num-lanes:
|
||||
description:
|
||||
Number of lanes in this group. The group is made up of consecutive lanes.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 16
|
||||
|
||||
required:
|
||||
- reg
|
||||
- resets
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- reg
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
sierra-phy@fd240000 {
|
||||
compatible = "cdns,sierra-phy-t0";
|
||||
reg = <0x0 0xfd240000 0x0 0x40000>;
|
||||
resets = <&phyrst 0>, <&phyrst 1>;
|
||||
reset-names = "sierra_reset", "sierra_apb";
|
||||
clocks = <&cmn_refclk_dig_div>, <&cmn_refclk1_dig_div>;
|
||||
clock-names = "cmn_refclk_dig_div", "cmn_refclk1_dig_div";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pcie0_phy0: phy@0 {
|
||||
reg = <0>;
|
||||
resets = <&phyrst 2>;
|
||||
cdns,num-lanes = <2>;
|
||||
#phy-cells = <0>;
|
||||
cdns,phy-type = <PHY_TYPE_PCIE>;
|
||||
};
|
||||
pcie0_phy1: phy@2 {
|
||||
reg = <2>;
|
||||
resets = <&phyrst 4>;
|
||||
cdns,num-lanes = <1>;
|
||||
#phy-cells = <0>;
|
||||
cdns,phy-type = <PHY_TYPE_PCIE>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,73 +0,0 @@
|
||||
STMicroelectronics STM32 USB HS PHY controller
|
||||
|
||||
The STM32 USBPHYC block contains a dual port High Speed UTMI+ PHY and a UTMI
|
||||
switch. It controls PHY configuration and status, and the UTMI+ switch that
|
||||
selects either OTG or HOST controller for the second PHY port. It also sets
|
||||
PLL configuration.
|
||||
|
||||
USBPHYC
|
||||
|_ PLL
|
||||
|
|
||||
|_ PHY port#1 _________________ HOST controller
|
||||
| _ |
|
||||
| / 1|________________|
|
||||
|_ PHY port#2 ----| |________________
|
||||
| \_0| |
|
||||
|_ UTMI switch_______| OTG controller
|
||||
|
||||
|
||||
Phy provider node
|
||||
=================
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "st,stm32mp1-usbphyc"
|
||||
- reg: address and length of the usb phy control register set
|
||||
- clocks: phandle + clock specifier for the PLL phy clock
|
||||
- #address-cells: number of address cells for phys sub-nodes, must be <1>
|
||||
- #size-cells: number of size cells for phys sub-nodes, must be <0>
|
||||
|
||||
Optional properties:
|
||||
- assigned-clocks: phandle + clock specifier for the PLL phy clock
|
||||
- assigned-clock-parents: the PLL phy clock parent
|
||||
- resets: phandle + reset specifier
|
||||
|
||||
Required nodes: one sub-node per port the controller provides.
|
||||
|
||||
Phy sub-nodes
|
||||
==============
|
||||
|
||||
Required properties:
|
||||
- reg: phy port index
|
||||
- phy-supply: phandle to the regulator providing 3V3 power to the PHY,
|
||||
see phy-bindings.txt in the same directory.
|
||||
- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY
|
||||
- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY
|
||||
- #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY
|
||||
port#1 and must be <1> for PHY port#2, to select USB controller
|
||||
|
||||
|
||||
Example:
|
||||
usbphyc: usb-phy@5a006000 {
|
||||
compatible = "st,stm32mp1-usbphyc";
|
||||
reg = <0x5a006000 0x1000>;
|
||||
clocks = <&rcc_clk USBPHY_K>;
|
||||
resets = <&rcc_rst USBPHY_R>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usbphyc_port0: usb-phy@0 {
|
||||
reg = <0>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
vdda1v1-supply = <®11>;
|
||||
vdda1v8-supply = <®18>
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usbphyc_port1: usb-phy@1 {
|
||||
reg = <1>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
vdda1v1-supply = <®11>;
|
||||
vdda1v8-supply = <®18>
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
};
|
138
Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
Normal file
138
Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
Normal file
@ -0,0 +1,138 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/phy-stm32-usbphyc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 USB HS PHY controller binding
|
||||
|
||||
description:
|
||||
|
||||
The STM32 USBPHYC block contains a dual port High Speed UTMI+ PHY and a UTMI
|
||||
switch. It controls PHY configuration and status, and the UTMI+ switch that
|
||||
selects either OTG or HOST controller for the second PHY port. It also sets
|
||||
PLL configuration.
|
||||
|
||||
USBPHYC
|
||||
|_ PLL
|
||||
|
|
||||
|_ PHY port#1 _________________ HOST controller
|
||||
| __ |
|
||||
| / 1|________________|
|
||||
|_ PHY port#2 ----| |________________
|
||||
| \_0| |
|
||||
|_ UTMI switch_______| OTG controller
|
||||
|
||||
maintainers:
|
||||
- Amelie Delaunay <amelie.delaunay@st.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32mp1-usbphyc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
#Required child nodes:
|
||||
|
||||
patternProperties:
|
||||
"^usb-phy@[0|1]$":
|
||||
type: object
|
||||
description:
|
||||
Each port the controller provides must be represented as a sub-node.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: phy port index.
|
||||
maxItems: 1
|
||||
|
||||
phy-supply:
|
||||
description: regulator providing 3V3 power supply to the PHY.
|
||||
|
||||
vdda1v1-supply:
|
||||
description: regulator providing 1V1 power supply to the PLL block
|
||||
|
||||
vdda1v8-supply:
|
||||
description: regulator providing 1V8 power supply to the PLL block
|
||||
|
||||
"#phy-cells":
|
||||
enum: [ 0x0, 0x1 ]
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
reg:
|
||||
const: 0
|
||||
then:
|
||||
properties:
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
else:
|
||||
properties:
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description:
|
||||
The value is used to select UTMI switch output.
|
||||
0 for OTG controller and 1 for Host controller.
|
||||
|
||||
required:
|
||||
- reg
|
||||
- phy-supply
|
||||
- vdda1v1-supply
|
||||
- vdda1v8-supply
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- usb-phy@0
|
||||
- usb-phy@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <dt-bindings/reset/stm32mp1-resets.h>
|
||||
usbphyc: usbphyc@5a006000 {
|
||||
compatible = "st,stm32mp1-usbphyc";
|
||||
reg = <0x5a006000 0x1000>;
|
||||
clocks = <&rcc USBPHY_K>;
|
||||
resets = <&rcc USBPHY_R>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usbphyc_port0: usb-phy@0 {
|
||||
reg = <0>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
vdda1v1-supply = <®11>;
|
||||
vdda1v8-supply = <®18>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
usbphyc_port1: usb-phy@1 {
|
||||
reg = <1>;
|
||||
phy-supply = <&vdd_usb>;
|
||||
vdda1v1-supply = <®11>;
|
||||
vdda1v8-supply = <®18>;
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
};
|
||||
...
|
@ -31,6 +31,9 @@ properties:
|
||||
- qcom,sdm845-qmp-usb3-uni-phy
|
||||
- qcom,sm8150-qmp-ufs-phy
|
||||
- qcom,sm8250-qmp-ufs-phy
|
||||
- qcom,sm8250-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8250-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8250-qmp-modem-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -259,6 +262,9 @@ allOf:
|
||||
enum:
|
||||
- qcom,sdm845-qhp-pcie-phy
|
||||
- qcom,sdm845-qmp-pcie-phy
|
||||
- qcom,sm8250-qmp-gen3x1-pcie-phy
|
||||
- qcom,sm8250-qmp-gen3x2-pcie-phy
|
||||
- qcom,sm8250-qmp-modem-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -16,6 +16,11 @@ Optional properties:
|
||||
- drive-impedance-ohm: Specifies the drive impedance in Ohm.
|
||||
Possible values are 33, 40, 50, 66 and 100.
|
||||
If not set, the default value of 50 will be applied.
|
||||
- enable-strobe-pulldown: Enable internal pull-down for the strobe line.
|
||||
If not set, pull-down is not used.
|
||||
- output-tapdelay-select: Specifies the phyctrl_otapdlysec register.
|
||||
If not set, the register defaults to 0x4.
|
||||
Maximum value 0xf.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -47,6 +47,7 @@ Required properties:
|
||||
- "samsung,exynos4210-usb2-phy"
|
||||
- "samsung,exynos4x12-usb2-phy"
|
||||
- "samsung,exynos5250-usb2-phy"
|
||||
- "samsung,exynos5420-usb2-phy"
|
||||
- "samsung,s5pv210-usb2-phy"
|
||||
- reg : a list of registers used by phy driver
|
||||
- first and obligatory is the location of phy modules registers
|
||||
|
14
MAINTAINERS
14
MAINTAINERS
@ -11082,6 +11082,12 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-mt7621.txt
|
||||
F: drivers/i2c/busses/i2c-mt7621.c
|
||||
|
||||
MEDIATEK MT7621 PHY PCI DRIVER
|
||||
M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml
|
||||
F: drivers/phy/ralink/phy-mt7621-pci.c
|
||||
|
||||
MEDIATEK NAND CONTROLLER DRIVER
|
||||
L: linux-mtd@lists.infradead.org
|
||||
S: Orphan
|
||||
@ -14521,6 +14527,14 @@ F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
|
||||
F: drivers/mailbox/qcom-ipcc.c
|
||||
F: include/dt-bindings/mailbox/qcom-ipcc.h
|
||||
|
||||
QUALCOMM IPQ4019 USB PHY DRIVER
|
||||
M: Robert Marko <robert.marko@sartura.hr>
|
||||
M: Luka Perkov <luka.perkov@sartura.hr>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/phy/qcom-usb-ipq4019-phy.yaml
|
||||
F: drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
|
||||
|
||||
QUALCOMM IPQ4019 VQMMC REGULATOR DRIVER
|
||||
M: Robert Marko <robert.marko@sartura.hr>
|
||||
M: Luka Perkov <luka.perkov@sartura.hr>
|
||||
|
@ -66,6 +66,7 @@ source "drivers/phy/broadcom/Kconfig"
|
||||
source "drivers/phy/cadence/Kconfig"
|
||||
source "drivers/phy/freescale/Kconfig"
|
||||
source "drivers/phy/hisilicon/Kconfig"
|
||||
source "drivers/phy/ingenic/Kconfig"
|
||||
source "drivers/phy/lantiq/Kconfig"
|
||||
source "drivers/phy/marvell/Kconfig"
|
||||
source "drivers/phy/mediatek/Kconfig"
|
||||
|
@ -15,6 +15,7 @@ obj-y += allwinner/ \
|
||||
cadence/ \
|
||||
freescale/ \
|
||||
hisilicon/ \
|
||||
ingenic/ \
|
||||
intel/ \
|
||||
lantiq/ \
|
||||
marvell/ \
|
||||
|
@ -686,7 +686,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
int i, ret;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
@ -700,8 +699,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
|
||||
if (!data->cfg)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl");
|
||||
data->base = devm_ioremap_resource(dev, res);
|
||||
data->base = devm_platform_ioremap_resource_byname(pdev, "phy_ctrl");
|
||||
if (IS_ERR(data->base))
|
||||
return PTR_ERR(data->base);
|
||||
|
||||
@ -796,9 +794,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
|
||||
|
||||
if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */
|
||||
snprintf(name, sizeof(name), "pmu%d", i);
|
||||
res = platform_get_resource_byname(pdev,
|
||||
IORESOURCE_MEM, name);
|
||||
phy->pmu = devm_ioremap_resource(dev, res);
|
||||
phy->pmu = devm_platform_ioremap_resource_byname(pdev, name);
|
||||
if (IS_ERR(phy->pmu))
|
||||
return PTR_ERR(phy->pmu);
|
||||
}
|
||||
@ -969,7 +965,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
|
||||
.disc_thresh = 3,
|
||||
.phyctl_offset = REG_PHYCTL_A33,
|
||||
.dedicated_clocks = true,
|
||||
.enable_pmu_unk1 = true,
|
||||
.phy0_dual_route = true,
|
||||
.missing_phys = BIT(1) | BIT(2),
|
||||
};
|
||||
|
@ -134,7 +134,6 @@ static int sun50i_usb3_phy_probe(struct platform_device *pdev)
|
||||
struct sun50i_usb3_phy *phy;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
|
||||
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
|
||||
if (!phy)
|
||||
@ -153,8 +152,7 @@ static int sun50i_usb3_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(phy->reset);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->regs = devm_ioremap_resource(dev, res);
|
||||
phy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->regs))
|
||||
return PTR_ERR(phy->regs);
|
||||
|
||||
|
@ -253,15 +253,13 @@ static int sun6i_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct sun6i_dphy *dphy;
|
||||
struct resource *res;
|
||||
void __iomem *regs;
|
||||
|
||||
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
if (!dphy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs)) {
|
||||
dev_err(&pdev->dev, "Couldn't map the DPHY encoder registers\n");
|
||||
return PTR_ERR(regs);
|
||||
|
@ -117,7 +117,6 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
|
||||
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
|
||||
if (!phy)
|
||||
@ -156,8 +155,7 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->pmu = devm_ioremap_resource(dev, res);
|
||||
phy->pmu = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->pmu))
|
||||
return PTR_ERR(phy->pmu);
|
||||
|
||||
|
@ -66,7 +66,20 @@ config PHY_MESON_AXG_MIPI_PCIE_ANALOG
|
||||
depends on OF && (ARCH_MESON || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
select GENERIC_PHY_MIPI_DPHY
|
||||
help
|
||||
Enable this to support the Meson MIPI + PCIE analog PHY
|
||||
found in Meson AXG SoCs.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_MESON_AXG_MIPI_DPHY
|
||||
tristate "Meson AXG MIPI DPHY driver"
|
||||
default ARCH_MESON
|
||||
depends on OF && (ARCH_MESON || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
select GENERIC_PHY_MIPI_DPHY
|
||||
help
|
||||
Enable this to support the Meson MIPI DPHY found in Meson AXG
|
||||
SoCs.
|
||||
If unsure, say N.
|
||||
|
@ -5,3 +5,4 @@ obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o
|
||||
obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o
|
||||
obj-$(CONFIG_PHY_MESON_AXG_PCIE) += phy-meson-axg-pcie.o
|
||||
obj-$(CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG) += phy-meson-axg-mipi-pcie-analog.o
|
||||
obj-$(CONFIG_PHY_MESON_AXG_MIPI_DPHY) += phy-meson-axg-mipi-dphy.o
|
||||
|
413
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
Normal file
413
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
Normal file
@ -0,0 +1,413 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Meson AXG MIPI DPHY driver
|
||||
*
|
||||
* Copyright (C) 2018 Amlogic, Inc. All rights reserved
|
||||
* Copyright (C) 2020 BayLibre, SAS
|
||||
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/* [31] soft reset for the phy.
|
||||
* 1: reset. 0: dessert the reset.
|
||||
* [30] clock lane soft reset.
|
||||
* [29] data byte lane 3 soft reset.
|
||||
* [28] data byte lane 2 soft reset.
|
||||
* [27] data byte lane 1 soft reset.
|
||||
* [26] data byte lane 0 soft reset.
|
||||
* [25] mipi dsi pll clock selection.
|
||||
* 1: clock from fixed 850Mhz clock source. 0: from VID2 PLL.
|
||||
* [12] mipi HSbyteclk enable.
|
||||
* [11] mipi divider clk selection.
|
||||
* 1: select the mipi DDRCLKHS from clock divider.
|
||||
* 0: from PLL clock.
|
||||
* [10] mipi clock divider control.
|
||||
* 1: /4. 0: /2.
|
||||
* [9] mipi divider output enable.
|
||||
* [8] mipi divider counter enable.
|
||||
* [7] PLL clock enable.
|
||||
* [5] LPDT data endian.
|
||||
* 1 = transfer the high bit first. 0 : transfer the low bit first.
|
||||
* [4] HS data endian.
|
||||
* [3] force data byte lane in stop mode.
|
||||
* [2] force data byte lane 0 in receiver mode.
|
||||
* [1] write 1 to sync the txclkesc input. the internal logic have to
|
||||
* use txclkesc to decide Txvalid and Txready.
|
||||
* [0] enalbe the MIPI DPHY TxDDRClk.
|
||||
*/
|
||||
#define MIPI_DSI_PHY_CTRL 0x0
|
||||
|
||||
/* [31] clk lane tx_hs_en control selection.
|
||||
* 1: from register. 0: use clk lane state machine.
|
||||
* [30] register bit for clock lane tx_hs_en.
|
||||
* [29] clk lane tx_lp_en contrl selection.
|
||||
* 1: from register. 0: from clk lane state machine.
|
||||
* [28] register bit for clock lane tx_lp_en.
|
||||
* [27] chan0 tx_hs_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [26] register bit for chan0 tx_hs_en.
|
||||
* [25] chan0 tx_lp_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [24] register bit from chan0 tx_lp_en.
|
||||
* [23] chan0 rx_lp_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [22] register bit from chan0 rx_lp_en.
|
||||
* [21] chan0 contention detection enable control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [20] register bit from chan0 contention dectection enable.
|
||||
* [19] chan1 tx_hs_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [18] register bit for chan1 tx_hs_en.
|
||||
* [17] chan1 tx_lp_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [16] register bit from chan1 tx_lp_en.
|
||||
* [15] chan2 tx_hs_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [14] register bit for chan2 tx_hs_en.
|
||||
* [13] chan2 tx_lp_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [12] register bit from chan2 tx_lp_en.
|
||||
* [11] chan3 tx_hs_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [10] register bit for chan3 tx_hs_en.
|
||||
* [9] chan3 tx_lp_en control selection.
|
||||
* 1: from register. 0: from chan0 state machine.
|
||||
* [8] register bit from chan3 tx_lp_en.
|
||||
* [4] clk chan power down. this bit is also used as the power down
|
||||
* of the whole MIPI_DSI_PHY.
|
||||
* [3] chan3 power down.
|
||||
* [2] chan2 power down.
|
||||
* [1] chan1 power down.
|
||||
* [0] chan0 power down.
|
||||
*/
|
||||
#define MIPI_DSI_CHAN_CTRL 0x4
|
||||
|
||||
/* [24] rx turn watch dog triggered.
|
||||
* [23] rx esc watchdog triggered.
|
||||
* [22] mbias ready.
|
||||
* [21] txclkesc synced and ready.
|
||||
* [20:17] clk lane state. {mbias_ready, tx_stop, tx_ulps, tx_hs_active}
|
||||
* [16:13] chan3 state{0, tx_stop, tx_ulps, tx_hs_active}
|
||||
* [12:9] chan2 state.{0, tx_stop, tx_ulps, tx_hs_active}
|
||||
* [8:5] chan1 state. {0, tx_stop, tx_ulps, tx_hs_active}
|
||||
* [4:0] chan0 state. {TX_STOP, tx_ULPS, hs_active, direction, rxulpsesc}
|
||||
*/
|
||||
#define MIPI_DSI_CHAN_STS 0x8
|
||||
|
||||
/* [31:24] TCLK_PREPARE.
|
||||
* [23:16] TCLK_ZERO.
|
||||
* [15:8] TCLK_POST.
|
||||
* [7:0] TCLK_TRAIL.
|
||||
*/
|
||||
#define MIPI_DSI_CLK_TIM 0xc
|
||||
|
||||
/* [31:24] THS_PREPARE.
|
||||
* [23:16] THS_ZERO.
|
||||
* [15:8] THS_TRAIL.
|
||||
* [7:0] THS_EXIT.
|
||||
*/
|
||||
#define MIPI_DSI_HS_TIM 0x10
|
||||
|
||||
/* [31:24] tTA_GET.
|
||||
* [23:16] tTA_GO.
|
||||
* [15:8] tTA_SURE.
|
||||
* [7:0] tLPX.
|
||||
*/
|
||||
#define MIPI_DSI_LP_TIM 0x14
|
||||
|
||||
/* wait time to MIPI DIS analog ready. */
|
||||
#define MIPI_DSI_ANA_UP_TIM 0x18
|
||||
|
||||
/* TINIT. */
|
||||
#define MIPI_DSI_INIT_TIM 0x1c
|
||||
|
||||
/* TWAKEUP. */
|
||||
#define MIPI_DSI_WAKEUP_TIM 0x20
|
||||
|
||||
/* when in RxULPS check state, after the the logic enable the analog,
|
||||
* how long we should wait to check the lP state .
|
||||
*/
|
||||
#define MIPI_DSI_LPOK_TIM 0x24
|
||||
|
||||
/* Watchdog for RX low power state no finished. */
|
||||
#define MIPI_DSI_LP_WCHDOG 0x28
|
||||
|
||||
/* tMBIAS, after send power up signals to analog,
|
||||
* how long we should wait for analog powered up.
|
||||
*/
|
||||
#define MIPI_DSI_ANA_CTRL 0x2c
|
||||
|
||||
/* [31:8] reserved for future.
|
||||
* [7:0] tCLK_PRE.
|
||||
*/
|
||||
#define MIPI_DSI_CLK_TIM1 0x30
|
||||
|
||||
/* watchdog for turn around waiting time. */
|
||||
#define MIPI_DSI_TURN_WCHDOG 0x34
|
||||
|
||||
/* When in RxULPS state, how frequency we should to check
|
||||
* if the TX side out of ULPS state.
|
||||
*/
|
||||
#define MIPI_DSI_ULPS_CHECK 0x38
|
||||
#define MIPI_DSI_TEST_CTRL0 0x3c
|
||||
#define MIPI_DSI_TEST_CTRL1 0x40
|
||||
|
||||
struct phy_meson_axg_mipi_dphy_priv {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
struct reset_control *reset;
|
||||
struct phy *analog;
|
||||
struct phy_configure_opts_mipi_dphy config;
|
||||
};
|
||||
|
||||
static const struct regmap_config phy_meson_axg_mipi_dphy_regmap_conf = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = MIPI_DSI_TEST_CTRL1,
|
||||
};
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_init(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = phy_init(priv->analog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_reset(priv->reset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_configure(struct phy *phy,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = phy_configure(priv->analog, opts);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(&priv->config, opts, sizeof(priv->config));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
unsigned long temp;
|
||||
|
||||
ret = phy_power_on(priv->analog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* enable phy clock */
|
||||
regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL, 0x1);
|
||||
regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL,
|
||||
BIT(0) | /* enable the DSI PLL clock . */
|
||||
BIT(7) | /* enable pll clock which connected to DDR clock path */
|
||||
BIT(8)); /* enable the clock divider counter */
|
||||
|
||||
/* enable the divider clock out */
|
||||
regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(9), BIT(9));
|
||||
|
||||
/* enable the byte clock generation. */
|
||||
regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(12), BIT(12));
|
||||
regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31), BIT(31));
|
||||
regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31), 0);
|
||||
|
||||
/* Calculate lanebyteclk period in ps */
|
||||
temp = (1000000 * 100) / (priv->config.hs_clk_rate / 1000);
|
||||
temp = temp * 8 * 10;
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_CLK_TIM,
|
||||
DIV_ROUND_UP(priv->config.clk_trail, temp) |
|
||||
(DIV_ROUND_UP(priv->config.clk_post +
|
||||
priv->config.hs_trail, temp) << 8) |
|
||||
(DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
|
||||
(DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
|
||||
regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
|
||||
DIV_ROUND_UP(priv->config.clk_pre, temp));
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
|
||||
DIV_ROUND_UP(priv->config.hs_exit, temp) |
|
||||
(DIV_ROUND_UP(priv->config.hs_trail, temp) << 8) |
|
||||
(DIV_ROUND_UP(priv->config.hs_zero, temp) << 16) |
|
||||
(DIV_ROUND_UP(priv->config.hs_prepare, temp) << 24));
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_LP_TIM,
|
||||
DIV_ROUND_UP(priv->config.lpx, temp) |
|
||||
(DIV_ROUND_UP(priv->config.ta_sure, temp) << 8) |
|
||||
(DIV_ROUND_UP(priv->config.ta_go, temp) << 16) |
|
||||
(DIV_ROUND_UP(priv->config.ta_get, temp) << 24));
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_ANA_UP_TIM, 0x0100);
|
||||
regmap_write(priv->regmap, MIPI_DSI_INIT_TIM,
|
||||
DIV_ROUND_UP(priv->config.init * NSEC_PER_MSEC, temp));
|
||||
regmap_write(priv->regmap, MIPI_DSI_WAKEUP_TIM,
|
||||
DIV_ROUND_UP(priv->config.wakeup * NSEC_PER_MSEC, temp));
|
||||
regmap_write(priv->regmap, MIPI_DSI_LPOK_TIM, 0x7C);
|
||||
regmap_write(priv->regmap, MIPI_DSI_ULPS_CHECK, 0x927C);
|
||||
regmap_write(priv->regmap, MIPI_DSI_LP_WCHDOG, 0x1000);
|
||||
regmap_write(priv->regmap, MIPI_DSI_TURN_WCHDOG, 0x1000);
|
||||
|
||||
/* Powerup the analog circuit */
|
||||
switch (priv->config.lanes) {
|
||||
case 1:
|
||||
regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xe);
|
||||
break;
|
||||
case 2:
|
||||
regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xc);
|
||||
break;
|
||||
case 3:
|
||||
regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0x8);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Trigger a sync active for esc_clk */
|
||||
regmap_update_bits(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(1), BIT(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_power_off(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_CHAN_CTRL, 0xf);
|
||||
regmap_write(priv->regmap, MIPI_DSI_PHY_CTRL, BIT(31));
|
||||
|
||||
phy_power_off(priv->analog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_exit(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = phy_exit(priv->analog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return reset_control_reset(priv->reset);
|
||||
}
|
||||
|
||||
static const struct phy_ops phy_meson_axg_mipi_dphy_ops = {
|
||||
.configure = phy_meson_axg_mipi_dphy_configure,
|
||||
.init = phy_meson_axg_mipi_dphy_init,
|
||||
.exit = phy_meson_axg_mipi_dphy_exit,
|
||||
.power_on = phy_meson_axg_mipi_dphy_power_on,
|
||||
.power_off = phy_meson_axg_mipi_dphy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int phy_meson_axg_mipi_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct phy_meson_axg_mipi_dphy_priv *priv;
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
priv->regmap = devm_regmap_init_mmio(dev, base,
|
||||
&phy_meson_axg_mipi_dphy_regmap_conf);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
priv->clk = devm_clk_get(dev, "pclk");
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
priv->reset = devm_reset_control_get(dev, "phy");
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
priv->analog = devm_phy_get(dev, "analog");
|
||||
if (IS_ERR(priv->analog))
|
||||
return PTR_ERR(priv->analog);
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(priv->reset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &phy_meson_axg_mipi_dphy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
ret = PTR_ERR(phy);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, priv);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id phy_meson_axg_mipi_dphy_of_match[] = {
|
||||
{ .compatible = "amlogic,axg-mipi-dphy", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, phy_meson_axg_mipi_dphy_of_match);
|
||||
|
||||
static struct platform_driver phy_meson_axg_mipi_dphy_driver = {
|
||||
.probe = phy_meson_axg_mipi_dphy_probe,
|
||||
.driver = {
|
||||
.name = "phy-meson-axg-mipi-dphy",
|
||||
.of_match_table = phy_meson_axg_mipi_dphy_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(phy_meson_axg_mipi_dphy_driver);
|
||||
|
||||
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
|
||||
MODULE_DESCRIPTION("Meson AXG MIPI DPHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -4,9 +4,13 @@
|
||||
*
|
||||
* Copyright (C) 2019 Remi Pommarel <repk@triplefau.lt>
|
||||
*/
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
@ -14,10 +18,10 @@
|
||||
#define HHI_MIPI_CNTL0_COMMON_BLOCK GENMASK(31, 28)
|
||||
#define HHI_MIPI_CNTL0_ENABLE BIT(29)
|
||||
#define HHI_MIPI_CNTL0_BANDGAP BIT(26)
|
||||
#define HHI_MIPI_CNTL0_DECODE_TO_RTERM GENMASK(15, 12)
|
||||
#define HHI_MIPI_CNTL0_OUTPUT_EN BIT(3)
|
||||
#define HHI_MIPI_CNTL0_DIF_REF_CTL1 GENMASK(25, 16)
|
||||
#define HHI_MIPI_CNTL0_DIF_REF_CTL0 GENMASK(15, 0)
|
||||
|
||||
#define HHI_MIPI_CNTL1 0x01
|
||||
#define HHI_MIPI_CNTL1 0x04
|
||||
#define HHI_MIPI_CNTL1_CH0_CML_PDR_EN BIT(12)
|
||||
#define HHI_MIPI_CNTL1_LP_ABILITY GENMASK(5, 4)
|
||||
#define HHI_MIPI_CNTL1_LP_RESISTER BIT(3)
|
||||
@ -25,41 +29,145 @@
|
||||
#define HHI_MIPI_CNTL1_INPUT_SEL BIT(1)
|
||||
#define HHI_MIPI_CNTL1_PRBS7_EN BIT(0)
|
||||
|
||||
#define HHI_MIPI_CNTL2 0x02
|
||||
#define HHI_MIPI_CNTL2 0x08
|
||||
#define HHI_MIPI_CNTL2_CH_PU GENMASK(31, 25)
|
||||
#define HHI_MIPI_CNTL2_CH_CTL GENMASK(24, 19)
|
||||
#define HHI_MIPI_CNTL2_CH0_DIGDR_EN BIT(18)
|
||||
#define HHI_MIPI_CNTL2_CH_DIGDR_EN BIT(17)
|
||||
#define HHI_MIPI_CNTL2_LPULPS_EN BIT(16)
|
||||
#define HHI_MIPI_CNTL2_CH_EN(n) BIT(15 - (n))
|
||||
#define HHI_MIPI_CNTL2_CH_EN GENMASK(15, 11)
|
||||
#define HHI_MIPI_CNTL2_CH0_LP_CTL GENMASK(10, 1)
|
||||
|
||||
#define DSI_LANE_0 BIT(4)
|
||||
#define DSI_LANE_1 BIT(3)
|
||||
#define DSI_LANE_CLK BIT(2)
|
||||
#define DSI_LANE_2 BIT(1)
|
||||
#define DSI_LANE_3 BIT(0)
|
||||
|
||||
struct phy_axg_mipi_pcie_analog_priv {
|
||||
struct phy *phy;
|
||||
unsigned int mode;
|
||||
struct regmap *regmap;
|
||||
bool dsi_configured;
|
||||
bool dsi_enabled;
|
||||
bool powered;
|
||||
struct phy_configure_opts_mipi_dphy config;
|
||||
};
|
||||
|
||||
static const struct regmap_config phy_axg_mipi_pcie_analog_regmap_conf = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = HHI_MIPI_CNTL2,
|
||||
};
|
||||
static void phy_bandgap_enable(struct phy_axg_mipi_pcie_analog_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_BANDGAP, HHI_MIPI_CNTL0_BANDGAP);
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_ENABLE, HHI_MIPI_CNTL0_ENABLE);
|
||||
}
|
||||
|
||||
static void phy_bandgap_disable(struct phy_axg_mipi_pcie_analog_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_BANDGAP, 0);
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_ENABLE, 0);
|
||||
}
|
||||
|
||||
static void phy_dsi_analog_enable(struct phy_axg_mipi_pcie_analog_priv *priv)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_DIF_REF_CTL1,
|
||||
FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0x1b8));
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
BIT(31), BIT(31));
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_DIF_REF_CTL0,
|
||||
FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL0, 0x8));
|
||||
|
||||
regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x001e);
|
||||
|
||||
regmap_write(priv->regmap, HHI_MIPI_CNTL2,
|
||||
(0x26e0 << 16) | (0x459 << 0));
|
||||
|
||||
reg = DSI_LANE_CLK;
|
||||
switch (priv->config.lanes) {
|
||||
case 4:
|
||||
reg |= DSI_LANE_3;
|
||||
fallthrough;
|
||||
case 3:
|
||||
reg |= DSI_LANE_2;
|
||||
fallthrough;
|
||||
case 2:
|
||||
reg |= DSI_LANE_1;
|
||||
fallthrough;
|
||||
case 1:
|
||||
reg |= DSI_LANE_0;
|
||||
break;
|
||||
default:
|
||||
reg = 0;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL2,
|
||||
HHI_MIPI_CNTL2_CH_EN,
|
||||
FIELD_PREP(HHI_MIPI_CNTL2_CH_EN, reg));
|
||||
|
||||
priv->dsi_enabled = true;
|
||||
}
|
||||
|
||||
static void phy_dsi_analog_disable(struct phy_axg_mipi_pcie_analog_priv *priv)
|
||||
{
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_DIF_REF_CTL1,
|
||||
FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0));
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, BIT(31), 0);
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_DIF_REF_CTL1, 0);
|
||||
|
||||
regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x6);
|
||||
|
||||
regmap_write(priv->regmap, HHI_MIPI_CNTL2, 0x00200000);
|
||||
|
||||
priv->dsi_enabled = false;
|
||||
}
|
||||
|
||||
static int phy_axg_mipi_pcie_analog_configure(struct phy *phy,
|
||||
union phy_configure_opts *opts)
|
||||
{
|
||||
struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(&priv->config, opts, sizeof(priv->config));
|
||||
|
||||
priv->dsi_configured = true;
|
||||
|
||||
/* If PHY was already powered on, setup the DSI analog part */
|
||||
if (priv->powered) {
|
||||
/* If reconfiguring, disable & reconfigure */
|
||||
if (priv->dsi_enabled)
|
||||
phy_dsi_analog_disable(priv);
|
||||
|
||||
usleep_range(100, 200);
|
||||
|
||||
phy_dsi_analog_enable(priv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_axg_mipi_pcie_analog_power_on(struct phy *phy)
|
||||
{
|
||||
struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
/* MIPI not supported yet */
|
||||
if (priv->mode != PHY_TYPE_PCIE)
|
||||
return -EINVAL;
|
||||
phy_bandgap_enable(priv);
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_BANDGAP, HHI_MIPI_CNTL0_BANDGAP);
|
||||
if (priv->dsi_configured)
|
||||
phy_dsi_analog_enable(priv);
|
||||
|
||||
priv->powered = true;
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_ENABLE, HHI_MIPI_CNTL0_ENABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -67,58 +175,23 @@ static int phy_axg_mipi_pcie_analog_power_off(struct phy *phy)
|
||||
{
|
||||
struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
/* MIPI not supported yet */
|
||||
if (priv->mode != PHY_TYPE_PCIE)
|
||||
return -EINVAL;
|
||||
phy_bandgap_disable(priv);
|
||||
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_BANDGAP, 0);
|
||||
regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
|
||||
HHI_MIPI_CNTL0_ENABLE, 0);
|
||||
return 0;
|
||||
}
|
||||
if (priv->dsi_enabled)
|
||||
phy_dsi_analog_disable(priv);
|
||||
|
||||
static int phy_axg_mipi_pcie_analog_init(struct phy *phy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
priv->powered = false;
|
||||
|
||||
static int phy_axg_mipi_pcie_analog_exit(struct phy *phy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops phy_axg_mipi_pcie_analog_ops = {
|
||||
.init = phy_axg_mipi_pcie_analog_init,
|
||||
.exit = phy_axg_mipi_pcie_analog_exit,
|
||||
.configure = phy_axg_mipi_pcie_analog_configure,
|
||||
.power_on = phy_axg_mipi_pcie_analog_power_on,
|
||||
.power_off = phy_axg_mipi_pcie_analog_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct phy *phy_axg_mipi_pcie_analog_xlate(struct device *dev,
|
||||
struct of_phandle_args *args)
|
||||
{
|
||||
struct phy_axg_mipi_pcie_analog_priv *priv = dev_get_drvdata(dev);
|
||||
unsigned int mode;
|
||||
|
||||
if (args->args_count != 1) {
|
||||
dev_err(dev, "invalid number of arguments\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
mode = args->args[0];
|
||||
|
||||
/* MIPI mode is not supported yet */
|
||||
if (mode != PHY_TYPE_PCIE) {
|
||||
dev_err(dev, "invalid phy mode select argument\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
priv->mode = mode;
|
||||
return priv->phy;
|
||||
}
|
||||
|
||||
static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy;
|
||||
@ -126,27 +199,20 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
|
||||
struct phy_axg_mipi_pcie_analog_priv *priv;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct regmap *map;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base)) {
|
||||
dev_err(dev, "failed to get regmap base\n");
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
map = devm_regmap_init_mmio(dev, base,
|
||||
&phy_axg_mipi_pcie_analog_regmap_conf);
|
||||
/* Get the hhi system controller node */
|
||||
map = syscon_node_to_regmap(of_get_parent(dev->of_node));
|
||||
if (IS_ERR(map)) {
|
||||
dev_err(dev, "failed to get HHI regmap\n");
|
||||
dev_err(dev,
|
||||
"failed to get HHI regmap\n");
|
||||
return PTR_ERR(map);
|
||||
}
|
||||
|
||||
priv->regmap = map;
|
||||
|
||||
priv->phy = devm_phy_create(dev, np, &phy_axg_mipi_pcie_analog_ops);
|
||||
@ -160,8 +226,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
|
||||
phy_set_drvdata(priv->phy, priv);
|
||||
dev_set_drvdata(dev, priv);
|
||||
|
||||
phy = devm_of_phy_provider_register(dev,
|
||||
phy_axg_mipi_pcie_analog_xlate);
|
||||
phy = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy);
|
||||
}
|
||||
|
@ -129,7 +129,6 @@ static int phy_axg_pcie_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_axg_pcie_priv *priv;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
@ -145,8 +144,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
@ -155,7 +153,7 @@ static int phy_axg_pcie_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
priv->reset = devm_reset_control_array_get(dev, false, false);
|
||||
priv->reset = devm_reset_control_array_get_exclusive(dev);
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
|
@ -292,7 +292,6 @@ static int phy_meson_g12a_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct phy_meson_g12a_usb2_priv *priv;
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
@ -305,8 +304,7 @@ static int phy_meson_g12a_usb2_probe(struct platform_device *pdev)
|
||||
priv->dev = dev;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -386,7 +386,6 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct phy_g12a_usb3_pcie_priv *priv;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
@ -395,8 +394,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
@ -418,7 +416,7 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_disable_clk_ref;
|
||||
|
||||
priv->reset = devm_reset_control_array_get(dev, false, false);
|
||||
priv->reset = devm_reset_control_array_get_exclusive(dev);
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
|
@ -158,7 +158,8 @@ static int phy_meson_gxl_usb2_set_mode(struct phy *phy,
|
||||
U2P_R0_DM_PULLDOWN);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
|
||||
U2P_R0_DP_PULLDOWN);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
|
||||
U2P_R0_ID_PULLUP);
|
||||
break;
|
||||
|
||||
case PHY_MODE_USB_DEVICE:
|
||||
@ -230,7 +231,6 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct phy_meson_gxl_usb2_priv *priv;
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
@ -242,8 +242,7 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -126,7 +126,6 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
|
||||
struct device_node *node = dev->of_node, *child;
|
||||
struct cygnus_pcie_phy_core *core;
|
||||
struct phy_provider *provider;
|
||||
struct resource *res;
|
||||
unsigned cnt = 0;
|
||||
int ret;
|
||||
|
||||
@ -141,8 +140,7 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev)
|
||||
|
||||
core->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
core->base = devm_ioremap_resource(dev, res);
|
||||
core->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(core->base))
|
||||
return PTR_ERR(core->base);
|
||||
|
||||
|
@ -94,7 +94,6 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct bcm_kona_usb *phy;
|
||||
struct resource *res;
|
||||
struct phy *gphy;
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
@ -102,8 +101,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
phy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->regs))
|
||||
return PTR_ERR(phy->regs);
|
||||
|
||||
|
@ -83,7 +83,6 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct bcm_ns_usb2 *usb2;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
usb2 = devm_kzalloc(&pdev->dev, sizeof(*usb2), GFP_KERNEL);
|
||||
@ -91,8 +90,7 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
usb2->dev = dev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmu");
|
||||
usb2->dmu = devm_ioremap_resource(dev, res);
|
||||
usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
|
||||
if (IS_ERR(usb2->dmu)) {
|
||||
dev_err(dev, "Failed to map DMU regs\n");
|
||||
return PTR_ERR(usb2->dmu);
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000 /* usecs */
|
||||
|
||||
#define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f
|
||||
#define BCM_NS_USB3_PHY_PLL30_BLOCK 0x8000
|
||||
#define BCM_NS_USB3_PHY_TX_PMD_BLOCK 0x8040
|
||||
@ -51,11 +49,8 @@ struct bcm_ns_usb3 {
|
||||
struct device *dev;
|
||||
enum bcm_ns_family family;
|
||||
void __iomem *dmp;
|
||||
void __iomem *ccb_mii;
|
||||
struct mdio_device *mdiodev;
|
||||
struct phy *phy;
|
||||
|
||||
int (*phy_write)(struct bcm_ns_usb3 *usb3, u16 reg, u16 value);
|
||||
};
|
||||
|
||||
static const struct of_device_id bcm_ns_usb3_id_table[] = {
|
||||
@ -69,13 +64,9 @@ static const struct of_device_id bcm_ns_usb3_id_table[] = {
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
|
||||
|
||||
static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
return usb3->phy_write(usb3, reg, value);
|
||||
}
|
||||
u16 value);
|
||||
|
||||
static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
@ -187,8 +178,8 @@ static const struct phy_ops ops = {
|
||||
* MDIO driver code
|
||||
**************************************************/
|
||||
|
||||
static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
struct mdio_device *mdiodev = usb3->mdiodev;
|
||||
|
||||
@ -229,8 +220,6 @@ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
|
||||
return PTR_ERR(usb3->dmp);
|
||||
}
|
||||
|
||||
usb3->phy_write = bcm_ns_usb3_mdiodev_phy_write;
|
||||
|
||||
usb3->phy = devm_phy_create(dev, NULL, &ops);
|
||||
if (IS_ERR(usb3->phy)) {
|
||||
dev_err(dev, "Failed to create PHY\n");
|
||||
@ -254,145 +243,7 @@ static struct mdio_driver bcm_ns_usb3_mdio_driver = {
|
||||
.probe = bcm_ns_usb3_mdio_probe,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* Platform driver code
|
||||
**************************************************/
|
||||
|
||||
static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
|
||||
u32 mask, u32 value, int usec)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = readl_poll_timeout_atomic(addr, val, ((val & mask) == value),
|
||||
10, usec);
|
||||
if (ret)
|
||||
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
|
||||
0x0100, 0x0000,
|
||||
BCM_NS_USB3_MII_MNG_TIMEOUT_US);
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
int err;
|
||||
|
||||
err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
if (err < 0) {
|
||||
dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* TODO: Use a proper MDIO bus layer */
|
||||
tmp |= 0x58020000; /* Magic value for MDIO PHY write */
|
||||
tmp |= reg << 18;
|
||||
tmp |= value;
|
||||
writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
|
||||
|
||||
return bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct of_device_id *of_id;
|
||||
struct bcm_ns_usb3 *usb3;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
|
||||
if (!usb3)
|
||||
return -ENOMEM;
|
||||
|
||||
usb3->dev = dev;
|
||||
|
||||
of_id = of_match_device(bcm_ns_usb3_id_table, dev);
|
||||
if (!of_id)
|
||||
return -EINVAL;
|
||||
usb3->family = (enum bcm_ns_family)of_id->data;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmp");
|
||||
usb3->dmp = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(usb3->dmp)) {
|
||||
dev_err(dev, "Failed to map DMP regs\n");
|
||||
return PTR_ERR(usb3->dmp);
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ccb-mii");
|
||||
usb3->ccb_mii = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(usb3->ccb_mii)) {
|
||||
dev_err(dev, "Failed to map ChipCommon B MII regs\n");
|
||||
return PTR_ERR(usb3->ccb_mii);
|
||||
}
|
||||
|
||||
/* Enable MDIO. Setting MDCDIV as 26 */
|
||||
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
|
||||
|
||||
/* Wait for MDIO? */
|
||||
udelay(2);
|
||||
|
||||
usb3->phy_write = bcm_ns_usb3_platform_phy_write;
|
||||
|
||||
usb3->phy = devm_phy_create(dev, NULL, &ops);
|
||||
if (IS_ERR(usb3->phy)) {
|
||||
dev_err(dev, "Failed to create PHY\n");
|
||||
return PTR_ERR(usb3->phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(usb3->phy, usb3);
|
||||
platform_set_drvdata(pdev, usb3);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (!IS_ERR(phy_provider))
|
||||
dev_info(dev, "Registered Broadcom Northstar USB 3.0 PHY driver\n");
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static struct platform_driver bcm_ns_usb3_driver = {
|
||||
.probe = bcm_ns_usb3_probe,
|
||||
.driver = {
|
||||
.name = "bcm_ns_usb3",
|
||||
.of_match_table = bcm_ns_usb3_id_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bcm_ns_usb3_module_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* For backward compatibility we register as MDIO and platform driver.
|
||||
* After getting MDIO binding commonly used (e.g. switching all DT files
|
||||
* to use it) we should deprecate the old binding and eventually drop
|
||||
* support for it.
|
||||
*/
|
||||
|
||||
err = mdio_driver_register(&bcm_ns_usb3_mdio_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = platform_driver_register(&bcm_ns_usb3_driver);
|
||||
if (err)
|
||||
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
|
||||
|
||||
return err;
|
||||
}
|
||||
module_init(bcm_ns_usb3_module_init);
|
||||
|
||||
static void __exit bcm_ns_usb3_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bcm_ns_usb3_driver);
|
||||
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
|
||||
}
|
||||
module_exit(bcm_ns_usb3_module_exit)
|
||||
mdio_module_driver(bcm_ns_usb3_mdio_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
|
||||
|
@ -293,7 +293,6 @@ static int ns2_drd_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ns2_phy_driver *driver;
|
||||
struct ns2_phy_data *data;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
@ -307,23 +306,19 @@ static int ns2_drd_phy_probe(struct platform_device *pdev)
|
||||
if (!driver->data)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "icfg");
|
||||
driver->icfgdrd_regs = devm_ioremap_resource(dev, res);
|
||||
driver->icfgdrd_regs = devm_platform_ioremap_resource_byname(pdev, "icfg");
|
||||
if (IS_ERR(driver->icfgdrd_regs))
|
||||
return PTR_ERR(driver->icfgdrd_regs);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rst-ctrl");
|
||||
driver->idmdrd_rst_ctrl = devm_ioremap_resource(dev, res);
|
||||
driver->idmdrd_rst_ctrl = devm_platform_ioremap_resource_byname(pdev, "rst-ctrl");
|
||||
if (IS_ERR(driver->idmdrd_rst_ctrl))
|
||||
return PTR_ERR(driver->idmdrd_rst_ctrl);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crmu-ctrl");
|
||||
driver->crmu_usb2_ctrl = devm_ioremap_resource(dev, res);
|
||||
driver->crmu_usb2_ctrl = devm_platform_ioremap_resource_byname(pdev, "crmu-ctrl");
|
||||
if (IS_ERR(driver->crmu_usb2_ctrl))
|
||||
return PTR_ERR(driver->crmu_usb2_ctrl);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2-strap");
|
||||
driver->usb2h_strap_reg = devm_ioremap_resource(dev, res);
|
||||
driver->usb2h_strap_reg = devm_platform_ioremap_resource_byname(pdev, "usb2-strap");
|
||||
if (IS_ERR(driver->usb2h_strap_reg))
|
||||
return PTR_ERR(driver->usb2h_strap_reg);
|
||||
|
||||
|
@ -217,7 +217,6 @@ static int sr_pcie_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct sr_pcie_phy_core *core;
|
||||
struct resource *res;
|
||||
struct phy_provider *provider;
|
||||
unsigned int phy_idx = 0;
|
||||
|
||||
@ -226,9 +225,7 @@ static int sr_pcie_phy_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
core->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
core->base = devm_ioremap_resource(core->dev, res);
|
||||
core->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(core->base))
|
||||
return PTR_ERR(core->base);
|
||||
|
||||
|
@ -300,14 +300,12 @@ static int bcm_usb_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *dn = dev->of_node;
|
||||
const struct of_device_id *of_id;
|
||||
struct resource *res;
|
||||
void __iomem *regs;
|
||||
int ret;
|
||||
enum bcm_usb_phy_version version;
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(dev, res);
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@ -65,6 +65,7 @@ struct brcm_sata_port {
|
||||
bool ssc_en;
|
||||
enum brcm_sata_phy_rxaeq_mode rxaeq_mode;
|
||||
u32 rxaeq_val;
|
||||
u32 tx_amplitude_val;
|
||||
};
|
||||
|
||||
struct brcm_sata_phy {
|
||||
@ -84,6 +85,10 @@ enum sata_phy_regs {
|
||||
BLOCK0_SPARE_OOB_CLK_SEL_MASK = 0x3,
|
||||
BLOCK0_SPARE_OOB_CLK_SEL_REFBY2 = 0x1,
|
||||
|
||||
BLOCK1_REG_BANK = 0x10,
|
||||
BLOCK1_TEST_TX = 0x83,
|
||||
BLOCK1_TEST_TX_AMP_SHIFT = 12,
|
||||
|
||||
PLL_REG_BANK_0 = 0x050,
|
||||
PLL_REG_BANK_0_PLLCONTROL_0 = 0x81,
|
||||
PLLCONTROL_0_FREQ_DET_RESTART = BIT(13),
|
||||
@ -379,6 +384,29 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port)
|
||||
brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
|
||||
~tmp, RXPMD_MON_CORRECT_EN | value);
|
||||
|
||||
tmp = GENMASK(15, 12);
|
||||
switch (port->tx_amplitude_val) {
|
||||
case 400:
|
||||
value = BIT(12) | BIT(13);
|
||||
break;
|
||||
case 500:
|
||||
value = BIT(13);
|
||||
break;
|
||||
case 600:
|
||||
value = BIT(12);
|
||||
break;
|
||||
case 800:
|
||||
value = 0;
|
||||
break;
|
||||
default:
|
||||
value = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
if (value != tmp)
|
||||
brcm_sata_phy_wr(port, BLOCK1_REG_BANK, BLOCK1_TEST_TX, ~tmp,
|
||||
value);
|
||||
|
||||
/* Turn on/off SSC */
|
||||
brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN,
|
||||
port->ssc_en ? TX_ACTRL5_SSC_EN : 0);
|
||||
@ -726,7 +754,6 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
struct device_node *dn = dev->of_node, *child;
|
||||
const struct of_device_id *of_id;
|
||||
struct brcm_sata_phy *priv;
|
||||
struct resource *res;
|
||||
struct phy_provider *provider;
|
||||
int ret, count = 0;
|
||||
|
||||
@ -739,8 +766,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
dev_set_drvdata(dev, priv);
|
||||
priv->dev = dev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
|
||||
priv->phy_base = devm_ioremap_resource(dev, res);
|
||||
priv->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
|
||||
if (IS_ERR(priv->phy_base))
|
||||
return PTR_ERR(priv->phy_base);
|
||||
|
||||
@ -751,9 +777,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
priv->version = BRCM_SATA_PHY_STB_28NM;
|
||||
|
||||
if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy-ctrl");
|
||||
priv->ctrl_base = devm_ioremap_resource(dev, res);
|
||||
priv->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "phy-ctrl");
|
||||
if (IS_ERR(priv->ctrl_base))
|
||||
return PTR_ERR(priv->ctrl_base);
|
||||
}
|
||||
@ -791,6 +815,10 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
|
||||
if (port->rxaeq_mode == RXAEQ_MODE_MANUAL)
|
||||
of_property_read_u32(child, "brcm,rxaeq-value",
|
||||
&port->rxaeq_val);
|
||||
|
||||
of_property_read_u32(child, "brcm,tx-amplitude-millivolt",
|
||||
&port->tx_amplitude_val);
|
||||
|
||||
port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
|
||||
if (IS_ERR(port->phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
|
@ -314,7 +314,6 @@ static int cdns_dphy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct cdns_dphy *dphy;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
|
||||
@ -326,8 +325,7 @@ static int cdns_dphy_probe(struct platform_device *pdev)
|
||||
if (!dphy->ops)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dphy->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
dphy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(dphy->regs))
|
||||
return PTR_ERR(dphy->regs);
|
||||
|
||||
|
@ -263,7 +263,6 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev)
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cdns_salvo_phy *salvo_phy;
|
||||
struct resource *res;
|
||||
const struct of_device_id *match;
|
||||
struct cdns_salvo_data *data;
|
||||
|
||||
@ -281,8 +280,7 @@ static int cdns_salvo_phy_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(salvo_phy->clk))
|
||||
return PTR_ERR(salvo_phy->clk);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
salvo_phy->base = devm_ioremap_resource(dev, res);
|
||||
salvo_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(salvo_phy->base))
|
||||
return PTR_ERR(salvo_phy->base);
|
||||
|
||||
|
@ -479,7 +479,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
const struct of_device_id *match;
|
||||
struct cdns_sierra_data *data;
|
||||
unsigned int id_value;
|
||||
struct resource *res;
|
||||
int i, ret, node = 0;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
@ -502,8 +501,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
||||
sp->dev = dev;
|
||||
sp->init_data = data;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base)) {
|
||||
dev_err(dev, "missing \"reg\"\n");
|
||||
return PTR_ERR(base);
|
||||
|
@ -434,7 +434,6 @@ static int mixel_dphy_probe(struct platform_device *pdev)
|
||||
struct device_node *np = dev->of_node;
|
||||
struct phy_provider *phy_provider;
|
||||
struct mixel_dphy_priv *priv;
|
||||
struct resource *res;
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
|
||||
@ -449,8 +448,7 @@ static int mixel_dphy_probe(struct platform_device *pdev)
|
||||
if (!priv->devdata)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -131,7 +131,7 @@ static const struct phy_ops imx8mq_usb_phy_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct phy_ops imx8mp_usb_phy_ops = {
|
||||
static const struct phy_ops imx8mp_usb_phy_ops = {
|
||||
.init = imx8mp_usb_phy_init,
|
||||
.power_on = imx8mq_phy_power_on,
|
||||
.power_off = imx8mq_phy_power_off,
|
||||
@ -152,7 +152,6 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct imx8mq_usb_phy *imx_phy;
|
||||
struct resource *res;
|
||||
const struct phy_ops *phy_ops;
|
||||
|
||||
imx_phy = devm_kzalloc(dev, sizeof(*imx_phy), GFP_KERNEL);
|
||||
@ -165,8 +164,7 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(imx_phy->clk);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
imx_phy->base = devm_ioremap_resource(dev, res);
|
||||
imx_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(imx_phy->base))
|
||||
return PTR_ERR(imx_phy->base);
|
||||
|
||||
|
13
drivers/phy/ingenic/Kconfig
Normal file
13
drivers/phy/ingenic/Kconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Phy drivers for Ingenic platforms
|
||||
#
|
||||
config PHY_INGENIC_USB
|
||||
tristate "Ingenic SoCs USB PHY Driver"
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on USB_SUPPORT
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
This driver provides USB PHY support for the USB controller found
|
||||
on the JZ-series and X-series SoCs from Ingenic.
|
2
drivers/phy/ingenic/Makefile
Normal file
2
drivers/phy/ingenic/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y += phy-ingenic-usb.o
|
412
drivers/phy/ingenic/phy-ingenic-usb.c
Normal file
412
drivers/phy/ingenic/phy-ingenic-usb.c
Normal file
@ -0,0 +1,412 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Ingenic SoCs USB PHY driver
|
||||
* Copyright (c) Paul Cercueil <paul@crapouillou.net>
|
||||
* Copyright (c) 漆鹏振 (Qi Pengzhen) <aric.pzqi@ingenic.com>
|
||||
* Copyright (c) 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
/* OTGPHY register offsets */
|
||||
#define REG_USBPCR_OFFSET 0x00
|
||||
#define REG_USBRDT_OFFSET 0x04
|
||||
#define REG_USBVBFIL_OFFSET 0x08
|
||||
#define REG_USBPCR1_OFFSET 0x0c
|
||||
|
||||
/* bits within the USBPCR register */
|
||||
#define USBPCR_USB_MODE BIT(31)
|
||||
#define USBPCR_AVLD_REG BIT(30)
|
||||
#define USBPCR_COMMONONN BIT(25)
|
||||
#define USBPCR_VBUSVLDEXT BIT(24)
|
||||
#define USBPCR_VBUSVLDEXTSEL BIT(23)
|
||||
#define USBPCR_POR BIT(22)
|
||||
#define USBPCR_SIDDQ BIT(21)
|
||||
#define USBPCR_OTG_DISABLE BIT(20)
|
||||
#define USBPCR_TXPREEMPHTUNE BIT(6)
|
||||
|
||||
#define USBPCR_IDPULLUP_MASK GENMASK(29, 28)
|
||||
#define USBPCR_IDPULLUP_ALWAYS 0x2
|
||||
#define USBPCR_IDPULLUP_SUSPEND 0x1
|
||||
#define USBPCR_IDPULLUP_OTG 0x0
|
||||
|
||||
#define USBPCR_COMPDISTUNE_MASK GENMASK(19, 17)
|
||||
#define USBPCR_COMPDISTUNE_DFT 0x4
|
||||
|
||||
#define USBPCR_OTGTUNE_MASK GENMASK(16, 14)
|
||||
#define USBPCR_OTGTUNE_DFT 0x4
|
||||
|
||||
#define USBPCR_SQRXTUNE_MASK GENMASK(13, 11)
|
||||
#define USBPCR_SQRXTUNE_DCR_20PCT 0x7
|
||||
#define USBPCR_SQRXTUNE_DFT 0x3
|
||||
|
||||
#define USBPCR_TXFSLSTUNE_MASK GENMASK(10, 7)
|
||||
#define USBPCR_TXFSLSTUNE_DCR_50PPT 0xf
|
||||
#define USBPCR_TXFSLSTUNE_DCR_25PPT 0x7
|
||||
#define USBPCR_TXFSLSTUNE_DFT 0x3
|
||||
#define USBPCR_TXFSLSTUNE_INC_25PPT 0x1
|
||||
#define USBPCR_TXFSLSTUNE_INC_50PPT 0x0
|
||||
|
||||
#define USBPCR_TXHSXVTUNE_MASK GENMASK(5, 4)
|
||||
#define USBPCR_TXHSXVTUNE_DFT 0x3
|
||||
#define USBPCR_TXHSXVTUNE_DCR_15MV 0x1
|
||||
|
||||
#define USBPCR_TXRISETUNE_MASK GENMASK(5, 4)
|
||||
#define USBPCR_TXRISETUNE_DFT 0x3
|
||||
|
||||
#define USBPCR_TXVREFTUNE_MASK GENMASK(3, 0)
|
||||
#define USBPCR_TXVREFTUNE_INC_75PPT 0xb
|
||||
#define USBPCR_TXVREFTUNE_INC_25PPT 0x7
|
||||
#define USBPCR_TXVREFTUNE_DFT 0x5
|
||||
|
||||
/* bits within the USBRDTR register */
|
||||
#define USBRDT_UTMI_RST BIT(27)
|
||||
#define USBRDT_HB_MASK BIT(26)
|
||||
#define USBRDT_VBFIL_LD_EN BIT(25)
|
||||
#define USBRDT_IDDIG_EN BIT(24)
|
||||
#define USBRDT_IDDIG_REG BIT(23)
|
||||
#define USBRDT_VBFIL_EN BIT(2)
|
||||
|
||||
/* bits within the USBPCR1 register */
|
||||
#define USBPCR1_BVLD_REG BIT(31)
|
||||
#define USBPCR1_DPPD BIT(29)
|
||||
#define USBPCR1_DMPD BIT(28)
|
||||
#define USBPCR1_USB_SEL BIT(28)
|
||||
#define USBPCR1_PORT_RST BIT(21)
|
||||
#define USBPCR1_WORD_IF_16BIT BIT(19)
|
||||
|
||||
enum ingenic_usb_phy_version {
|
||||
ID_JZ4770,
|
||||
ID_JZ4775,
|
||||
ID_JZ4780,
|
||||
ID_X1000,
|
||||
ID_X1830,
|
||||
ID_X2000,
|
||||
};
|
||||
|
||||
struct ingenic_soc_info {
|
||||
enum ingenic_usb_phy_version version;
|
||||
|
||||
void (*usb_phy_init)(struct phy *phy);
|
||||
};
|
||||
|
||||
struct ingenic_usb_phy {
|
||||
const struct ingenic_soc_info *soc_info;
|
||||
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
struct regulator *vcc_supply;
|
||||
};
|
||||
|
||||
static int ingenic_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
int err;
|
||||
u32 reg;
|
||||
|
||||
err = clk_prepare_enable(priv->clk);
|
||||
if (err) {
|
||||
dev_err(&phy->dev, "Unable to start clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->soc_info->usb_phy_init(phy);
|
||||
|
||||
/* Wait for PHY to reset */
|
||||
usleep_range(30, 300);
|
||||
reg = readl(priv->base + REG_USBPCR_OFFSET);
|
||||
writel(reg & ~USBPCR_POR, priv->base + REG_USBPCR_OFFSET);
|
||||
usleep_range(300, 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ingenic_usb_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
regulator_disable(priv->vcc_supply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ingenic_usb_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
int err;
|
||||
|
||||
err = regulator_enable(priv->vcc_supply);
|
||||
if (err) {
|
||||
dev_err(&phy->dev, "Unable to enable VCC: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ingenic_usb_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
|
||||
regulator_disable(priv->vcc_supply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ingenic_usb_phy_set_mode(struct phy *phy,
|
||||
enum phy_mode mode, int submode)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
switch (mode) {
|
||||
case PHY_MODE_USB_HOST:
|
||||
reg = readl(priv->base + REG_USBPCR_OFFSET);
|
||||
u32p_replace_bits(®, 1, USBPCR_USB_MODE);
|
||||
u32p_replace_bits(®, 0, USBPCR_VBUSVLDEXT);
|
||||
u32p_replace_bits(®, 0, USBPCR_VBUSVLDEXTSEL);
|
||||
u32p_replace_bits(®, 0, USBPCR_OTG_DISABLE);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
|
||||
break;
|
||||
case PHY_MODE_USB_DEVICE:
|
||||
reg = readl(priv->base + REG_USBPCR_OFFSET);
|
||||
u32p_replace_bits(®, 0, USBPCR_USB_MODE);
|
||||
u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXT);
|
||||
u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXTSEL);
|
||||
u32p_replace_bits(®, 1, USBPCR_OTG_DISABLE);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
|
||||
break;
|
||||
case PHY_MODE_USB_OTG:
|
||||
reg = readl(priv->base + REG_USBPCR_OFFSET);
|
||||
u32p_replace_bits(®, 1, USBPCR_USB_MODE);
|
||||
u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXT);
|
||||
u32p_replace_bits(®, 1, USBPCR_VBUSVLDEXTSEL);
|
||||
u32p_replace_bits(®, 0, USBPCR_OTG_DISABLE);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops ingenic_usb_phy_ops = {
|
||||
.init = ingenic_usb_phy_init,
|
||||
.exit = ingenic_usb_phy_exit,
|
||||
.power_on = ingenic_usb_phy_power_on,
|
||||
.power_off = ingenic_usb_phy_power_off,
|
||||
.set_mode = ingenic_usb_phy_set_mode,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void jz4770_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
reg = USBPCR_AVLD_REG | USBPCR_COMMONONN | USBPCR_POR |
|
||||
FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_ALWAYS) |
|
||||
FIELD_PREP(USBPCR_COMPDISTUNE_MASK, USBPCR_COMPDISTUNE_DFT) |
|
||||
FIELD_PREP(USBPCR_OTGTUNE_MASK, USBPCR_OTGTUNE_DFT) |
|
||||
FIELD_PREP(USBPCR_SQRXTUNE_MASK, USBPCR_SQRXTUNE_DFT) |
|
||||
FIELD_PREP(USBPCR_TXFSLSTUNE_MASK, USBPCR_TXFSLSTUNE_DFT) |
|
||||
FIELD_PREP(USBPCR_TXRISETUNE_MASK, USBPCR_TXRISETUNE_DFT) |
|
||||
FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_DFT);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static void jz4775_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL |
|
||||
USBPCR1_WORD_IF_16BIT;
|
||||
writel(reg, priv->base + REG_USBPCR1_OFFSET);
|
||||
|
||||
reg = USBPCR_COMMONONN | USBPCR_POR |
|
||||
FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_INC_75PPT);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static void jz4780_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_USB_SEL |
|
||||
USBPCR1_WORD_IF_16BIT;
|
||||
writel(reg, priv->base + REG_USBPCR1_OFFSET);
|
||||
|
||||
reg = USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR;
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static void x1000_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT;
|
||||
writel(reg, priv->base + REG_USBPCR1_OFFSET);
|
||||
|
||||
reg = USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR |
|
||||
FIELD_PREP(USBPCR_SQRXTUNE_MASK, USBPCR_SQRXTUNE_DCR_20PCT) |
|
||||
FIELD_PREP(USBPCR_TXHSXVTUNE_MASK, USBPCR_TXHSXVTUNE_DCR_15MV) |
|
||||
FIELD_PREP(USBPCR_TXVREFTUNE_MASK, USBPCR_TXVREFTUNE_INC_25PPT);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static void x1830_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
/* rdt */
|
||||
writel(USBRDT_VBFIL_EN | USBRDT_UTMI_RST, priv->base + REG_USBRDT_OFFSET);
|
||||
|
||||
reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_WORD_IF_16BIT |
|
||||
USBPCR1_DMPD | USBPCR1_DPPD;
|
||||
writel(reg, priv->base + REG_USBPCR1_OFFSET);
|
||||
|
||||
reg = USBPCR_VBUSVLDEXT | USBPCR_TXPREEMPHTUNE | USBPCR_COMMONONN | USBPCR_POR |
|
||||
FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_OTG);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static void x2000_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ingenic_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 reg;
|
||||
|
||||
reg = readl(priv->base + REG_USBPCR1_OFFSET) | USBPCR1_DPPD | USBPCR1_DMPD;
|
||||
writel(reg & ~USBPCR1_PORT_RST, priv->base + REG_USBPCR1_OFFSET);
|
||||
|
||||
reg = USBPCR_POR | FIELD_PREP(USBPCR_IDPULLUP_MASK, USBPCR_IDPULLUP_OTG);
|
||||
writel(reg, priv->base + REG_USBPCR_OFFSET);
|
||||
}
|
||||
|
||||
static const struct ingenic_soc_info jz4770_soc_info = {
|
||||
.version = ID_JZ4770,
|
||||
|
||||
.usb_phy_init = jz4770_usb_phy_init,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info jz4775_soc_info = {
|
||||
.version = ID_JZ4775,
|
||||
|
||||
.usb_phy_init = jz4775_usb_phy_init,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info jz4780_soc_info = {
|
||||
.version = ID_JZ4780,
|
||||
|
||||
.usb_phy_init = jz4780_usb_phy_init,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info x1000_soc_info = {
|
||||
.version = ID_X1000,
|
||||
|
||||
.usb_phy_init = x1000_usb_phy_init,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info x1830_soc_info = {
|
||||
.version = ID_X1830,
|
||||
|
||||
.usb_phy_init = x1830_usb_phy_init,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info x2000_soc_info = {
|
||||
.version = ID_X2000,
|
||||
|
||||
.usb_phy_init = x2000_usb_phy_init,
|
||||
};
|
||||
|
||||
static int ingenic_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ingenic_usb_phy *priv;
|
||||
struct phy_provider *provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
int err;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->soc_info = device_get_match_data(dev);
|
||||
if (!priv->soc_info) {
|
||||
dev_err(dev, "Error: No device match found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->base)) {
|
||||
dev_err(dev, "Failed to map registers\n");
|
||||
return PTR_ERR(priv->base);
|
||||
}
|
||||
|
||||
priv->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(priv->clk)) {
|
||||
err = PTR_ERR(priv->clk);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get clock\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->vcc_supply = devm_regulator_get(dev, "vcc");
|
||||
if (IS_ERR(priv->vcc_supply)) {
|
||||
err = PTR_ERR(priv->vcc_supply);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get regulator\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops);
|
||||
if (IS_ERR(priv))
|
||||
return PTR_ERR(priv);
|
||||
|
||||
phy_set_drvdata(priv->phy, priv);
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id ingenic_usb_phy_of_matches[] = {
|
||||
{ .compatible = "ingenic,jz4770-phy", .data = &jz4770_soc_info },
|
||||
{ .compatible = "ingenic,jz4775-phy", .data = &jz4775_soc_info },
|
||||
{ .compatible = "ingenic,jz4780-phy", .data = &jz4780_soc_info },
|
||||
{ .compatible = "ingenic,x1000-phy", .data = &x1000_soc_info },
|
||||
{ .compatible = "ingenic,x1830-phy", .data = &x1830_soc_info },
|
||||
{ .compatible = "ingenic,x2000-phy", .data = &x2000_soc_info },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ingenic_usb_phy_of_matches);
|
||||
|
||||
static struct platform_driver ingenic_usb_phy_driver = {
|
||||
.probe = ingenic_usb_phy_probe,
|
||||
.driver = {
|
||||
.name = "ingenic-usb-phy",
|
||||
.of_match_table = ingenic_usb_phy_of_matches,
|
||||
},
|
||||
};
|
||||
module_platform_driver(ingenic_usb_phy_driver);
|
||||
|
||||
MODULE_AUTHOR("周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>");
|
||||
MODULE_AUTHOR("漆鹏振 (Qi Pengzhen) <aric.pzqi@ingenic.com>");
|
||||
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
|
||||
MODULE_DESCRIPTION("Ingenic SoCs USB PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -14,6 +14,18 @@ config PHY_INTEL_KEEMBAY_EMMC
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called phy-keembay-emmc.ko.
|
||||
|
||||
config PHY_INTEL_KEEMBAY_USB
|
||||
tristate "Intel Keem Bay USB PHY driver"
|
||||
depends on ARCH_KEEMBAY || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Choose this option if you have an Intel Keem Bay SoC.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called phy-keembay-usb.ko.
|
||||
|
||||
config PHY_INTEL_LGM_COMBO
|
||||
bool "Intel Lightning Mountain ComboPHY driver"
|
||||
depends on X86 || COMPILE_TEST
|
||||
|
@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC) += phy-intel-keembay-emmc.o
|
||||
obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB) += phy-intel-keembay-usb.o
|
||||
obj-$(CONFIG_PHY_INTEL_LGM_COMBO) += phy-intel-lgm-combo.o
|
||||
obj-$(CONFIG_PHY_INTEL_LGM_EMMC) += phy-intel-lgm-emmc.o
|
||||
|
301
drivers/phy/intel/phy-intel-keembay-usb.c
Normal file
301
drivers/phy/intel/phy-intel-keembay-usb.c
Normal file
@ -0,0 +1,301 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Intel Keem Bay USB PHY driver
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* USS (USB Subsystem) clock control registers */
|
||||
#define USS_CPR_CLK_EN 0x00
|
||||
#define USS_CPR_CLK_SET 0x04
|
||||
#define USS_CPR_CLK_CLR 0x08
|
||||
#define USS_CPR_RST_EN 0x10
|
||||
#define USS_CPR_RST_SET 0x14
|
||||
#define USS_CPR_RST_CLR 0x18
|
||||
|
||||
/* USS clock/reset bit fields */
|
||||
#define USS_CPR_PHY_TST BIT(6)
|
||||
#define USS_CPR_LOW_JIT BIT(5)
|
||||
#define USS_CPR_CORE BIT(4)
|
||||
#define USS_CPR_SUSPEND BIT(3)
|
||||
#define USS_CPR_ALT_REF BIT(2)
|
||||
#define USS_CPR_REF BIT(1)
|
||||
#define USS_CPR_SYS BIT(0)
|
||||
#define USS_CPR_MASK GENMASK(6, 0)
|
||||
|
||||
/* USS APB slave registers */
|
||||
#define USS_USB_CTRL_CFG0 0x10
|
||||
#define VCC_RESET_N_MASK BIT(31)
|
||||
|
||||
#define USS_USB_PHY_CFG0 0x30
|
||||
#define POR_MASK BIT(15)
|
||||
#define PHY_RESET_MASK BIT(14)
|
||||
#define PHY_REF_USE_PAD_MASK BIT(5)
|
||||
|
||||
#define USS_USB_PHY_CFG6 0x64
|
||||
#define PHY0_SRAM_EXT_LD_DONE_MASK BIT(23)
|
||||
|
||||
#define USS_USB_PARALLEL_IF_CTRL 0xa0
|
||||
#define USB_PHY_CR_PARA_SEL_MASK BIT(2)
|
||||
|
||||
#define USS_USB_TSET_SIGNALS_AND_GLOB 0xac
|
||||
#define USB_PHY_CR_PARA_CLK_EN_MASK BIT(7)
|
||||
|
||||
#define USS_USB_STATUS_REG 0xb8
|
||||
#define PHY0_SRAM_INIT_DONE_MASK BIT(3)
|
||||
|
||||
#define USS_USB_TIEOFFS_CONSTANTS_REG1 0xc0
|
||||
#define IDDQ_ENABLE_MASK BIT(10)
|
||||
|
||||
struct keembay_usb_phy {
|
||||
struct device *dev;
|
||||
struct regmap *regmap_cpr;
|
||||
struct regmap *regmap_slv;
|
||||
};
|
||||
|
||||
static const struct regmap_config keembay_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = USS_USB_TIEOFFS_CONSTANTS_REG1,
|
||||
};
|
||||
|
||||
static int keembay_usb_clocks_on(struct keembay_usb_phy *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_cpr, USS_CPR_CLK_SET,
|
||||
USS_CPR_MASK, USS_CPR_MASK);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error clock set: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_cpr, USS_CPR_RST_SET,
|
||||
USS_CPR_MASK, USS_CPR_MASK);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error reset set: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv,
|
||||
USS_USB_TIEOFFS_CONSTANTS_REG1,
|
||||
IDDQ_ENABLE_MASK,
|
||||
FIELD_PREP(IDDQ_ENABLE_MASK, 0));
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error iddq disable: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait 30us to ensure all analog blocks are powered up. */
|
||||
usleep_range(30, 60);
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG0,
|
||||
PHY_REF_USE_PAD_MASK,
|
||||
FIELD_PREP(PHY_REF_USE_PAD_MASK, 1));
|
||||
if (ret)
|
||||
dev_err(priv->dev, "error ref clock select: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keembay_usb_core_off(struct keembay_usb_phy *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv, USS_USB_CTRL_CFG0,
|
||||
VCC_RESET_N_MASK,
|
||||
FIELD_PREP(VCC_RESET_N_MASK, 0));
|
||||
if (ret)
|
||||
dev_err(priv->dev, "error core reset: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keembay_usb_core_on(struct keembay_usb_phy *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv, USS_USB_CTRL_CFG0,
|
||||
VCC_RESET_N_MASK,
|
||||
FIELD_PREP(VCC_RESET_N_MASK, 1));
|
||||
if (ret)
|
||||
dev_err(priv->dev, "error core on: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keembay_usb_phys_on(struct keembay_usb_phy *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG0,
|
||||
POR_MASK | PHY_RESET_MASK,
|
||||
FIELD_PREP(POR_MASK | PHY_RESET_MASK, 0));
|
||||
if (ret)
|
||||
dev_err(priv->dev, "error phys on: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int keembay_usb_phy_init(struct phy *phy)
|
||||
{
|
||||
struct keembay_usb_phy *priv = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = keembay_usb_core_off(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* According to Keem Bay datasheet, wait minimum 20us after clock
|
||||
* enable before bringing PHYs out of reset.
|
||||
*/
|
||||
usleep_range(20, 40);
|
||||
|
||||
ret = keembay_usb_phys_on(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv,
|
||||
USS_USB_TSET_SIGNALS_AND_GLOB,
|
||||
USB_PHY_CR_PARA_CLK_EN_MASK,
|
||||
FIELD_PREP(USB_PHY_CR_PARA_CLK_EN_MASK, 0));
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error cr clock disable: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to Keem Bay datasheet, wait 2us after disabling the
|
||||
* clock into the USB 3.x parallel interface.
|
||||
*/
|
||||
udelay(2);
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv,
|
||||
USS_USB_PARALLEL_IF_CTRL,
|
||||
USB_PHY_CR_PARA_SEL_MASK,
|
||||
FIELD_PREP(USB_PHY_CR_PARA_SEL_MASK, 1));
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error cr select: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv,
|
||||
USS_USB_TSET_SIGNALS_AND_GLOB,
|
||||
USB_PHY_CR_PARA_CLK_EN_MASK,
|
||||
FIELD_PREP(USB_PHY_CR_PARA_CLK_EN_MASK, 1));
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error cr clock enable: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap_slv, USS_USB_STATUS_REG,
|
||||
val, val & PHY0_SRAM_INIT_DONE_MASK,
|
||||
USEC_PER_MSEC, 10 * USEC_PER_MSEC);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "SRAM init not done: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(priv->regmap_slv, USS_USB_PHY_CFG6,
|
||||
PHY0_SRAM_EXT_LD_DONE_MASK,
|
||||
FIELD_PREP(PHY0_SRAM_EXT_LD_DONE_MASK, 1));
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "error SRAM init done set: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to Keem Bay datasheet, wait 20us after setting the
|
||||
* SRAM load done bit, before releasing the controller reset.
|
||||
*/
|
||||
usleep_range(20, 40);
|
||||
|
||||
return keembay_usb_core_on(priv);
|
||||
}
|
||||
|
||||
static const struct phy_ops ops = {
|
||||
.init = keembay_usb_phy_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int keembay_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct keembay_usb_phy *priv;
|
||||
struct phy *generic_phy;
|
||||
struct phy_provider *phy_provider;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
base = devm_platform_ioremap_resource_byname(pdev, "cpr-apb-base");
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
priv->regmap_cpr = devm_regmap_init_mmio(dev, base,
|
||||
&keembay_regmap_config);
|
||||
if (IS_ERR(priv->regmap_cpr))
|
||||
return PTR_ERR(priv->regmap_cpr);
|
||||
|
||||
base = devm_platform_ioremap_resource_byname(pdev, "slv-apb-base");
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
priv->regmap_slv = devm_regmap_init_mmio(dev, base,
|
||||
&keembay_regmap_config);
|
||||
if (IS_ERR(priv->regmap_slv))
|
||||
return PTR_ERR(priv->regmap_slv);
|
||||
|
||||
generic_phy = devm_phy_create(dev, dev->of_node, &ops);
|
||||
if (IS_ERR(generic_phy))
|
||||
return dev_err_probe(dev, PTR_ERR(generic_phy),
|
||||
"failed to create PHY\n");
|
||||
|
||||
phy_set_drvdata(generic_phy, priv);
|
||||
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),
|
||||
"failed to register phy provider\n");
|
||||
|
||||
/* Setup USB subsystem clocks */
|
||||
ret = keembay_usb_clocks_on(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* and turn on the DWC3 core, prior to DWC3 driver init. */
|
||||
return keembay_usb_core_on(priv);
|
||||
}
|
||||
|
||||
static const struct of_device_id keembay_usb_phy_dt_ids[] = {
|
||||
{ .compatible = "intel,keembay-usb-phy" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, keembay_usb_phy_dt_ids);
|
||||
|
||||
static struct platform_driver keembay_usb_phy_driver = {
|
||||
.probe = keembay_usb_phy_probe,
|
||||
.driver = {
|
||||
.name = "keembay-usb-phy",
|
||||
.of_match_table = keembay_usb_phy_dt_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(keembay_usb_phy_driver);
|
||||
|
||||
MODULE_AUTHOR("Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>");
|
||||
MODULE_DESCRIPTION("Intel Keem Bay USB PHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -402,7 +402,6 @@ static int ltq_vrx200_pcie_phy_probe(struct platform_device *pdev)
|
||||
struct ltq_vrx200_pcie_phy_priv *priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *provider;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
@ -410,8 +409,7 @@ static int ltq_vrx200_pcie_phy_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -116,3 +116,15 @@ config PHY_MMP3_USB
|
||||
The PHY driver will be used by Marvell udc/ehci/otg driver.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_MMP3_HSIC
|
||||
tristate "Marvell MMP3 USB HSIC PHY Driver"
|
||||
depends on MACH_MMP3_DT || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Marvell MMP3 USB HSIC PHY driver for
|
||||
Marvell MMP3 SoC. This driver will be used my the Marvell EHCI
|
||||
driver to initialize the interface to internal USB HSIC
|
||||
components on MMP3-based boards.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
@ -3,6 +3,7 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
|
||||
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
|
||||
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
|
||||
obj-$(CONFIG_PHY_MMP3_USB) += phy-mmp3-usb.o
|
||||
obj-$(CONFIG_PHY_MMP3_HSIC) += phy-mmp3-hsic.o
|
||||
obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o
|
||||
obj-$(CONFIG_PHY_MVEBU_A3700_UTMI) += phy-mvebu-a3700-utmi.o
|
||||
obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o
|
||||
|
@ -105,15 +105,13 @@ static int armada375_usb_phy_probe(struct platform_device *pdev)
|
||||
struct phy *phy;
|
||||
struct phy_provider *phy_provider;
|
||||
void __iomem *usb_cluster_base;
|
||||
struct resource *res;
|
||||
struct armada375_cluster_phy *cluster_phy;
|
||||
|
||||
cluster_phy = devm_kzalloc(dev, sizeof(*cluster_phy), GFP_KERNEL);
|
||||
if (!cluster_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
usb_cluster_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
usb_cluster_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(usb_cluster_base))
|
||||
return PTR_ERR(usb_cluster_base);
|
||||
|
||||
|
@ -165,7 +165,6 @@ static int phy_berlin_usb_probe(struct platform_device *pdev)
|
||||
const struct of_device_id *match =
|
||||
of_match_device(phy_berlin_usb_of_match, &pdev->dev);
|
||||
struct phy_berlin_usb_priv *priv;
|
||||
struct resource *res;
|
||||
struct phy *phy;
|
||||
struct phy_provider *phy_provider;
|
||||
|
||||
@ -173,8 +172,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
|
82
drivers/phy/marvell/phy-mmp3-hsic.c
Normal file
82
drivers/phy/marvell/phy-mmp3-hsic.c
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define HSIC_CTRL 0x08
|
||||
#define HSIC_ENABLE BIT(7)
|
||||
#define PLL_BYPASS BIT(4)
|
||||
|
||||
static int mmp3_hsic_phy_init(struct phy *phy)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)phy_get_drvdata(phy);
|
||||
u32 hsic_ctrl;
|
||||
|
||||
hsic_ctrl = readl_relaxed(base + HSIC_CTRL);
|
||||
hsic_ctrl |= HSIC_ENABLE;
|
||||
hsic_ctrl |= PLL_BYPASS;
|
||||
writel_relaxed(hsic_ctrl, base + HSIC_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops mmp3_hsic_phy_ops = {
|
||||
.init = mmp3_hsic_phy_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct of_device_id mmp3_hsic_phy_of_match[] = {
|
||||
{ .compatible = "marvell,mmp3-hsic-phy", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match);
|
||||
|
||||
static int mmp3_hsic_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *provider;
|
||||
struct resource *resource;
|
||||
void __iomem *base;
|
||||
struct phy *phy;
|
||||
|
||||
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");
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, (void *)base);
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "failed to register PHY provider\n");
|
||||
return PTR_ERR(provider);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mmp3_hsic_phy_driver = {
|
||||
.probe = mmp3_hsic_phy_probe,
|
||||
.driver = {
|
||||
.name = "mmp3-hsic-phy",
|
||||
.of_match_table = mmp3_hsic_phy_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(mmp3_hsic_phy_driver);
|
||||
|
||||
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
|
||||
MODULE_DESCRIPTION("Marvell MMP3 USB HSIC PHY Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -246,7 +246,6 @@ MODULE_DEVICE_TABLE(of, mmp3_usb_phy_of_match);
|
||||
static int mmp3_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *resource;
|
||||
struct mmp3_usb_phy *mmp3_usb_phy;
|
||||
struct phy_provider *provider;
|
||||
|
||||
@ -254,8 +253,7 @@ static int mmp3_usb_phy_probe(struct platform_device *pdev)
|
||||
if (!mmp3_usb_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mmp3_usb_phy->base = devm_ioremap_resource(dev, resource);
|
||||
mmp3_usb_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(mmp3_usb_phy->base)) {
|
||||
dev_err(dev, "failed to remap PHY regs\n");
|
||||
return PTR_ERR(mmp3_usb_phy->base);
|
||||
|
@ -80,7 +80,6 @@ static const struct phy_ops phy_mvebu_sata_ops = {
|
||||
static int phy_mvebu_sata_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct priv *priv;
|
||||
struct phy *phy;
|
||||
|
||||
@ -88,8 +87,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
priv->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
|
@ -162,7 +162,6 @@ static int mv_hsic_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct mv_hsic_phy *mv_phy;
|
||||
struct resource *r;
|
||||
|
||||
mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL);
|
||||
if (!mv_phy)
|
||||
@ -176,8 +175,7 @@ static int mv_hsic_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(mv_phy->clk);
|
||||
}
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mv_phy->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
mv_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(mv_phy->base))
|
||||
return PTR_ERR(mv_phy->base);
|
||||
|
||||
|
@ -294,7 +294,6 @@ static int mv_usb2_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct mv_usb2_phy *mv_phy;
|
||||
struct resource *r;
|
||||
|
||||
mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL);
|
||||
if (!mv_phy)
|
||||
@ -308,8 +307,7 @@ static int mv_usb2_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(mv_phy->clk);
|
||||
}
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mv_phy->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
mv_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(mv_phy->base))
|
||||
return PTR_ERR(mv_phy->base);
|
||||
|
||||
|
@ -286,7 +286,6 @@ MODULE_DEVICE_TABLE(of, pxa_usb_phy_of_match);
|
||||
static int pxa_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *resource;
|
||||
struct pxa_usb_phy *pxa_usb_phy;
|
||||
struct phy_provider *provider;
|
||||
const struct of_device_id *of_id;
|
||||
@ -301,8 +300,7 @@ static int pxa_usb_phy_probe(struct platform_device *pdev)
|
||||
else
|
||||
pxa_usb_phy->version = PXA_USB_PHY_MMP2;
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
pxa_usb_phy->base = devm_ioremap_resource(dev, resource);
|
||||
pxa_usb_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pxa_usb_phy->base)) {
|
||||
dev_err(dev, "failed to remap PHY regs\n");
|
||||
return PTR_ERR(pxa_usb_phy->base);
|
||||
|
@ -5,7 +5,8 @@
|
||||
config PHY_MTK_TPHY
|
||||
tristate "MediaTek T-PHY Driver"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on OF && OF_ADDRESS
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Say 'Y' here to add support for MediaTek T-PHY driver,
|
||||
@ -29,7 +30,8 @@ config PHY_MTK_UFS
|
||||
config PHY_MTK_XSPHY
|
||||
tristate "MediaTek XS-PHY Driver"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
depends on OF
|
||||
depends on OF && OF_ADDRESS
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the SuperSpeedPlus XS-PHY transceiver for
|
||||
@ -38,7 +40,9 @@ config PHY_MTK_XSPHY
|
||||
|
||||
config PHY_MTK_HDMI
|
||||
tristate "MediaTek HDMI-PHY Driver"
|
||||
depends on ARCH_MEDIATEK && OF
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support HDMI PHY for Mediatek SoCs.
|
||||
|
@ -84,8 +84,9 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
|
||||
hdmi_phy->conf->hdmi_phy_disable_tmds)
|
||||
return &mtk_hdmi_phy_dev_ops;
|
||||
|
||||
dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n");
|
||||
return NULL;
|
||||
if (hdmi_phy)
|
||||
dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
|
||||
@ -201,7 +202,7 @@ static const struct of_device_id mtk_hdmi_phy_match[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
struct platform_driver mtk_hdmi_phy_driver = {
|
||||
static struct platform_driver mtk_hdmi_phy_driver = {
|
||||
.probe = mtk_hdmi_phy_probe,
|
||||
.driver = {
|
||||
.name = "mediatek-hdmi-phy",
|
||||
|
@ -195,7 +195,6 @@ static int ufs_mtk_phy_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy *generic_phy;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct ufs_mtk_phy *phy;
|
||||
int ret;
|
||||
|
||||
@ -203,8 +202,7 @@ static int ufs_mtk_phy_probe(struct platform_device *pdev)
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->mmio = devm_ioremap_resource(dev, res);
|
||||
phy->mmio = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->mmio))
|
||||
return PTR_ERR(phy->mmio);
|
||||
|
||||
|
@ -1644,7 +1644,6 @@ static int xgene_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct xgene_phy_ctx *ctx;
|
||||
struct resource *res;
|
||||
u32 default_spd[] = DEFAULT_SATA_SPD_SEL;
|
||||
u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN;
|
||||
u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION;
|
||||
@ -1661,8 +1660,7 @@ static int xgene_phy_probe(struct platform_device *pdev)
|
||||
|
||||
ctx->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ctx->sds_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
ctx->sds_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ctx->sds_base))
|
||||
return PTR_ERR(ctx->sds_base);
|
||||
|
||||
|
@ -201,7 +201,6 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_apq8064_sata_phy *phy;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
struct phy *generic_phy;
|
||||
int ret;
|
||||
@ -210,8 +209,7 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev)
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->mmio = devm_ioremap_resource(dev, res);
|
||||
phy->mmio = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->mmio))
|
||||
return PTR_ERR(phy->mmio);
|
||||
|
||||
|
@ -95,7 +95,6 @@ MODULE_DEVICE_TABLE(of, ipq4019_usb_phy_of_match);
|
||||
static int ipq4019_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
struct ipq4019_usb_phy *phy;
|
||||
|
||||
@ -104,8 +103,7 @@ static int ipq4019_usb_phy_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
phy->dev = &pdev->dev;
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->base)) {
|
||||
dev_err(dev, "failed to remap register memory\n");
|
||||
return PTR_ERR(phy->base);
|
||||
|
@ -128,7 +128,6 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_ipq806x_sata_phy *phy;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
struct phy *generic_phy;
|
||||
int ret;
|
||||
@ -137,8 +136,7 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->mmio = devm_ioremap_resource(dev, res);
|
||||
phy->mmio = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->mmio))
|
||||
return PTR_ERR(phy->mmio);
|
||||
|
||||
|
@ -250,7 +250,6 @@ static int qcom_pcie2_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct qcom_phy *qphy;
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy *phy;
|
||||
int ret;
|
||||
@ -260,9 +259,7 @@ static int qcom_pcie2_phy_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
qphy->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
qphy->base = devm_ioremap_resource(dev, res);
|
||||
qphy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(qphy->base))
|
||||
return PTR_ERR(qphy->base);
|
||||
|
||||
|
@ -217,6 +217,13 @@ static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_PCS_READY_STATUS] = 0x160,
|
||||
};
|
||||
|
||||
static const unsigned int sm8250_pcie_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 sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
|
||||
[QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
|
||||
[QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
|
||||
@ -1824,6 +1831,149 @@ static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x55),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x68),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xaa),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x34),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xa2),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x06),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_serdes_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x07),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x35),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RCLK_AUXDATA_SEL, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x14),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x30),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x0b),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x12),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_tx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x20),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_rx_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xbf),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x15),
|
||||
QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x05),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f),
|
||||
};
|
||||
|
||||
static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
|
||||
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
|
||||
};
|
||||
|
||||
/* struct qmp_phy_cfg - per-PHY initialization config */
|
||||
struct qmp_phy_cfg {
|
||||
/* phy-type - PCIE/UFS/USB */
|
||||
@ -1834,14 +1984,24 @@ struct qmp_phy_cfg {
|
||||
/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
|
||||
const struct qmp_phy_init_tbl *serdes_tbl;
|
||||
int serdes_tbl_num;
|
||||
const struct qmp_phy_init_tbl *serdes_tbl_sec;
|
||||
int serdes_tbl_num_sec;
|
||||
const struct qmp_phy_init_tbl *tx_tbl;
|
||||
int tx_tbl_num;
|
||||
const struct qmp_phy_init_tbl *tx_tbl_sec;
|
||||
int tx_tbl_num_sec;
|
||||
const struct qmp_phy_init_tbl *rx_tbl;
|
||||
int rx_tbl_num;
|
||||
const struct qmp_phy_init_tbl *rx_tbl_sec;
|
||||
int rx_tbl_num_sec;
|
||||
const struct qmp_phy_init_tbl *pcs_tbl;
|
||||
int pcs_tbl_num;
|
||||
const struct qmp_phy_init_tbl *pcs_tbl_sec;
|
||||
int pcs_tbl_num_sec;
|
||||
const struct qmp_phy_init_tbl *pcs_misc_tbl;
|
||||
int pcs_misc_tbl_num;
|
||||
const struct qmp_phy_init_tbl *pcs_misc_tbl_sec;
|
||||
int pcs_misc_tbl_num_sec;
|
||||
|
||||
/* Init sequence for DP PHY block link rates */
|
||||
const struct qmp_phy_init_tbl *serdes_tbl_rbr;
|
||||
@ -2245,6 +2405,83 @@ static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
|
||||
.pwrdn_delay_max = 1005, /* us */
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
|
||||
.type = PHY_TYPE_PCIE,
|
||||
.nlanes = 1,
|
||||
|
||||
.serdes_tbl = sm8250_qmp_pcie_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
|
||||
.serdes_tbl_sec = sm8250_qmp_gen3x1_pcie_serdes_tbl,
|
||||
.serdes_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
|
||||
.tx_tbl = sm8250_qmp_pcie_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
|
||||
.rx_tbl = sm8250_qmp_pcie_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
|
||||
.rx_tbl_sec = sm8250_qmp_gen3x1_pcie_rx_tbl,
|
||||
.rx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_rx_tbl),
|
||||
.pcs_tbl = sm8250_qmp_pcie_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
|
||||
.pcs_tbl_sec = sm8250_qmp_gen3x1_pcie_pcs_tbl,
|
||||
.pcs_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_pcs_tbl),
|
||||
.pcs_misc_tbl = sm8250_qmp_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
|
||||
.pcs_misc_tbl_sec = sm8250_qmp_gen3x1_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x1_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 | REFCLK_DRV_DSBL,
|
||||
|
||||
.has_pwrdn_delay = true,
|
||||
.pwrdn_delay_min = 995, /* us */
|
||||
.pwrdn_delay_max = 1005, /* us */
|
||||
};
|
||||
|
||||
static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
|
||||
.type = PHY_TYPE_PCIE,
|
||||
.nlanes = 2,
|
||||
|
||||
.serdes_tbl = sm8250_qmp_pcie_serdes_tbl,
|
||||
.serdes_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
|
||||
.tx_tbl = sm8250_qmp_pcie_tx_tbl,
|
||||
.tx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_tx_tbl),
|
||||
.tx_tbl_sec = sm8250_qmp_gen3x2_pcie_tx_tbl,
|
||||
.tx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
|
||||
.rx_tbl = sm8250_qmp_pcie_rx_tbl,
|
||||
.rx_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_rx_tbl),
|
||||
.rx_tbl_sec = sm8250_qmp_gen3x2_pcie_rx_tbl,
|
||||
.rx_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_rx_tbl),
|
||||
.pcs_tbl = sm8250_qmp_pcie_pcs_tbl,
|
||||
.pcs_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_tbl),
|
||||
.pcs_tbl_sec = sm8250_qmp_gen3x2_pcie_pcs_tbl,
|
||||
.pcs_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_pcs_tbl),
|
||||
.pcs_misc_tbl = sm8250_qmp_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
|
||||
.pcs_misc_tbl_sec = sm8250_qmp_gen3x2_pcie_pcs_misc_tbl,
|
||||
.pcs_misc_tbl_num_sec = ARRAY_SIZE(sm8250_qmp_gen3x2_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 | REFCLK_DRV_DSBL,
|
||||
|
||||
.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 qmp_v3_usb3phy_cfg = {
|
||||
.type = PHY_TYPE_USB3,
|
||||
.nlanes = 1,
|
||||
@ -2629,6 +2866,9 @@ static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
|
||||
int ret;
|
||||
|
||||
qcom_qmp_phy_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
|
||||
if (cfg->serdes_tbl_sec)
|
||||
qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl_sec,
|
||||
cfg->serdes_tbl_num_sec);
|
||||
|
||||
if (cfg->type == PHY_TYPE_DP) {
|
||||
switch (dp_opts->link_rate) {
|
||||
@ -3117,10 +3357,19 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
|
||||
/* Tx, Rx, and PCS configurations */
|
||||
qcom_qmp_phy_configure_lane(tx, cfg->regs,
|
||||
cfg->tx_tbl, cfg->tx_tbl_num, 1);
|
||||
if (cfg->tx_tbl_sec)
|
||||
qcom_qmp_phy_configure_lane(tx, cfg->regs, cfg->tx_tbl_sec,
|
||||
cfg->tx_tbl_num_sec, 1);
|
||||
|
||||
/* Configuration for other LANE for USB-DP combo PHY */
|
||||
if (cfg->is_dual_lane_phy)
|
||||
if (cfg->is_dual_lane_phy) {
|
||||
qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
|
||||
cfg->tx_tbl, cfg->tx_tbl_num, 2);
|
||||
if (cfg->tx_tbl_sec)
|
||||
qcom_qmp_phy_configure_lane(qphy->tx2, cfg->regs,
|
||||
cfg->tx_tbl_sec,
|
||||
cfg->tx_tbl_num_sec, 2);
|
||||
}
|
||||
|
||||
/* Configure special DP tx tunings */
|
||||
if (cfg->type == PHY_TYPE_DP)
|
||||
@ -3128,16 +3377,28 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
|
||||
|
||||
qcom_qmp_phy_configure_lane(rx, cfg->regs,
|
||||
cfg->rx_tbl, cfg->rx_tbl_num, 1);
|
||||
if (cfg->rx_tbl_sec)
|
||||
qcom_qmp_phy_configure_lane(rx, cfg->regs,
|
||||
cfg->rx_tbl_sec, cfg->rx_tbl_num_sec, 1);
|
||||
|
||||
if (cfg->is_dual_lane_phy)
|
||||
if (cfg->is_dual_lane_phy) {
|
||||
qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
|
||||
cfg->rx_tbl, cfg->rx_tbl_num, 2);
|
||||
if (cfg->rx_tbl_sec)
|
||||
qcom_qmp_phy_configure_lane(qphy->rx2, cfg->regs,
|
||||
cfg->rx_tbl_sec,
|
||||
cfg->rx_tbl_num_sec, 2);
|
||||
}
|
||||
|
||||
/* Configure link rate, swing, etc. */
|
||||
if (cfg->type == PHY_TYPE_DP)
|
||||
if (cfg->type == PHY_TYPE_DP) {
|
||||
qcom_qmp_phy_configure_dp_phy(qphy);
|
||||
else
|
||||
} else {
|
||||
qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
|
||||
if (cfg->pcs_tbl_sec)
|
||||
qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl_sec,
|
||||
cfg->pcs_tbl_num_sec);
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(qmp->ufs_reset);
|
||||
if (ret)
|
||||
@ -3145,6 +3406,9 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
|
||||
|
||||
qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl,
|
||||
cfg->pcs_misc_tbl_num);
|
||||
if (cfg->pcs_misc_tbl_sec)
|
||||
qcom_qmp_phy_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
|
||||
cfg->pcs_misc_tbl_num_sec);
|
||||
|
||||
/*
|
||||
* Pull out PHY from POWER DOWN state.
|
||||
@ -3900,6 +4164,15 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,sm8250-qmp-usb3-uni-phy",
|
||||
.data = &sm8250_usb3_uniphy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
|
||||
.data = &sm8250_qmp_gen3x1_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
|
||||
.data = &sm8250_qmp_gen3x2_pciephy_cfg,
|
||||
}, {
|
||||
.compatible = "qcom,sm8250-qmp-modem-pcie-phy",
|
||||
.data = &sm8250_qmp_gen3x2_pciephy_cfg,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
@ -403,6 +403,7 @@
|
||||
#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0 0x028
|
||||
#define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1 0x030
|
||||
#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1 0x034
|
||||
#define QSERDES_V4_COM_CLK_ENABLE1 0x048
|
||||
#define QSERDES_V4_COM_SYSCLK_BUF_ENABLE 0x050
|
||||
#define QSERDES_V4_COM_PLL_IVCO 0x058
|
||||
#define QSERDES_V4_COM_CMN_IPTRIM 0x060
|
||||
@ -432,6 +433,7 @@
|
||||
#define QSERDES_V4_COM_VCO_TUNE1_MODE1 0x118
|
||||
#define QSERDES_V4_COM_VCO_TUNE2_MODE1 0x11c
|
||||
#define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124
|
||||
#define QSERDES_V4_COM_CLK_SELECT 0x154
|
||||
#define QSERDES_V4_COM_HSCLK_SEL 0x158
|
||||
#define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c
|
||||
#define QSERDES_V4_COM_CORECLK_DIV_MODE1 0x16c
|
||||
@ -471,12 +473,14 @@
|
||||
#define QSERDES_V4_RX_UCDR_SB2_GAIN1 0x054
|
||||
#define QSERDES_V4_RX_UCDR_SB2_GAIN2 0x058
|
||||
#define QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE 0x060
|
||||
#define QSERDES_V4_RX_RCLK_AUXDATA_SEL 0x064
|
||||
#define QSERDES_V4_RX_AC_JTAG_ENABLE 0x068
|
||||
#define QSERDES_V4_RX_AC_JTAG_MODE 0x078
|
||||
#define QSERDES_V4_RX_RX_TERM_BW 0x080
|
||||
#define QSERDES_V4_RX_VGA_CAL_CNTRL1 0x0d4
|
||||
#define QSERDES_V4_RX_VGA_CAL_CNTRL2 0x0d8
|
||||
#define QSERDES_V4_RX_GM_CAL 0x0dc
|
||||
#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1 0x0e8
|
||||
#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2 0x0ec
|
||||
#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3 0x0f0
|
||||
#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4 0x0f4
|
||||
@ -485,6 +489,7 @@
|
||||
#define QSERDES_V4_RX_RX_IDAC_MEASURE_TIME 0x100
|
||||
#define QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
|
||||
#define QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114
|
||||
#define QSERDES_V4_RX_SIGDET_ENABLES 0x118
|
||||
#define QSERDES_V4_RX_SIGDET_CNTRL 0x11c
|
||||
#define QSERDES_V4_RX_SIGDET_LVL 0x120
|
||||
#define QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL 0x124
|
||||
@ -806,4 +811,17 @@
|
||||
#define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10
|
||||
#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14
|
||||
|
||||
/* Only for QMP V4 PHY - PCS_PCIE registers (same as PCS_MISC?) */
|
||||
#define QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
|
||||
#define QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4 0x14
|
||||
#define QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x1c
|
||||
#define QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x40
|
||||
#define QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x48
|
||||
#define QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x50
|
||||
#define QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS 0x90
|
||||
#define QPHY_V4_PCS_PCIE_EQ_CONFIG2 0xa4
|
||||
#define QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE 0xb4
|
||||
#define QPHY_V4_PCS_PCIE_PRESET_P10_PRE 0xbc
|
||||
#define QPHY_V4_PCS_PCIE_PRESET_P10_POST 0xe0
|
||||
|
||||
#endif
|
||||
|
@ -844,7 +844,6 @@ static int qusb2_phy_probe(struct platform_device *pdev)
|
||||
struct qusb2_phy *qphy;
|
||||
struct phy_provider *phy_provider;
|
||||
struct phy *generic_phy;
|
||||
struct resource *res;
|
||||
int ret, i;
|
||||
int num;
|
||||
u32 value;
|
||||
@ -855,8 +854,7 @@ static int qusb2_phy_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
or = &qphy->overrides;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
qphy->base = devm_ioremap_resource(dev, res);
|
||||
qphy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(qphy->base))
|
||||
return PTR_ERR(qphy->base);
|
||||
|
||||
|
@ -2,6 +2,14 @@
|
||||
#
|
||||
# PHY drivers for Ralink platforms.
|
||||
#
|
||||
config PHY_MT7621_PCI
|
||||
tristate "MediaTek MT7621 PCI PHY Driver"
|
||||
depends on RALINK && OF
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver,
|
||||
|
||||
config PHY_RALINK_USB
|
||||
tristate "Ralink USB PHY driver"
|
||||
depends on RALINK || COMPILE_TEST
|
||||
|
@ -1,2 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_PHY_MT7621_PCI) += phy-mt7621-pci.o
|
||||
obj-$(CONFIG_PHY_RALINK_USB) += phy-ralink-usb.o
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
@ -23,12 +24,10 @@
|
||||
#define RG_P0_TO_P1_WIDTH 0x100
|
||||
#define RG_PE1_H_LCDDS_REG 0x49c
|
||||
#define RG_PE1_H_LCDDS_PCW GENMASK(30, 0)
|
||||
#define RG_PE1_H_LCDDS_PCW_VAL(x) ((0x7fffffff & (x)) << 0)
|
||||
|
||||
#define RG_PE1_FRC_H_XTAL_REG 0x400
|
||||
#define RG_PE1_FRC_H_XTAL_TYPE BIT(8)
|
||||
#define RG_PE1_H_XTAL_TYPE GENMASK(10, 9)
|
||||
#define RG_PE1_H_XTAL_TYPE_VAL(x) ((0x3 & (x)) << 9)
|
||||
|
||||
#define RG_PE1_FRC_PHY_REG 0x000
|
||||
#define RG_PE1_FRC_PHY_EN BIT(4)
|
||||
@ -36,47 +35,34 @@
|
||||
|
||||
#define RG_PE1_H_PLL_REG 0x490
|
||||
#define RG_PE1_H_PLL_BC GENMASK(23, 22)
|
||||
#define RG_PE1_H_PLL_BC_VAL(x) ((0x3 & (x)) << 22)
|
||||
#define RG_PE1_H_PLL_BP GENMASK(21, 18)
|
||||
#define RG_PE1_H_PLL_BP_VAL(x) ((0xf & (x)) << 18)
|
||||
#define RG_PE1_H_PLL_IR GENMASK(15, 12)
|
||||
#define RG_PE1_H_PLL_IR_VAL(x) ((0xf & (x)) << 12)
|
||||
#define RG_PE1_H_PLL_IC GENMASK(11, 8)
|
||||
#define RG_PE1_H_PLL_IC_VAL(x) ((0xf & (x)) << 8)
|
||||
#define RG_PE1_H_PLL_PREDIV GENMASK(7, 6)
|
||||
#define RG_PE1_H_PLL_PREDIV_VAL(x) ((0x3 & (x)) << 6)
|
||||
#define RG_PE1_PLL_DIVEN GENMASK(3, 1)
|
||||
#define RG_PE1_PLL_DIVEN_VAL(x) ((0x7 & (x)) << 1)
|
||||
|
||||
#define RG_PE1_H_PLL_FBKSEL_REG 0x4bc
|
||||
#define RG_PE1_H_PLL_FBKSEL GENMASK(5, 4)
|
||||
#define RG_PE1_H_PLL_FBKSEL_VAL(x) ((0x3 & (x)) << 4)
|
||||
|
||||
#define RG_PE1_H_LCDDS_SSC_PRD_REG 0x4a4
|
||||
#define RG_PE1_H_LCDDS_SSC_PRD GENMASK(15, 0)
|
||||
#define RG_PE1_H_LCDDS_SSC_PRD_VAL(x) ((0xffff & (x)) << 0)
|
||||
|
||||
#define RG_PE1_H_LCDDS_SSC_DELTA_REG 0x4a8
|
||||
#define RG_PE1_H_LCDDS_SSC_DELTA GENMASK(11, 0)
|
||||
#define RG_PE1_H_LCDDS_SSC_DELTA_VAL(x) ((0xfff & (x)) << 0)
|
||||
#define RG_PE1_H_LCDDS_SSC_DELTA1 GENMASK(27, 16)
|
||||
#define RG_PE1_H_LCDDS_SSC_DELTA1_VAL(x) ((0xff & (x)) << 16)
|
||||
|
||||
#define RG_PE1_LCDDS_CLK_PH_INV_REG 0x4a0
|
||||
#define RG_PE1_LCDDS_CLK_PH_INV BIT(5)
|
||||
|
||||
#define RG_PE1_H_PLL_BR_REG 0x4ac
|
||||
#define RG_PE1_H_PLL_BR GENMASK(18, 16)
|
||||
#define RG_PE1_H_PLL_BR_VAL(x) ((0x7 & (x)) << 16)
|
||||
|
||||
#define RG_PE1_MSTCKDIV_REG 0x414
|
||||
#define RG_PE1_MSTCKDIV GENMASK(7, 6)
|
||||
#define RG_PE1_MSTCKDIV_VAL(x) ((0x3 & (x)) << 6)
|
||||
|
||||
#define RG_PE1_FRC_MSTCKDIV BIT(5)
|
||||
|
||||
#define XTAL_MODE_SEL_SHIFT 6
|
||||
#define XTAL_MODE_SEL_MASK 0x7
|
||||
#define XTAL_MASK GENMASK(7, 6)
|
||||
|
||||
#define MAX_PHYS 2
|
||||
|
||||
@ -99,28 +85,22 @@ struct mt7621_pci_phy {
|
||||
bool bypass_pipe_rst;
|
||||
};
|
||||
|
||||
static inline u32 phy_read(struct mt7621_pci_phy *phy, u32 reg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
regmap_read(phy->regmap, reg, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void phy_write(struct mt7621_pci_phy *phy, u32 val, u32 reg)
|
||||
{
|
||||
regmap_write(phy->regmap, reg, val);
|
||||
}
|
||||
|
||||
static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy,
|
||||
u32 reg, u32 clr, u32 set)
|
||||
{
|
||||
u32 val = phy_read(phy, reg);
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* We cannot use 'regmap_write_bits' here because internally
|
||||
* 'set' is masked before is set to the value that will be
|
||||
* written to the register. That way results in no reliable
|
||||
* pci setup. Avoid to mask 'set' before set value to 'val'
|
||||
* completely avoid the problem.
|
||||
*/
|
||||
regmap_read(phy->regmap, reg, &val);
|
||||
val &= ~clr;
|
||||
val |= set;
|
||||
phy_write(phy, val, reg);
|
||||
regmap_write(phy->regmap, reg, val);
|
||||
}
|
||||
|
||||
static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
|
||||
@ -141,18 +121,18 @@ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
struct device *dev = phy->dev;
|
||||
u32 xtal_mode;
|
||||
|
||||
xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0)
|
||||
>> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
|
||||
xtal_mode = FIELD_GET(XTAL_MASK, rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0));
|
||||
|
||||
/* Set PCIe Port PHY to disable SSC */
|
||||
/* Debug Xtal Type */
|
||||
mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
|
||||
RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE,
|
||||
RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
|
||||
RG_PE1_FRC_H_XTAL_TYPE |
|
||||
FIELD_PREP(RG_PE1_H_XTAL_TYPE, 0x00));
|
||||
|
||||
/* disable port */
|
||||
mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG,
|
||||
RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
|
||||
mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, RG_PE1_PHY_EN,
|
||||
RG_PE1_FRC_PHY_EN);
|
||||
|
||||
if (phy->has_dual_port) {
|
||||
mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
|
||||
@ -161,39 +141,42 @@ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
|
||||
if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
|
||||
/* Set Pre-divider ratio (for host mode) */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
|
||||
RG_PE1_H_PLL_PREDIV,
|
||||
RG_PE1_H_PLL_PREDIV_VAL(0x01));
|
||||
dev_info(dev, "Xtal is 40MHz\n");
|
||||
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 */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
|
||||
RG_PE1_H_PLL_PREDIV,
|
||||
RG_PE1_H_PLL_PREDIV_VAL(0x00));
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
|
||||
FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00));
|
||||
|
||||
/* Select feedback clock */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG,
|
||||
RG_PE1_H_PLL_FBKSEL,
|
||||
RG_PE1_H_PLL_FBKSEL_VAL(0x01));
|
||||
FIELD_PREP(RG_PE1_H_PLL_FBKSEL, 0x01));
|
||||
|
||||
/* DDS NCPO PCW (for host mode) */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
|
||||
RG_PE1_H_LCDDS_SSC_PRD,
|
||||
RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000));
|
||||
FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x00));
|
||||
|
||||
/* DDS SSC dither period control */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
|
||||
RG_PE1_H_LCDDS_SSC_PRD,
|
||||
RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d));
|
||||
FIELD_PREP(RG_PE1_H_LCDDS_SSC_PRD, 0x18d));
|
||||
|
||||
/* DDS SSC dither amplitude control */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG,
|
||||
RG_PE1_H_LCDDS_SSC_DELTA |
|
||||
RG_PE1_H_LCDDS_SSC_DELTA1,
|
||||
RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) |
|
||||
RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a));
|
||||
dev_info(dev, "Xtal is 25MHz\n");
|
||||
} else { /* 20MHz Xtal */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
|
||||
RG_PE1_H_PLL_PREDIV,
|
||||
RG_PE1_H_PLL_PREDIV_VAL(0x00));
|
||||
FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA, 0x4a) |
|
||||
FIELD_PREP(RG_PE1_H_LCDDS_SSC_DELTA1, 0x4a));
|
||||
|
||||
dev_info(dev, "Xtal is 20MHz\n");
|
||||
dev_dbg(dev, "Xtal is 25MHz\n");
|
||||
} else { /* 20MHz Xtal */
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, RG_PE1_H_PLL_PREDIV,
|
||||
FIELD_PREP(RG_PE1_H_PLL_PREDIV, 0x00));
|
||||
|
||||
dev_dbg(dev, "Xtal is 20MHz\n");
|
||||
}
|
||||
|
||||
/* DDS clock inversion */
|
||||
@ -204,18 +187,21 @@ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
|
||||
RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
|
||||
RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN,
|
||||
RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) |
|
||||
RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) |
|
||||
RG_PE1_PLL_DIVEN_VAL(0x02));
|
||||
FIELD_PREP(RG_PE1_H_PLL_BC, 0x02) |
|
||||
FIELD_PREP(RG_PE1_H_PLL_BP, 0x06) |
|
||||
FIELD_PREP(RG_PE1_H_PLL_IR, 0x02) |
|
||||
FIELD_PREP(RG_PE1_H_PLL_IC, 0x01) |
|
||||
FIELD_PREP(RG_PE1_PLL_DIVEN, 0x02));
|
||||
|
||||
mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
|
||||
RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
|
||||
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 */
|
||||
/* set force mode enable of da_pe1_mstckdiv */
|
||||
mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
|
||||
RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
|
||||
RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
|
||||
FIELD_PREP(RG_PE1_MSTCKDIV, 0x01) |
|
||||
RG_PE1_FRC_MSTCKDIV);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,7 +295,6 @@ static int mt7621_pci_phy_probe(struct platform_device *pdev)
|
||||
const struct soc_device_attribute *attr;
|
||||
struct phy_provider *provider;
|
||||
struct mt7621_pci_phy *phy;
|
||||
struct resource *res;
|
||||
|
||||
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
|
||||
if (!phy)
|
||||
@ -322,13 +307,7 @@ static int mt7621_pci_phy_probe(struct platform_device *pdev)
|
||||
phy->dev = dev;
|
||||
platform_set_drvdata(pdev, phy);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to get address resource\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
phy->port_base = devm_ioremap_resource(dev, res);
|
||||
phy->port_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->port_base)) {
|
||||
dev_err(dev, "failed to remap phy regs\n");
|
||||
return PTR_ERR(phy->port_base);
|
||||
@ -356,7 +335,7 @@ static const struct of_device_id mt7621_pci_phy_ids[] = {
|
||||
{ .compatible = "mediatek,mt7621-pci-phy" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt7621_pci_ids);
|
||||
MODULE_DEVICE_TABLE(of, mt7621_pci_phy_ids);
|
||||
|
||||
static struct platform_driver mt7621_pci_phy_driver = {
|
||||
.probe = mt7621_pci_phy_probe,
|
@ -170,7 +170,6 @@ MODULE_DEVICE_TABLE(of, ralink_usb_phy_of_match);
|
||||
static int ralink_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
const struct of_device_id *match;
|
||||
struct ralink_usb_phy *phy;
|
||||
@ -194,8 +193,7 @@ static int ralink_usb_phy_probe(struct platform_device *pdev)
|
||||
|
||||
/* The MT7628 and MT7688 require extra setup of PHY registers. */
|
||||
if (of_device_is_compatible(dev->of_node, "mediatek,mt7628-usbphy")) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->base)) {
|
||||
dev_err(dev, "failed to remap register memory\n");
|
||||
return PTR_ERR(phy->base);
|
||||
|
@ -339,7 +339,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
struct rcar_gen2_phy_driver *drv;
|
||||
struct phy_provider *provider;
|
||||
struct device_node *np;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
const struct rcar_gen2_phy_data *data;
|
||||
@ -357,8 +356,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -76,7 +76,6 @@ static int rcar_gen3_phy_pcie_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *provider;
|
||||
struct rcar_gen3_phy *phy;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int error;
|
||||
|
||||
@ -86,8 +85,7 @@ static int rcar_gen3_phy_pcie_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -611,7 +611,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rcar_gen3_chan *channel;
|
||||
struct phy_provider *provider;
|
||||
struct resource *res;
|
||||
const struct phy_ops *phy_usb2_ops;
|
||||
int ret = 0, i;
|
||||
|
||||
@ -624,8 +623,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
if (!channel)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
channel->base = devm_ioremap_resource(dev, res);
|
||||
channel->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(channel->base))
|
||||
return PTR_ERR(channel->base);
|
||||
|
||||
@ -656,8 +654,10 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
|
||||
*/
|
||||
pm_runtime_enable(dev);
|
||||
phy_usb2_ops = of_device_get_match_data(dev);
|
||||
if (!phy_usb2_ops)
|
||||
return -EINVAL;
|
||||
if (!phy_usb2_ops) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
mutex_init(&channel->lock);
|
||||
for (i = 0; i < NUM_OF_PHYS; i++) {
|
||||
|
@ -133,7 +133,6 @@ static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rcar_gen3_usb3 *r;
|
||||
struct phy_provider *provider;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
struct clk *clk;
|
||||
|
||||
@ -146,8 +145,7 @@ static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev)
|
||||
if (!r)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
r->base = devm_ioremap_resource(dev, res);
|
||||
r->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(r->base))
|
||||
return PTR_ERR(r->base);
|
||||
|
||||
|
@ -32,6 +32,7 @@ config PHY_ROCKCHIP_INNO_HDMI
|
||||
tristate "Rockchip INNO HDMI PHY Driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
depends on COMMON_CLK
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip Innosilicon HDMI PHY.
|
||||
|
@ -65,8 +65,14 @@
|
||||
#define PHYCTRL_OTAPDLYENA 0x1
|
||||
#define PHYCTRL_OTAPDLYENA_MASK 0x1
|
||||
#define PHYCTRL_OTAPDLYENA_SHIFT 0xb
|
||||
#define PHYCTRL_OTAPDLYSEL_DEFAULT 0x4
|
||||
#define PHYCTRL_OTAPDLYSEL_MAXVALUE 0xf
|
||||
#define PHYCTRL_OTAPDLYSEL_MASK 0xf
|
||||
#define PHYCTRL_OTAPDLYSEL_SHIFT 0x7
|
||||
#define PHYCTRL_REN_STRB_DISABLE 0x0
|
||||
#define PHYCTRL_REN_STRB_ENABLE 0x1
|
||||
#define PHYCTRL_REN_STRB_MASK 0x1
|
||||
#define PHYCTRL_REN_STRB_SHIFT 0x9
|
||||
|
||||
#define PHYCTRL_IS_CALDONE(x) \
|
||||
((((x) >> PHYCTRL_CALDONE_SHIFT) & \
|
||||
@ -80,6 +86,8 @@ struct rockchip_emmc_phy {
|
||||
struct regmap *reg_base;
|
||||
struct clk *emmcclk;
|
||||
unsigned int drive_impedance;
|
||||
unsigned int enable_strobe_pulldown;
|
||||
unsigned int output_tapdelay_select;
|
||||
};
|
||||
|
||||
static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
|
||||
@ -291,10 +299,17 @@ static int rockchip_emmc_phy_power_on(struct phy *phy)
|
||||
/* Output tap delay */
|
||||
regmap_write(rk_phy->reg_base,
|
||||
rk_phy->reg_offset + GRF_EMMCPHY_CON0,
|
||||
HIWORD_UPDATE(4,
|
||||
HIWORD_UPDATE(rk_phy->output_tapdelay_select,
|
||||
PHYCTRL_OTAPDLYSEL_MASK,
|
||||
PHYCTRL_OTAPDLYSEL_SHIFT));
|
||||
|
||||
/* Internal pull-down for strobe line */
|
||||
regmap_write(rk_phy->reg_base,
|
||||
rk_phy->reg_offset + GRF_EMMCPHY_CON2,
|
||||
HIWORD_UPDATE(rk_phy->enable_strobe_pulldown,
|
||||
PHYCTRL_REN_STRB_MASK,
|
||||
PHYCTRL_REN_STRB_SHIFT));
|
||||
|
||||
/* Power up emmc phy analog blocks */
|
||||
return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON);
|
||||
}
|
||||
@ -359,10 +374,22 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev)
|
||||
rk_phy->reg_offset = reg_offset;
|
||||
rk_phy->reg_base = grf;
|
||||
rk_phy->drive_impedance = PHYCTRL_DR_50OHM;
|
||||
rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_DISABLE;
|
||||
rk_phy->output_tapdelay_select = PHYCTRL_OTAPDLYSEL_DEFAULT;
|
||||
|
||||
if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val))
|
||||
rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val);
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "enable-strobe-pulldown"))
|
||||
rk_phy->enable_strobe_pulldown = PHYCTRL_REN_STRB_ENABLE;
|
||||
|
||||
if (!of_property_read_u32(dev->of_node, "output-tapdelay-select", &val)) {
|
||||
if (val <= PHYCTRL_OTAPDLYSEL_MAXVALUE)
|
||||
rk_phy->output_tapdelay_select = val;
|
||||
else
|
||||
dev_err(dev, "output-tapdelay-select exceeds limit, apply default\n");
|
||||
}
|
||||
|
||||
generic_phy = devm_phy_create(dev, dev->of_node, &ops);
|
||||
if (IS_ERR(generic_phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
|
@ -1144,7 +1144,6 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct inno_hdmi_phy *inno;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
void __iomem *regs;
|
||||
int ret;
|
||||
|
||||
@ -1158,8 +1157,7 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev)
|
||||
if (!inno->plat_data || !inno->plat_data->ops)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(inno->dev, res);
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@ -4,70 +4,41 @@
|
||||
*
|
||||
* Phy provider for PCIe controller on Exynos SoC series
|
||||
*
|
||||
* Copyright (C) 2017 Samsung Electronics Co., Ltd.
|
||||
* Copyright (C) 2017-2020 Samsung Electronics Co., Ltd.
|
||||
* Jaehoon Chung <jh80.chung@samsung.com>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* PCIe Purple registers */
|
||||
#define PCIE_PHY_GLOBAL_RESET 0x000
|
||||
#define PCIE_PHY_COMMON_RESET 0x004
|
||||
#define PCIE_PHY_CMN_REG 0x008
|
||||
#define PCIE_PHY_MAC_RESET 0x00c
|
||||
#define PCIE_PHY_PLL_LOCKED 0x010
|
||||
#define PCIE_PHY_TRSVREG_RESET 0x020
|
||||
#define PCIE_PHY_TRSV_RESET 0x024
|
||||
#define PCIE_PHY_OFFSET(x) ((x) * 0x4)
|
||||
|
||||
/* PCIe PHY registers */
|
||||
#define PCIE_PHY_IMPEDANCE 0x004
|
||||
#define PCIE_PHY_PLL_DIV_0 0x008
|
||||
#define PCIE_PHY_PLL_BIAS 0x00c
|
||||
#define PCIE_PHY_DCC_FEEDBACK 0x014
|
||||
#define PCIE_PHY_PLL_DIV_1 0x05c
|
||||
#define PCIE_PHY_COMMON_POWER 0x064
|
||||
#define PCIE_PHY_COMMON_PD_CMN BIT(3)
|
||||
#define PCIE_PHY_TRSV0_EMP_LVL 0x084
|
||||
#define PCIE_PHY_TRSV0_DRV_LVL 0x088
|
||||
#define PCIE_PHY_TRSV0_RXCDR 0x0ac
|
||||
#define PCIE_PHY_TRSV0_POWER 0x0c4
|
||||
#define PCIE_PHY_TRSV0_PD_TSV BIT(7)
|
||||
#define PCIE_PHY_TRSV0_LVCC 0x0dc
|
||||
#define PCIE_PHY_TRSV1_EMP_LVL 0x144
|
||||
#define PCIE_PHY_TRSV1_RXCDR 0x16c
|
||||
#define PCIE_PHY_TRSV1_POWER 0x184
|
||||
#define PCIE_PHY_TRSV1_PD_TSV BIT(7)
|
||||
#define PCIE_PHY_TRSV1_LVCC 0x19c
|
||||
#define PCIE_PHY_TRSV2_EMP_LVL 0x204
|
||||
#define PCIE_PHY_TRSV2_RXCDR 0x22c
|
||||
#define PCIE_PHY_TRSV2_POWER 0x244
|
||||
#define PCIE_PHY_TRSV2_PD_TSV BIT(7)
|
||||
#define PCIE_PHY_TRSV2_LVCC 0x25c
|
||||
#define PCIE_PHY_TRSV3_EMP_LVL 0x2c4
|
||||
#define PCIE_PHY_TRSV3_RXCDR 0x2ec
|
||||
#define PCIE_PHY_TRSV3_POWER 0x304
|
||||
#define PCIE_PHY_TRSV3_PD_TSV BIT(7)
|
||||
#define PCIE_PHY_TRSV3_LVCC 0x31c
|
||||
/* Sysreg FSYS register offsets and bits for Exynos5433 */
|
||||
#define PCIE_EXYNOS5433_PHY_MAC_RESET 0x0208
|
||||
#define PCIE_MAC_RESET_MASK 0xFF
|
||||
#define PCIE_MAC_RESET BIT(4)
|
||||
#define PCIE_EXYNOS5433_PHY_L1SUB_CM_CON 0x1010
|
||||
#define PCIE_REFCLK_GATING_EN BIT(0)
|
||||
#define PCIE_EXYNOS5433_PHY_COMMON_RESET 0x1020
|
||||
#define PCIE_PHY_RESET BIT(0)
|
||||
#define PCIE_EXYNOS5433_PHY_GLOBAL_RESET 0x1040
|
||||
#define PCIE_GLOBAL_RESET BIT(0)
|
||||
#define PCIE_REFCLK BIT(1)
|
||||
#define PCIE_REFCLK_MASK 0x16
|
||||
#define PCIE_APP_REQ_EXIT_L1_MODE BIT(5)
|
||||
|
||||
struct exynos_pcie_phy_data {
|
||||
const struct phy_ops *ops;
|
||||
};
|
||||
/* PMU PCIE PHY isolation control */
|
||||
#define EXYNOS5433_PMU_PCIE_PHY_OFFSET 0x730
|
||||
|
||||
/* For Exynos pcie phy */
|
||||
struct exynos_pcie_phy {
|
||||
const struct exynos_pcie_phy_data *drv_data;
|
||||
void __iomem *phy_base;
|
||||
void __iomem *blk_base; /* For exynos5440 */
|
||||
void __iomem *base;
|
||||
struct regmap *pmureg;
|
||||
struct regmap *fsysreg;
|
||||
};
|
||||
|
||||
static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset)
|
||||
@ -75,153 +46,103 @@ static void exynos_pcie_phy_writel(void __iomem *base, u32 val, u32 offset)
|
||||
writel(val, base + offset);
|
||||
}
|
||||
|
||||
static u32 exynos_pcie_phy_readl(void __iomem *base, u32 offset)
|
||||
{
|
||||
return readl(base + offset);
|
||||
}
|
||||
|
||||
/* For Exynos5440 specific functions */
|
||||
static int exynos5440_pcie_phy_init(struct phy *phy)
|
||||
/* Exynos5433 specific functions */
|
||||
static int exynos5433_pcie_phy_init(struct phy *phy)
|
||||
{
|
||||
struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
|
||||
|
||||
/* DCC feedback control off */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET,
|
||||
PCIE_PHY_RESET, 1);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET,
|
||||
PCIE_MAC_RESET, 0);
|
||||
|
||||
/* set TX/RX impedance */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0xd5, PCIE_PHY_IMPEDANCE);
|
||||
/* PHY refclk 24MHz */
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET,
|
||||
PCIE_REFCLK_MASK, PCIE_REFCLK);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET,
|
||||
PCIE_GLOBAL_RESET, 0);
|
||||
|
||||
/* set 50Mhz PHY clock */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x14, PCIE_PHY_PLL_DIV_0);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x12, PCIE_PHY_PLL_DIV_1);
|
||||
|
||||
/* set TX Differential output for lane 0 */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL);
|
||||
exynos_pcie_phy_writel(ep->base, 0x11, PCIE_PHY_OFFSET(0x3));
|
||||
|
||||
/* set TX Pre-emphasis Level Control for lane 0 to minimum */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL);
|
||||
/* band gap reference on */
|
||||
exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x20));
|
||||
exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x4b));
|
||||
|
||||
/* set RX clock and data recovery bandwidth */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0xe7, PCIE_PHY_PLL_BIAS);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR);
|
||||
/* jitter tuning */
|
||||
exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x4));
|
||||
exynos_pcie_phy_writel(ep->base, 0x02, PCIE_PHY_OFFSET(0x7));
|
||||
exynos_pcie_phy_writel(ep->base, 0x41, PCIE_PHY_OFFSET(0x21));
|
||||
exynos_pcie_phy_writel(ep->base, 0x7F, PCIE_PHY_OFFSET(0x14));
|
||||
exynos_pcie_phy_writel(ep->base, 0xC0, PCIE_PHY_OFFSET(0x15));
|
||||
exynos_pcie_phy_writel(ep->base, 0x61, PCIE_PHY_OFFSET(0x36));
|
||||
|
||||
/* change TX Pre-emphasis Level Control for lanes */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL);
|
||||
/* D0 uninit.. */
|
||||
exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x3D));
|
||||
|
||||
/* set LVCC */
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC);
|
||||
exynos_pcie_phy_writel(ep->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC);
|
||||
/* 24MHz */
|
||||
exynos_pcie_phy_writel(ep->base, 0x94, PCIE_PHY_OFFSET(0x8));
|
||||
exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x9));
|
||||
exynos_pcie_phy_writel(ep->base, 0x93, PCIE_PHY_OFFSET(0xA));
|
||||
exynos_pcie_phy_writel(ep->base, 0x6B, PCIE_PHY_OFFSET(0xC));
|
||||
exynos_pcie_phy_writel(ep->base, 0xA5, PCIE_PHY_OFFSET(0xF));
|
||||
exynos_pcie_phy_writel(ep->base, 0x34, PCIE_PHY_OFFSET(0x16));
|
||||
exynos_pcie_phy_writel(ep->base, 0xA3, PCIE_PHY_OFFSET(0x17));
|
||||
exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x1A));
|
||||
exynos_pcie_phy_writel(ep->base, 0x71, PCIE_PHY_OFFSET(0x23));
|
||||
exynos_pcie_phy_writel(ep->base, 0x4C, PCIE_PHY_OFFSET(0x24));
|
||||
|
||||
/* pulse for common reset */
|
||||
exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_COMMON_RESET);
|
||||
udelay(500);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET);
|
||||
exynos_pcie_phy_writel(ep->base, 0x0E, PCIE_PHY_OFFSET(0x26));
|
||||
exynos_pcie_phy_writel(ep->base, 0x14, PCIE_PHY_OFFSET(0x7));
|
||||
exynos_pcie_phy_writel(ep->base, 0x48, PCIE_PHY_OFFSET(0x43));
|
||||
exynos_pcie_phy_writel(ep->base, 0x44, PCIE_PHY_OFFSET(0x44));
|
||||
exynos_pcie_phy_writel(ep->base, 0x03, PCIE_PHY_OFFSET(0x45));
|
||||
exynos_pcie_phy_writel(ep->base, 0xA7, PCIE_PHY_OFFSET(0x48));
|
||||
exynos_pcie_phy_writel(ep->base, 0x13, PCIE_PHY_OFFSET(0x54));
|
||||
exynos_pcie_phy_writel(ep->base, 0x04, PCIE_PHY_OFFSET(0x31));
|
||||
exynos_pcie_phy_writel(ep->base, 0, PCIE_PHY_OFFSET(0x32));
|
||||
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_COMMON_RESET,
|
||||
PCIE_PHY_RESET, 0);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_MAC_RESET,
|
||||
PCIE_MAC_RESET_MASK, PCIE_MAC_RESET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos5440_pcie_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_COMMON_RESET);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_CMN_REG);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSVREG_RESET);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_TRSV_RESET);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER);
|
||||
val &= ~PCIE_PHY_COMMON_PD_CMN;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER);
|
||||
val &= ~PCIE_PHY_TRSV0_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER);
|
||||
val &= ~PCIE_PHY_TRSV1_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER);
|
||||
val &= ~PCIE_PHY_TRSV2_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER);
|
||||
val &= ~PCIE_PHY_TRSV3_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos5440_pcie_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
|
||||
if (readl_poll_timeout(ep->phy_base + PCIE_PHY_PLL_LOCKED, val,
|
||||
(val != 0), 1, 500)) {
|
||||
dev_err(&phy->dev, "PLL Locked: 0x%x\n", val);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_COMMON_POWER);
|
||||
val |= PCIE_PHY_COMMON_PD_CMN;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_COMMON_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV0_POWER);
|
||||
val |= PCIE_PHY_TRSV0_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV0_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV1_POWER);
|
||||
val |= PCIE_PHY_TRSV1_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV1_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV2_POWER);
|
||||
val |= PCIE_PHY_TRSV2_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV2_POWER);
|
||||
|
||||
val = exynos_pcie_phy_readl(ep->phy_base, PCIE_PHY_TRSV3_POWER);
|
||||
val |= PCIE_PHY_TRSV3_PD_TSV;
|
||||
exynos_pcie_phy_writel(ep->phy_base, val, PCIE_PHY_TRSV3_POWER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos5440_pcie_phy_reset(struct phy *phy)
|
||||
static int exynos5433_pcie_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
|
||||
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_MAC_RESET);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 1, PCIE_PHY_GLOBAL_RESET);
|
||||
exynos_pcie_phy_writel(ep->blk_base, 0, PCIE_PHY_GLOBAL_RESET);
|
||||
|
||||
regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET,
|
||||
BIT(0), 1);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_GLOBAL_RESET,
|
||||
PCIE_APP_REQ_EXIT_L1_MODE, 0);
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON,
|
||||
PCIE_REFCLK_GATING_EN, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops exynos5440_phy_ops = {
|
||||
.init = exynos5440_pcie_phy_init,
|
||||
.power_on = exynos5440_pcie_phy_power_on,
|
||||
.power_off = exynos5440_pcie_phy_power_off,
|
||||
.reset = exynos5440_pcie_phy_reset,
|
||||
static int exynos5433_pcie_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct exynos_pcie_phy *ep = phy_get_drvdata(phy);
|
||||
|
||||
regmap_update_bits(ep->fsysreg, PCIE_EXYNOS5433_PHY_L1SUB_CM_CON,
|
||||
PCIE_REFCLK_GATING_EN, PCIE_REFCLK_GATING_EN);
|
||||
regmap_update_bits(ep->pmureg, EXYNOS5433_PMU_PCIE_PHY_OFFSET,
|
||||
BIT(0), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops exynos5433_phy_ops = {
|
||||
.init = exynos5433_pcie_phy_init,
|
||||
.power_on = exynos5433_pcie_phy_power_on,
|
||||
.power_off = exynos5433_pcie_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct exynos_pcie_phy_data exynos5440_pcie_phy_data = {
|
||||
.ops = &exynos5440_phy_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id exynos_pcie_phy_match[] = {
|
||||
{
|
||||
.compatible = "samsung,exynos5440-pcie-phy",
|
||||
.data = &exynos5440_pcie_phy_data,
|
||||
.compatible = "samsung,exynos5433-pcie-phy",
|
||||
},
|
||||
{},
|
||||
};
|
||||
@ -232,30 +153,30 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
|
||||
struct exynos_pcie_phy *exynos_phy;
|
||||
struct phy *generic_phy;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
const struct exynos_pcie_phy_data *drv_data;
|
||||
|
||||
drv_data = of_device_get_match_data(dev);
|
||||
if (!drv_data)
|
||||
return -ENODEV;
|
||||
|
||||
exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL);
|
||||
if (!exynos_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
exynos_phy->phy_base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(exynos_phy->phy_base))
|
||||
return PTR_ERR(exynos_phy->phy_base);
|
||||
exynos_phy->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(exynos_phy->base))
|
||||
return PTR_ERR(exynos_phy->base);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
exynos_phy->blk_base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(exynos_phy->blk_base))
|
||||
return PTR_ERR(exynos_phy->blk_base);
|
||||
exynos_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"samsung,pmu-syscon");
|
||||
if (IS_ERR(exynos_phy->pmureg)) {
|
||||
dev_err(&pdev->dev, "PMU regmap lookup failed.\n");
|
||||
return PTR_ERR(exynos_phy->pmureg);
|
||||
}
|
||||
|
||||
exynos_phy->drv_data = drv_data;
|
||||
exynos_phy->fsysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"samsung,fsys-sysreg");
|
||||
if (IS_ERR(exynos_phy->fsysreg)) {
|
||||
dev_err(&pdev->dev, "FSYS sysreg regmap lookup failed.\n");
|
||||
return PTR_ERR(exynos_phy->fsysreg);
|
||||
}
|
||||
|
||||
generic_phy = devm_phy_create(dev, dev->of_node, drv_data->ops);
|
||||
generic_phy = devm_phy_create(dev, dev->of_node, &exynos5433_phy_ops);
|
||||
if (IS_ERR(generic_phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
return PTR_ERR(generic_phy);
|
||||
@ -275,5 +196,4 @@ static struct platform_driver exynos_pcie_phy_driver = {
|
||||
.suppress_bind_attrs = true,
|
||||
}
|
||||
};
|
||||
|
||||
builtin_platform_driver(exynos_pcie_phy_driver);
|
||||
|
@ -829,7 +829,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
|
||||
struct device_node *node = dev->of_node;
|
||||
struct exynos5_usbdrd_phy *phy_drd;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
const struct exynos5_usbdrd_phy_drvdata *drv_data;
|
||||
struct regmap *reg_pmu;
|
||||
u32 pmu_offset;
|
||||
@ -843,8 +842,7 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
|
||||
dev_set_drvdata(dev, phy_drd);
|
||||
phy_drd->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy_drd->reg_phy = devm_ioremap_resource(dev, res);
|
||||
phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy_drd->reg_phy))
|
||||
return PTR_ERR(phy_drd->reg_phy);
|
||||
|
||||
|
@ -162,7 +162,6 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos_sata_phy *sata_phy;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device_node *node;
|
||||
int ret = 0;
|
||||
@ -171,9 +170,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
|
||||
if (!sata_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
sata_phy->regs = devm_ioremap_resource(dev, res);
|
||||
sata_phy->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(sata_phy->regs))
|
||||
return PTR_ERR(sata_phy->regs);
|
||||
|
||||
|
@ -117,9 +117,9 @@
|
||||
|
||||
/* Isolation, configured in the power management unit */
|
||||
#define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704
|
||||
#define EXYNOS_5250_USB_ISOL_OTG BIT(0)
|
||||
#define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708
|
||||
#define EXYNOS_5250_USB_ISOL_HOST BIT(0)
|
||||
#define EXYNOS_5420_USB_ISOL_HOST_OFFSET 0x70C
|
||||
#define EXYNOS_5250_USB_ISOL_ENABLE BIT(0)
|
||||
|
||||
/* Mode swtich register */
|
||||
#define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230
|
||||
@ -132,7 +132,6 @@ enum exynos4x12_phy_id {
|
||||
EXYNOS5250_HOST,
|
||||
EXYNOS5250_HSIC0,
|
||||
EXYNOS5250_HSIC1,
|
||||
EXYNOS5250_NUM_PHYS,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -176,20 +175,19 @@ static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on)
|
||||
{
|
||||
struct samsung_usb2_phy_driver *drv = inst->drv;
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 mask = EXYNOS_5250_USB_ISOL_ENABLE;
|
||||
|
||||
switch (inst->cfg->id) {
|
||||
case EXYNOS5250_DEVICE:
|
||||
if (drv->cfg == &exynos5250_usb2_phy_config &&
|
||||
inst->cfg->id == EXYNOS5250_DEVICE)
|
||||
offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET;
|
||||
mask = EXYNOS_5250_USB_ISOL_OTG;
|
||||
break;
|
||||
case EXYNOS5250_HOST:
|
||||
else if (drv->cfg == &exynos5250_usb2_phy_config &&
|
||||
inst->cfg->id == EXYNOS5250_HOST)
|
||||
offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET;
|
||||
mask = EXYNOS_5250_USB_ISOL_HOST;
|
||||
break;
|
||||
default:
|
||||
else if (drv->cfg == &exynos5420_usb2_phy_config &&
|
||||
inst->cfg->id == EXYNOS5250_HOST)
|
||||
offset = EXYNOS_5420_USB_ISOL_HOST_OFFSET;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask);
|
||||
}
|
||||
@ -390,9 +388,31 @@ static const struct samsung_usb2_common_phy exynos5250_phys[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct samsung_usb2_common_phy exynos5420_phys[] = {
|
||||
{
|
||||
.label = "host",
|
||||
.id = EXYNOS5250_HOST,
|
||||
.power_on = exynos5250_power_on,
|
||||
.power_off = exynos5250_power_off,
|
||||
},
|
||||
{
|
||||
.label = "hsic",
|
||||
.id = EXYNOS5250_HSIC0,
|
||||
.power_on = exynos5250_power_on,
|
||||
.power_off = exynos5250_power_off,
|
||||
},
|
||||
};
|
||||
|
||||
const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = {
|
||||
.has_mode_switch = 1,
|
||||
.num_phys = EXYNOS5250_NUM_PHYS,
|
||||
.num_phys = ARRAY_SIZE(exynos5250_phys),
|
||||
.phys = exynos5250_phys,
|
||||
.rate_to_clk = exynos5250_rate_to_clk,
|
||||
};
|
||||
|
||||
const struct samsung_usb2_phy_config exynos5420_usb2_phy_config = {
|
||||
.has_mode_switch = 1,
|
||||
.num_phys = ARRAY_SIZE(exynos5420_phys),
|
||||
.phys = exynos5420_phys,
|
||||
.rate_to_clk = exynos5250_rate_to_clk,
|
||||
};
|
||||
|
@ -127,6 +127,10 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = {
|
||||
.compatible = "samsung,exynos5250-usb2-phy",
|
||||
.data = &exynos5250_usb2_phy_config,
|
||||
},
|
||||
{
|
||||
.compatible = "samsung,exynos5420-usb2-phy",
|
||||
.data = &exynos5420_usb2_phy_config,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PHY_S5PV210_USB2
|
||||
{
|
||||
@ -143,7 +147,6 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
|
||||
const struct samsung_usb2_phy_config *cfg;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *mem;
|
||||
struct samsung_usb2_phy_driver *drv;
|
||||
int i, ret;
|
||||
|
||||
@ -167,8 +170,7 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
|
||||
drv->cfg = cfg;
|
||||
drv->dev = dev;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
drv->reg_phy = devm_ioremap_resource(dev, mem);
|
||||
drv->reg_phy = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(drv->reg_phy)) {
|
||||
dev_err(dev, "Failed to map register memory (phy)\n");
|
||||
return PTR_ERR(drv->reg_phy);
|
||||
|
@ -66,5 +66,6 @@ extern const struct samsung_usb2_phy_config exynos3250_usb2_phy_config;
|
||||
extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config;
|
||||
extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config;
|
||||
extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config;
|
||||
extern const struct samsung_usb2_phy_config exynos5420_usb2_phy_config;
|
||||
extern const struct samsung_usb2_phy_config s5pv210_usb2_phy_config;
|
||||
#endif
|
||||
|
@ -311,7 +311,6 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
|
||||
struct stm32_usbphyc *usbphyc;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *child, *np = dev->of_node;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
u32 version;
|
||||
int ret, port = 0;
|
||||
@ -322,17 +321,13 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
|
||||
usbphyc->dev = dev;
|
||||
dev_set_drvdata(dev, usbphyc);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
usbphyc->base = devm_ioremap_resource(dev, res);
|
||||
usbphyc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(usbphyc->base))
|
||||
return PTR_ERR(usbphyc->base);
|
||||
|
||||
usbphyc->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(usbphyc->clk)) {
|
||||
ret = PTR_ERR(usbphyc->clk);
|
||||
dev_err(dev, "clk get failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(usbphyc->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(usbphyc->clk), "clk get_failed\n");
|
||||
|
||||
ret = clk_prepare_enable(usbphyc->clk);
|
||||
if (ret) {
|
||||
@ -345,6 +340,10 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
|
||||
reset_control_assert(usbphyc->rst);
|
||||
udelay(2);
|
||||
reset_control_deassert(usbphyc->rst);
|
||||
} else {
|
||||
ret = PTR_ERR(usbphyc->rst);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
usbphyc->switch_setup = -EINVAL;
|
||||
|
@ -72,14 +72,12 @@ static int tegra_p2u_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy *generic_phy;
|
||||
struct tegra_p2u *phy;
|
||||
struct resource *res;
|
||||
|
||||
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctl");
|
||||
phy->base = devm_ioremap_resource(dev, res);
|
||||
phy->base = devm_platform_ioremap_resource_byname(pdev, "ctl");
|
||||
if (IS_ERR(phy->base))
|
||||
return PTR_ERR(phy->base);
|
||||
|
||||
|
@ -146,7 +146,7 @@ static void tegra_xusb_pad_release(struct device *dev)
|
||||
pad->soc->ops->remove(pad);
|
||||
}
|
||||
|
||||
static struct device_type tegra_xusb_pad_type = {
|
||||
static const struct device_type tegra_xusb_pad_type = {
|
||||
.release = tegra_xusb_pad_release,
|
||||
};
|
||||
|
||||
@ -513,7 +513,7 @@ static void tegra_xusb_port_release(struct device *dev)
|
||||
port->ops->release(port);
|
||||
}
|
||||
|
||||
static struct device_type tegra_xusb_port_type = {
|
||||
static const struct device_type tegra_xusb_port_type = {
|
||||
.release = tegra_xusb_port_release,
|
||||
};
|
||||
|
||||
@ -688,7 +688,7 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
|
||||
* reference to retrieve usb-phy details.
|
||||
*/
|
||||
port->usb_phy.dev = &lane->pad->lanes[port->index]->dev;
|
||||
port->usb_phy.dev->driver = port->padctl->dev->driver;
|
||||
port->usb_phy.dev->driver = port->dev.driver;
|
||||
port->usb_phy.otg->usb_phy = &port->usb_phy;
|
||||
port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral;
|
||||
port->usb_phy.otg->set_host = tegra_xusb_set_host;
|
||||
@ -1148,7 +1148,6 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
|
||||
const struct tegra_xusb_padctl_soc *soc;
|
||||
struct tegra_xusb_padctl *padctl;
|
||||
const struct of_device_id *match;
|
||||
struct resource *res;
|
||||
int err;
|
||||
|
||||
/* for backwards compatibility with old device trees */
|
||||
@ -1173,8 +1172,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
|
||||
INIT_LIST_HEAD(&padctl->pads);
|
||||
mutex_init(&padctl->lock);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
padctl->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
padctl->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(padctl->regs)) {
|
||||
err = PTR_ERR(padctl->regs);
|
||||
goto remove;
|
||||
@ -1200,7 +1198,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
|
||||
err = devm_regulator_bulk_get(&pdev->dev, padctl->soc->num_supplies,
|
||||
padctl->supplies);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to get regulators: %d\n", err);
|
||||
dev_err_probe(&pdev->dev, err, "failed to get regulators\n");
|
||||
goto remove;
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(of, omap_control_phy_id_table);
|
||||
|
||||
static int omap_control_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
const struct of_device_id *of_id;
|
||||
struct omap_control_phy *control_phy;
|
||||
|
||||
@ -285,16 +284,13 @@ static int omap_control_phy_probe(struct platform_device *pdev)
|
||||
control_phy->type = *(enum omap_control_phy_type *)of_id->data;
|
||||
|
||||
if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"otghs_control");
|
||||
control_phy->otghs_control = devm_ioremap_resource(
|
||||
&pdev->dev, res);
|
||||
control_phy->otghs_control =
|
||||
devm_platform_ioremap_resource_byname(pdev, "otghs_control");
|
||||
if (IS_ERR(control_phy->otghs_control))
|
||||
return PTR_ERR(control_phy->otghs_control);
|
||||
} else {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"power");
|
||||
control_phy->power = devm_ioremap_resource(&pdev->dev, res);
|
||||
control_phy->power =
|
||||
devm_platform_ioremap_resource_byname(pdev, "power");
|
||||
if (IS_ERR(control_phy->power)) {
|
||||
dev_err(&pdev->dev, "Couldn't get power register\n");
|
||||
return PTR_ERR(control_phy->power);
|
||||
@ -312,9 +308,8 @@ static int omap_control_phy_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (control_phy->type == OMAP_CTRL_TYPE_PCIE) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"pcie_pcs");
|
||||
control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res);
|
||||
control_phy->pcie_pcs =
|
||||
devm_platform_ioremap_resource_byname(pdev, "pcie_pcs");
|
||||
if (IS_ERR(control_phy->pcie_pcs))
|
||||
return PTR_ERR(control_phy->pcie_pcs);
|
||||
}
|
||||
|
@ -366,7 +366,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_usb *phy;
|
||||
struct phy *generic_phy;
|
||||
struct resource *res;
|
||||
struct phy_provider *phy_provider;
|
||||
struct usb_otg *otg;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
@ -403,8 +402,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
||||
|
||||
omap_usb2_init_errata(phy);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
phy->phy_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(phy->phy_base))
|
||||
return PTR_ERR(phy->phy_base);
|
||||
|
||||
|
@ -745,35 +745,28 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
|
||||
|
||||
static int ti_pipe3_get_tx_rx_base(struct ti_pipe3 *phy)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device *dev = phy->dev;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy_rx");
|
||||
phy->phy_rx = devm_ioremap_resource(dev, res);
|
||||
phy->phy_rx = devm_platform_ioremap_resource_byname(pdev, "phy_rx");
|
||||
if (IS_ERR(phy->phy_rx))
|
||||
return PTR_ERR(phy->phy_rx);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy_tx");
|
||||
phy->phy_tx = devm_ioremap_resource(dev, res);
|
||||
phy->phy_tx = devm_platform_ioremap_resource_byname(pdev, "phy_tx");
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy->phy_tx);
|
||||
}
|
||||
|
||||
static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device *dev = phy->dev;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
if (phy->mode == PIPE3_MODE_PCIE)
|
||||
return 0;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"pll_ctrl");
|
||||
phy->pll_ctrl_base = devm_ioremap_resource(dev, res);
|
||||
phy->pll_ctrl_base =
|
||||
devm_platform_ioremap_resource_byname(pdev, "pll_ctrl");
|
||||
return PTR_ERR_OR_ZERO(phy->pll_ctrl_base);
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,6 @@ source "drivers/staging/pi433/Kconfig"
|
||||
|
||||
source "drivers/staging/mt7621-pci/Kconfig"
|
||||
|
||||
source "drivers/staging/mt7621-pci-phy/Kconfig"
|
||||
|
||||
source "drivers/staging/mt7621-pinctrl/Kconfig"
|
||||
|
||||
source "drivers/staging/mt7621-dma/Kconfig"
|
||||
|
@ -37,7 +37,6 @@ obj-$(CONFIG_GREYBUS) += greybus/
|
||||
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
|
||||
obj-$(CONFIG_PI433) += pi433/
|
||||
obj-$(CONFIG_PCI_MT7621) += mt7621-pci/
|
||||
obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/
|
||||
obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/
|
||||
obj-$(CONFIG_SOC_MT7621) += mt7621-dma/
|
||||
obj-$(CONFIG_DMA_RALINK) += ralink-gdma/
|
||||
|
@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config PCI_MT7621_PHY
|
||||
tristate "MediaTek MT7621 PCI PHY Driver"
|
||||
depends on RALINK && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Say 'Y' here to add support for MediaTek MT7621 PCI PHY driver,
|
||||
|
@ -1,2 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PCI_MT7621_PHY) += pci-mt7621-phy.o
|
@ -1,4 +0,0 @@
|
||||
|
||||
- general code review and cleanup
|
||||
|
||||
Cc: NeilBrown <neil@brown.name> and Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user