1
0
Fork 0

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()
  ...
zero-sugar-mainline-defconfig
Greg Kroah-Hartman 2020-12-09 14:26:40 +01:00
commit 54bf54c859
101 changed files with 2659 additions and 944 deletions

View File

@ -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

View File

@ -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>;
};

View File

@ -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>;
};

View 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>;
};
};

View File

@ -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>;
};
};

View File

@ -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

View File

@ -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>;
};

View File

@ -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>;
};

View File

@ -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#"

View File

@ -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>;
};

View 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>;
};
};
};

View File

@ -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 = <&reg11>;
vdda1v8-supply = <&reg18>
#phy-cells = <0>;
};
usbphyc_port1: usb-phy@1 {
reg = <1>;
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>
#phy-cells = <1>;
};
};

View 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 = <&reg11>;
vdda1v8-supply = <&reg18>;
#phy-cells = <0>;
};
usbphyc_port1: usb-phy@1 {
reg = <1>;
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
vdda1v8-supply = <&reg18>;
#phy-cells = <1>;
};
};
...

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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>

View File

@ -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"

View File

@ -15,6 +15,7 @@ obj-y += allwinner/ \
cadence/ \
freescale/ \
hisilicon/ \
ingenic/ \
intel/ \
lantiq/ \
marvell/ \

View File

@ -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),
};

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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

View 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");

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View 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.

View File

@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += phy-ingenic-usb.o

View 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(&reg, 1, USBPCR_USB_MODE);
u32p_replace_bits(&reg, 0, USBPCR_VBUSVLDEXT);
u32p_replace_bits(&reg, 0, USBPCR_VBUSVLDEXTSEL);
u32p_replace_bits(&reg, 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(&reg, 0, USBPCR_USB_MODE);
u32p_replace_bits(&reg, 1, USBPCR_VBUSVLDEXT);
u32p_replace_bits(&reg, 1, USBPCR_VBUSVLDEXTSEL);
u32p_replace_bits(&reg, 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(&reg, 1, USBPCR_USB_MODE);
u32p_replace_bits(&reg, 1, USBPCR_VBUSVLDEXT);
u32p_replace_bits(&reg, 1, USBPCR_VBUSVLDEXTSEL);
u32p_replace_bits(&reg, 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");

View File

@ -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

View File

@ -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

View 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");

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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);

View 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");

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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",

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,
},
{ },
};

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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++) {

View File

@ -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);

View File

@ -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.

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,
};

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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"

View File

@ -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/

View File

@ -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,

View File

@ -1,2 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PCI_MT7621_PHY) += pci-mt7621-phy.o

View File

@ -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