Commit 21bdb3b0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'phy-for-4.13' of...

Merge tag 'phy-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next

Kishon writes:

phy: for 4.13

 *) Group phy drivers into vendor specific directories
 *) Add USB3 PHY driver for Renesas R-Car Gen3
 *) Add USB2 PHY driver for Meson GXL and GXM SoCs
 *) Add USB DRD PHY driver for Broadcom Northstar2
 *) Add USB PHY driver for CPCAP PMIC USB
 *) Make phy-meson8b-usb2 driver support USB PHY on Meson8
 *) Make phy-tusb1210 driver support TUSB1211
 *) Make phy-rockchip-inno-usb2 driver support usb2-phy in rk3228 SoCs
 *) Make phy-brcm-sata driver support for stingray SATA phy
 *) Make bcm-ns-usb3 as a MDIO driver
 *) Make rockchip-inno-usb2 support two host ports
 *) Implement ->set_mode() callback in phy-tusb1210
 *) Minor fixes in phy drivers
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parents 3134bc9c af850e14
......@@ -3,9 +3,10 @@ Driver for Broadcom Northstar USB 3.0 PHY
Required properties:
- compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy".
- reg: register mappings for DMP (Device Management Plugin) and ChipCommon B
MMI.
- reg-names: "dmp" and "ccb-mii"
- reg: address of MDIO bus device
- usb3-dmp-syscon: phandle to syscon with DMP (Device Management Plugin)
registers
- #phy-cells: must be 0
Initialization of USB 3.0 PHY depends on Northstar version. There are currently
three known series: Ax, Bx and Cx.
......@@ -15,9 +16,19 @@ Known B1: BCM4707 rev 6
Known C0: BCM47094 rev 0
Example:
usb3-phy {
compatible = "brcm,ns-ax-usb3-phy";
reg = <0x18105000 0x1000>, <0x18003000 0x1000>;
reg-names = "dmp", "ccb-mii";
#phy-cells = <0>;
mdio: mdio@0 {
reg = <0x0>;
#size-cells = <1>;
#address-cells = <0>;
usb3-phy@10 {
compatible = "brcm,ns-ax-usb3-phy";
reg = <0x10>;
usb3-dmp-syscon = <&usb3_dmp>;
#phy-cells = <0>;
};
};
usb3_dmp: syscon@18105000 {
reg = <0x18105000 0x1000>;
};
BROADCOM NORTHSTAR2 USB2 (DUAL ROLE DEVICE) PHY
Required properties:
- compatible: brcm,ns2-drd-phy
- reg: offset and length of the NS2 PHY related registers.
- reg-names
The below registers must be provided.
icfg - for DRD ICFG configurations
rst-ctrl - for DRD IDM reset
crmu-ctrl - for CRMU core vdd, PHY and PHY PLL reset
usb2-strap - for port over current polarity reversal
- #phy-cells: Must be 0. No args required.
- vbus-gpios: vbus gpio binding
- id-gpios: id gpio binding
Refer to phy/phy-bindings.txt for the generic PHY binding properties
Example:
usbdrd_phy: phy@66000960 {
#phy-cells = <0>;
compatible = "brcm,ns2-drd-phy";
reg = <0x66000960 0x24>,
<0x67012800 0x4>,
<0x6501d148 0x4>,
<0x664d0700 0x4>;
reg-names = "icfg", "rst-ctrl",
"crmu-ctrl", "usb2-strap";
id-gpios = <&gpio_g 30 0>;
vbus-gpios = <&gpio_g 31 0>;
};
......@@ -7,12 +7,13 @@ Required properties:
"brcm,iproc-ns2-sata-phy"
"brcm,iproc-nsp-sata-phy"
"brcm,phy-sata3"
"brcm,iproc-sr-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".
"brcm,iproc-ns2-sata-phy" and "brcm,iproc-sr-sata-phy".
Sub-nodes:
Each port's PHY should be represented as a sub-node.
......@@ -23,8 +24,8 @@ Sub-nodes required properties:
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" and
"brcm,iproc-nsp-sata-phy".
This property is not applicable for "brcm,iproc-ns2-sata-phy",
"brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy".
Example:
sata-phy@f0458100 {
......
* Amlogic Meson GXL and GXM USB2 PHY binding
Required properties:
- compatible: Should be "amlogic,meson-gxl-usb2-phy"
- reg: The base address and length of the registers
- #phys-cells: must be 0 (see phy-bindings.txt in this directory)
Optional properties:
- phy-supply: see phy-bindings.txt in this directory
Example:
usb2_phy0: phy@78000 {
compatible = "amlogic,meson-gxl-usb2-phy";
#phy-cells = <0>;
reg = <0x0 0x78000 0x0 0x20>;
};
* Amlogic Meson8b and GXBB USB2 PHY
* Amlogic Meson8, Meson8b and GXBB USB2 PHY
Required properties:
- compatible: Depending on the platform this should be one of:
"amlogic,meson8-usb2-phy"
"amlogic,meson8b-usb2-phy"
"amlogic,meson-gxbb-usb2-phy"
- reg: The base address and length of the registers
......
Motorola CPCAP PMIC USB PHY binding
Required properties:
compatible: Shall be either "motorola,cpcap-usb-phy" or
"motorola,mapphone-cpcap-usb-phy"
#phy-cells: Shall be 0
interrupts: CPCAP PMIC interrupts used by the USB PHY
interrupt-names: Interrupt names
io-channels: IIO ADC channels used by the USB PHY
io-channel-names: IIO ADC channel names
vusb-supply: Regulator for the PHY
Optional properties:
pinctrl: Optional alternate pin modes for the PHY
pinctrl-names: Names for optional pin modes
mode-gpios: Optional GPIOs for configuring alternate modes
Example:
cpcap_usb2_phy: phy {
compatible = "motorola,mapphone-cpcap-usb-phy";
pinctrl-0 = <&usb_gpio_mux_sel1 &usb_gpio_mux_sel2>;
pinctrl-1 = <&usb_ulpi_pins>;
pinctrl-2 = <&usb_utmi_pins>;
pinctrl-3 = <&uart3_pins>;
pinctrl-names = "default", "ulpi", "utmi", "uart";
#phy-cells = <0>;
interrupts-extended = <
&cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
&cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
&cpcap 48 1
>;
interrupt-names =
"id_ground", "id_float", "se0conn", "vbusvld",
"sessvld", "sessend", "se1", "dm", "dp";
mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH
&gpio1 0 GPIO_ACTIVE_HIGH>;
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
io-channel-names = "vbus", "id";
vusb-supply = <&vusb>;
};
......@@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK
Required properties (phy (parent) node):
- compatible : should be one of the listed compatibles:
* "rockchip,rk3228-usb2phy"
* "rockchip,rk3328-usb2phy"
* "rockchip,rk3366-usb2phy"
* "rockchip,rk3399-usb2phy"
......
* Renesas R-Car generation 3 USB 3.0 PHY
This file provides information on what the device node for the R-Car generation
3 USB 3.0 PHY contains.
If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL
instead of USB3_CLK. However, if you don't want to these features, you don't
need this driver.
Required properties:
- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795
SoC.
"renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796
SoC.
"renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible
device.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first
followed by the generic version.
- reg: offset and length of the USB 3.0 PHY register block.
- clocks: A list of phandles and clock-specifier pairs.
- clock-names: Name of the clocks.
- The funcional clock must be "usb3-if".
- The usb3's external clock must be "usb3s_clk".
- The usb2's external clock must be "usb_extal". If you want to use the ssc,
the clock-frequency must not be 0.
- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
Optional properties:
- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using
the following values as u32:
- 0 (or the property doesn't exist): disable the ssc
- 4980: enable the ssc as -4980 ppm
- 4492: enable the ssc as -4492 ppm
- 4003: enable the ssc as -4003 ppm
Example (R-Car H3):
usb-phy@e65ee000 {
compatible = "renesas,r8a7795-usb3-phy",
"renesas,rcar-gen3-usb3-phy";
reg = <0 0xe65ee000 0 0x90>;
clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>;
clock-names = "usb3-if", "usb3s_clk", "usb_extal";
};
......@@ -1843,8 +1843,8 @@ F: drivers/i2c/busses/i2c-st.c
F: drivers/media/rc/st_rc.c
F: drivers/media/platform/sti/c8sectpfe/
F: drivers/mmc/host/sdhci-st.c
F: drivers/phy/phy-miphy28lp.c
F: drivers/phy/phy-stih407-usb.c
F: drivers/phy/st/phy-miphy28lp.c
F: drivers/phy/st/phy-stih407-usb.c
F: drivers/pinctrl/pinctrl-st.c
F: drivers/remoteproc/st_remoteproc.c
F: drivers/remoteproc/st_slim_rproc.c
......@@ -10831,11 +10831,11 @@ L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/adc/rcar_gyro_adc.c
RENESAS USB2 PHY DRIVER
RENESAS USB PHY DRIVER
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-renesas-soc@vger.kernel.org
S: Maintained
F: drivers/phy/phy-rcar-gen3-usb2.c
F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de>
......@@ -11237,12 +11237,12 @@ L: linux-kernel@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/phy/samsung-phy.txt
F: Documentation/phy/samsung-usb2.txt
F: drivers/phy/phy-exynos4210-usb2.c
F: drivers/phy/phy-exynos4x12-usb2.c
F: drivers/phy/phy-exynos5250-usb2.c
F: drivers/phy/phy-s5pv210-usb2.c
F: drivers/phy/phy-samsung-usb2.c
F: drivers/phy/phy-samsung-usb2.h
F: drivers/phy/samsung/phy-exynos4210-usb2.c
F: drivers/phy/samsung/phy-exynos4x12-usb2.c
F: drivers/phy/samsung/phy-exynos5250-usb2.c
F: drivers/phy/samsung/phy-s5pv210-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.h
SERIAL DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
......
This diff is collapsed.
......@@ -3,64 +3,21 @@
#
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
phy-exynos-usb2-y += phy-samsung-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
obj-$(CONFIG_ARCH_SUNXI) += allwinner/
obj-$(CONFIG_ARCH_MESON) += amlogic/
obj-$(CONFIG_ARCH_RENESAS) += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += broadcom/ \
hisilicon/ \
marvell/ \
motorola/ \
qualcomm/ \
samsung/ \
st/ \
ti/
#
# Phy drivers for Allwinner platforms
#
config PHY_SUN4I_USB
tristate "Allwinner sunxi SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
depends on RESET_CONTROLLER
depends on EXTCON
depends on POWER_SUPPLY
depends on USB_SUPPORT
select GENERIC_PHY
select USB_COMMON
help
Enable this to support the transceiver that is part of Allwinner
sunxi SoCs.
This driver controls the entire USB PHY block, both the USB OTG
parts, as well as the 2 regular USB 2 host PHYs.
config PHY_SUN9I_USB
tristate "Allwinner sun9i SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
depends on RESET_CONTROLLER
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
help
Enable this to support the transceiver that is part of Allwinner
sun9i SoCs.
This driver controls each individual USB 2 host PHY.
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
#
# Phy drivers for Amlogic platforms
#
config PHY_MESON8B_USB2
tristate "Meson8, Meson8b and GXBB USB2 PHY driver"
default ARCH_MESON
depends on OF && (ARCH_MESON || COMPILE_TEST)
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
help
Enable this to support the Meson USB2 PHYs found in Meson8,
Meson8b and GXBB SoCs.
If unsure, say N.
config PHY_MESON_GXL_USB2
tristate "Meson GXL and GXM USB2 PHY drivers"
default ARCH_MESON
depends on OF && (ARCH_MESON || COMPILE_TEST)
depends on USB_SUPPORT
select USB_COMMON
select GENERIC_PHY
select REGMAP_MMIO
help
Enable this to support the Meson USB2 PHYs found in Meson
GXL and GXM SoCs.
If unsure, say N.
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o
/*
* Meson GXL and GXM USB2 PHY driver
*
* Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/of.h>
/* bits [31:27] are read-only */
#define U2P_R0 0x0
#define U2P_R0_BYPASS_SEL BIT(0)
#define U2P_R0_BYPASS_DM_EN BIT(1)
#define U2P_R0_BYPASS_DP_EN BIT(2)
#define U2P_R0_TXBITSTUFF_ENH BIT(3)
#define U2P_R0_TXBITSTUFF_EN BIT(4)
#define U2P_R0_DM_PULLDOWN BIT(5)
#define U2P_R0_DP_PULLDOWN BIT(6)
#define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
#define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
#define U2P_R0_ADP_PRB_EN BIT(9)
#define U2P_R0_ADP_DISCHARGE BIT(10)
#define U2P_R0_ADP_CHARGE BIT(11)
#define U2P_R0_DRV_VBUS BIT(12)
#define U2P_R0_ID_PULLUP BIT(13)
#define U2P_R0_LOOPBACK_EN_B BIT(14)
#define U2P_R0_OTG_DISABLE BIT(15)
#define U2P_R0_COMMON_ONN BIT(16)
#define U2P_R0_FSEL_MASK GENMASK(19, 17)
#define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
#define U2P_R0_POWER_ON_RESET BIT(22)
#define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
#define U2P_R0_ID_SET_ID_DQ BIT(25)
#define U2P_R0_ATE_RESET BIT(26)
#define U2P_R0_FSV_MINUS BIT(27)
#define U2P_R0_FSV_PLUS BIT(28)
#define U2P_R0_BYPASS_DM_DATA BIT(29)
#define U2P_R0_BYPASS_DP_DATA BIT(30)
#define U2P_R1 0x4
#define U2P_R1_BURN_IN_TEST BIT(0)
#define U2P_R1_ACA_ENABLE BIT(1)
#define U2P_R1_DCD_ENABLE BIT(2)
#define U2P_R1_VDAT_SRC_EN_B BIT(3)
#define U2P_R1_VDAT_DET_EN_B BIT(4)
#define U2P_R1_CHARGES_SEL BIT(5)
#define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
#define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
#define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
#define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
#define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
#define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
#define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
#define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
#define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
#define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
/* bits [31:14] are read-only */
#define U2P_R2 0x8
#define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
#define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
#define U2P_R2_ADDR_MASK GENMASK(11, 8)
#define U2P_R2_DATA_OUT_SEL BIT(12)
#define U2P_R2_CLK BIT(13)
#define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
#define U2P_R2_ACA_PIN_RANGE_C BIT(18)
#define U2P_R2_ACA_PIN_RANGE_B BIT(19)
#define U2P_R2_ACA_PIN_RANGE_A BIT(20)
#define U2P_R2_ACA_PIN_GND BIT(21)
#define U2P_R2_ACA_PIN_FLOAT BIT(22)
#define U2P_R2_CHARGE_DETECT BIT(23)
#define U2P_R2_DEVICE_SESSION_VALID BIT(24)
#define U2P_R2_ADP_PROBE BIT(25)
#define U2P_R2_ADP_SENSE BIT(26)
#define U2P_R2_SESSION_END BIT(27)
#define U2P_R2_VBUS_VALID BIT(28)
#define U2P_R2_B_VALID BIT(29)
#define U2P_R2_A_VALID BIT(30)
#define U2P_R2_ID_DIG BIT(31)
#define U2P_R3 0xc
#define RESET_COMPLETE_TIME 500
struct phy_meson_gxl_usb2_priv {
struct regmap *regmap;
enum phy_mode mode;
int is_enabled;
};
static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = U2P_R3,
};
static int phy_meson_gxl_usb2_reset(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
if (priv->is_enabled) {
/* reset the PHY and wait until settings are stabilized */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);
udelay(RESET_COMPLETE_TIME);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
0);
udelay(RESET_COMPLETE_TIME);
}
return 0;
}
static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
switch (mode) {
case PHY_MODE_USB_HOST:
case PHY_MODE_USB_OTG:
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
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);
break;
case PHY_MODE_USB_DEVICE:
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
0);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
0);
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
U2P_R0_ID_PULLUP);
break;
default:
return -EINVAL;
}
phy_meson_gxl_usb2_reset(phy);
priv->mode = mode;
return 0;
}
static int phy_meson_gxl_usb2_power_off(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
priv->is_enabled = 0;
/* power off the PHY by putting it into reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);
return 0;
}
static int phy_meson_gxl_usb2_power_on(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
int ret;
priv->is_enabled = 1;
/* power on the PHY by taking it out of reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
if (ret) {
phy_meson_gxl_usb2_power_off(phy);
dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n",
priv->mode);
return ret;
}
return 0;
}
static const struct phy_ops phy_meson_gxl_usb2_ops = {
.power_on = phy_meson_gxl_usb2_power_on,
.power_off = phy_meson_gxl_usb2_power_off,
.set_mode = phy_meson_gxl_usb2_set_mode,
.reset = phy_meson_gxl_usb2_reset,
.owner = THIS_MODULE,
};
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;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
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);
switch (of_usb_get_dr_mode_by_phy(dev->of_node, -1)) {
case USB_DR_MODE_PERIPHERAL:
priv->mode = PHY_MODE_USB_DEVICE;
break;
case USB_DR_MODE_OTG:
priv->mode = PHY_MODE_USB_OTG;
break;
case USB_DR_MODE_HOST:
default:
priv->mode = PHY_MODE_USB_HOST;
break;
}
priv->regmap = devm_regmap_init_mmio(dev, base,
&phy_meson_gxl_usb2_regmap_conf);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY\n");
return PTR_ERR(phy);
}
phy_set_drvdata(phy, priv);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id phy_meson_gxl_usb2_of_match[] = {
{ .compatible = "amlogic,meson-gxl-usb2-phy", },
{ },
};
MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb2_of_match);
static struct platform_driver phy_meson_gxl_usb2_driver = {
.probe = phy_meson_gxl_usb2_probe,
.driver = {
.name = "phy-meson-gxl-usb2",
.of_match_table = phy_meson_gxl_usb2_of_match,
},
};
module_platform_driver(phy_meson_gxl_usb2_driver);
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver");
MODULE_LICENSE("GPL v2");
/*
* Meson8b and GXBB USB2 PHY driver
* Meson8, Meson8b and GXBB USB2 PHY driver
*
* Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
*
......@@ -266,6 +266,7 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
}
static const struct of_device_id phy_meson8b_usb2_of_match[] = {
{ .compatible = "amlogic,meson8-usb2-phy", },
{ .compatible = "amlogic,meson8b-usb2-phy", },
{ .compatible = "amlogic,meson-gxbb-usb2-phy", },
{ },
......@@ -282,5 +283,5 @@ static struct platform_driver phy_meson8b_usb2_driver = {
module_platform_driver(phy_meson8b_usb2_driver);
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Meson8b and GXBB USB2 PHY driver");
MODULE_DESCRIPTION("Meson8, Meson8b and GXBB USB2 PHY driver");
MODULE_LICENSE("GPL");
#
# Phy drivers for Broadcom platforms
#
config PHY_CYGNUS_PCIE
tristate "Broadcom Cygnus PCIe PHY driver"
depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
select GENERIC_PHY
default ARCH_BCM_CYGNUS
help
Enable this to support the Broadcom Cygnus PCIe PHY.
If unsure, say N.
config BCM_KONA_USB2_PHY
tristate "Broadcom Kona USB2 PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support the Broadcom Kona USB 2.0 PHY.
config PHY_BCM_NS_USB2
tristate "Broadcom Northstar USB 2.0 PHY Driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support Broadcom USB 2.0 PHY connected to the USB
controller on Northstar family.
config PHY_BCM_NS_USB3
tristate "Broadcom Northstar USB 3.0 PHY Driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_IOMEM && OF
select GENERIC_PHY
select MDIO_DEVICE
help
Enable this to support Broadcom USB 3.0 PHY connected to the USB
controller on Northstar family.
config PHY_NS2_PCIE
tristate "Broadcom Northstar2 PCIe PHY driver"
depends on OF && MDIO_BUS_MUX_BCM_IPROC
select GENERIC_PHY
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom Northstar2 PCIe PHY.
If unsure, say N.
config PHY_NS2_USB_DRD
tristate "Broadcom Northstar2 USB DRD PHY support"
depends on OF && (ARCH_BCM_IPROC || COMPILE_TEST)
select GENERIC_PHY
select EXTCON
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom Northstar2 USB DRD PHY.
This driver initializes the PHY in either HOST or DEVICE mode.
The host or device configuration is read from device tree.
If unsure, say N.
config PHY_BRCM_SATA
tristate "Broadcom SATA PHY driver"
depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST
depends on OF
select GENERIC_PHY
default ARCH_BCM_IPROC
help
Enable this to support the Broadcom SATA PHY.
If unsure, say N.
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
obj-$(CONFIG_PHY_NS2_USB_DRD) += phy-bcm-ns2-usbdrd.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
......@@ -16,7 +16,9 @@
#include <linux/bcma/bcma.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
......@@ -52,7 +54,10 @@ struct bcm_ns_usb3 {
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[] = {
......@@ -68,63 +73,16 @@ 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_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
u32 mask, u32 value, unsigned long timeout)
{
unsigned long deadline = jiffies + timeout;
u32 val;
do {
val = readl(addr);
if ((val & mask) == value)
return 0;
cpu_relax();
udelay(10);
} while (!time_after_eq(jiffies, deadline));
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
return -EBUSY;
}
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,
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
}
static int bcm_ns_usb3_mdio_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 0;
return usb3->phy_write(usb3, reg, value);
}
static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
{
int err;
/* Enable MDIO. Setting MDCDIV as 26 */
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
/* Wait for MDIO? */
udelay(2);
/* USB3 PLL Block */
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK);
......@@ -143,9 +101,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
/* Deaaserting PLL Reset */
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
/* Deasserting USB3 system reset */
writel(0, usb3->dmp + BCMA_RESET_CTL);
......@@ -169,9 +124,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
/* Enabling SSC */
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
return 0;
}
......@@ -179,12 +131,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
{
int err;
/* Enable MDIO. Setting MDCDIV as 26 */
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
/* Wait for MDIO? */
udelay(2);
/* PLL30 block */
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK);
......@@ -205,9 +151,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3);
/* Deasserting USB3 system reset */
writel(0, usb3->dmp + BCMA_RESET_CTL);
......@@ -242,6 +185,128 @@ static const struct phy_ops ops = {
.owner = THIS_MODULE,
};
/**************************************************
* MDIO driver code
**************************************************/
static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
u16 value)
{
struct mdio_device *mdiodev = usb3->mdiodev;
return mdiobus_write(mdiodev->bus, mdiodev->addr, reg, value);
}
static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
{
struct device *dev = &mdiodev->dev;
const struct of_device_id *of_id;
struct phy_provider *phy_provider;
struct device_node *syscon_np;
struct bcm_ns_usb3 *usb3;
struct resource res;
int err;
usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
if (!usb3)
return -ENOMEM;
usb3->dev = dev;
usb3->mdiodev = mdiodev;
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;
syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
err = of_address_to_resource(syscon_np, 0, &res);
of_node_put(syscon_np);
if (err)
return err;
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);
}
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");
return PTR_ERR(usb3->phy);
}
phy_set_drvdata(usb3->phy, usb3);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static struct mdio_driver bcm_ns_usb3_mdio_driver = {
.mdiodrv = {
.driver = {
.name = "bcm_ns_mdio_usb3",
.of_match_table = bcm_ns_usb3_id_table,
},
},
.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, unsigned long timeout)
{
unsigned long deadline = jiffies + timeout;
u32 val;
do {
val = readl(addr);
if ((val & mask) == value)
return 0;
cpu_relax();
udelay(10);
} while (!time_after_eq(jiffies, deadline));
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
return -EBUSY;
}
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,
usecs_to_jiffies(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;
......@@ -275,6 +340,14 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev)
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");
......@@ -298,6 +371,35 @@ static struct platform_driver bcm_ns_usb3_driver = {
.of_match_table = bcm_ns_usb3_id_table,
},
};
module_platform_driver(bcm_ns_usb3_driver);
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)
MODULE_LICENSE("GPL v2");
This diff is collapsed.
......@@ -46,6 +46,7 @@ enum brcm_sata_phy_version {
BRCM_SATA_PHY_STB_40NM,
BRCM_SATA_PHY_IPROC_NS2,
BRCM_SATA_PHY_IPROC_NSP,
BRCM_SATA_PHY_IPROC_SR,
};
struct brcm_sata_port {
......@@ -81,12 +82,17 @@ enum sata_phy_regs {
PLL_ACTRL2 = 0x8b,
PLL_ACTRL2_SELDIV_MASK = 0x1f,
PLL_ACTRL2_SELDIV_SHIFT = 9,
PLL_ACTRL6 = 0x86,
PLL1_REG_BANK = 0x060,
PLL1_ACTRL2 = 0x82,
PLL1_ACTRL3 = 0x83,
PLL1_ACTRL4 = 0x84,
TX_REG_BANK = 0x070,
TX_ACTRL0 = 0x80,
TX_ACTRL0_TXPOL_FLIP = BIT(6),
OOB_REG_BANK = 0x150,
OOB1_REG_BANK = 0x160,
OOB_CTRL1 = 0x80,
......@@ -347,6 +353,68 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port)
return 0;
}
/* SR PHY PLL0 registers */
#define SR_PLL0_ACTRL6_MAGIC 0xa
/* SR PHY PLL1 registers */
#define SR_PLL1_ACTRL2_MAGIC 0x32
#define SR_PLL1_ACTRL3_MAGIC 0x2
#define SR_PLL1_ACTRL4_MAGIC 0x3e8
static int brcm_sr_sata_init(struct brcm_sata_port *port)
{
struct brcm_sata_phy *priv = port->phy_priv;
struct device *dev = port->phy_priv->dev;
void __iomem *base = priv->phy_base;
unsigned int val, try;
/* Configure PHY PLL register bank 1 */
val = SR_PLL1_ACTRL2_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
val = SR_PLL1_ACTRL3_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
val = SR_PLL1_ACTRL4_MAGIC;
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
/* Configure PHY PLL register bank 0 */
val = SR_PLL0_ACTRL6_MAGIC;
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
/* Wait for PHY PLL lock by polling pll_lock bit */
try = 50;
do {
val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
BLOCK0_XGXSSTATUS);
if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
break;
msleep(20);
try--;
} while (try);
if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
/* PLL did not lock; give up */
dev_err(dev, "port%d PLL did not lock\n", port->portnum);
return -ETIMEDOUT;
}
/* Invert Tx polarity */
brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0,
~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
/* Configure OOB control to handle 100MHz reference clock */
val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
(0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
(0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
(0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
(0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
(0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
return 0;
}
static int brcm_sata_phy_init(struct phy *phy)
{
int rc;
......@@ -363,6 +431,9 @@ static int brcm_sata_phy_init(struct phy *phy)
case BRCM_SATA_PHY_IPROC_NSP:
rc = brcm_nsp_sata_init(port);
break;
case BRCM_SATA_PHY_IPROC_SR:
rc = brcm_sr_sata_init(port);
break;
default:
rc = -ENODEV;
}
......@@ -384,6 +455,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = {
.data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
{ .compatible = "brcm,iproc-nsp-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_NSP },
{ .compatible = "brcm,iproc-sr-sata-phy",
.data = (void *)BRCM_SATA_PHY_IPROC_SR },
{},
};
MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
......
#
# Phy drivers for Hisilicon platforms
#
config PHY_HI6220_USB
tristate "hi6220 USB PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the HISILICON HI6220 USB PHY.
To compile this driver as a module, choose M here.
config PHY_HIX5HD2_SATA
tristate "HIX5HD2 SATA PHY Driver"
depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
select GENERIC_PHY
select MFD_SYSCON
help
Support for SATA PHY on Hisilicon hix5hd2 Soc.
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
#
# Phy drivers for Marvell platforms
#
config ARMADA375_USBCLUSTER_PHY
def_bool y
depends on MACH_ARMADA_375 || COMPILE_TEST
depends on OF && HAS_IOMEM
select GENERIC_PHY
config PHY_BERLIN_SATA
tristate "Marvell Berlin SATA PHY driver"
depends on ARCH_BERLIN && HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support the SATA PHY on Marvell Berlin SoCs.
config PHY_BERLIN_USB
tristate "Marvell Berlin USB PHY Driver"
depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
select GENERIC_PHY
help
Enable this to support the USB PHY on Marvell Berlin SoCs.
config PHY_MVEBU_SATA
def_bool y
depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
depends on OF
select GENERIC_PHY
config PHY_PXA_28NM_HSIC
tristate "Marvell USB HSIC 28nm PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support Marvell USB HSIC PHY driver for Marvell
SoC. This driver will do the PHY initialization and shutdown.
The PHY driver will be used by Marvell ehci driver.
To compile this driver as a module, choose M here.
config PHY_PXA_28NM_USB2
tristate "Marvell USB 2.0 28nm PHY Driver"
depends on HAS_IOMEM
select GENERIC_PHY
help
Enable this to support Marvell USB 2.0 PHY driver for Marvell
SoC. This driver will do the PHY initialization and shutdown.
The PHY driver will be used by Marvell udc/ehci/otg driver.
To compile this driver as a module, choose M here.
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_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
#
# Phy drivers for Motorola devices
#
config PHY_CPCAP_USB
tristate "CPCAP PMIC USB PHY driver"
depends on USB_SUPPORT && IIO
depends on USB_MUSB_HDRC || USB_MUSB_HDRC=n
select GENERIC_PHY
select USB_PHY
help
Enable this for USB to work on Motorola phones and tablets
such as Droid 4.
#
# Makefile for the phy drivers.
#
obj-$(CONFIG_PHY_CPCAP_USB) += phy-cpcap-usb.o
This diff is collapsed.
#
# Phy drivers for Qualcomm platforms
#
config PHY_QCOM_APQ8064_SATA
tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
depends on ARCH_QCOM
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
config PHY_QCOM_IPQ806X_SATA
tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
depends on ARCH_QCOM
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
config PHY_QCOM_QMP
tristate "Qualcomm QMP PHY Driver"
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
select GENERIC_PHY
help
Enable this to support the QMP PHY transceiver that is used
with controllers such as PCIe, UFS, and USB on Qualcomm chips.
config PHY_QCOM_QUSB2
tristate "Qualcomm QUSB2 PHY Driver"
depends on OF && (ARCH_QCOM || COMPILE_TEST)
depends on NVMEM || !NVMEM
select GENERIC_PHY
help
Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
controllers on Qualcomm chips. This driver supports the high-speed
PHY which is usually paired with either the ChipIdea or Synopsys DWC3
USB IPs on MSM SOCs.
config PHY_QCOM_UFS
tristate "Qualcomm UFS PHY driver"
depends on OF && ARCH_QCOM
select GENERIC_PHY
help
Support for UFS PHY on QCOM chipsets.
config PHY_QCOM_USB_HS
tristate "Qualcomm USB HS PHY module"
depends on USB_ULPI_BUS
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
select GENERIC_PHY
help
Support for the USB high-speed ULPI compliant phy on Qualcomm
chipsets.
config PHY_QCOM_USB_HSIC
tristate "Qualcomm USB HSIC ULPI PHY module"
depends on USB_ULPI_BUS
select GENERIC_PHY
help
Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
......@@ -11,12 +11,11 @@
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/reset.h>
#include <linux/extcon.h>
#include <linux/notifier.h>
#include "ulpi_phy.h"
#define ULPI_PWR_CLK_MNG_REG 0x88
# define ULPI_PWR_OTG_COMP_DISABLE BIT(0)
......
......@@ -8,13 +8,12 @@
#include <linux/module.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
#include <linux/phy/phy.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl-state.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include "ulpi_phy.h"
#define ULPI_HSIC_CFG 0x30
#define ULPI_HSIC_IO_CAL 0x33
......
#
# Phy drivers for Renesas platforms
#
config PHY_RCAR_GEN2
tristate "Renesas R-Car generation 2 USB PHY driver"
depends on ARCH_RENESAS
depends on GENERIC_PHY
help
Support for USB PHY found on Renesas R-Car generation 2 SoCs.
config PHY_RCAR_GEN3_USB2
tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
depends on ARCH_RENESAS
depends on EXTCON
select GENERIC_PHY
help
Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
config PHY_RCAR_GEN3_USB3
tristate "Renesas R-Car generation 3 USB 3.0 PHY driver"
depends on ARCH_RENESAS || COMPILE_TEST
select GENERIC_PHY
help
Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs.
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o
/*
* Renesas R-Car Gen3 for USB3.0 PHY driver
*
* Copyright (C) 2017 Renesas Electronics Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#define USB30_CLKSET0 0x034
#define USB30_CLKSET1 0x036
#define USB30_SSC_SET 0x038
#define USB30_PHY_ENABLE 0x060
#define USB30_VBUS_EN 0x064
/* USB30_CLKSET0 */
#define CLKSET0_PRIVATE 0x05c0
#define CLKSET0_USB30_FSEL_USB_EXTAL 0x0002
/* USB30_CLKSET1 */
#define CLKSET1_USB30_PLL_MULTI_SHIFT 6
#define CLKSET1_USB30_PLL_MULTI_USB_EXTAL (0x64 << \
CLKSET1_USB30_PLL_MULTI_SHIFT)
#define CLKSET1_PHYRESET BIT(4) /* 1: reset */
#define CLKSET1_REF_CLKDIV BIT(3) /* 1: USB_EXTAL */
#define CLKSET1_PRIVATE_2_1 BIT(1) /* Write B'01 */
#define CLKSET1_REF_CLK_SEL BIT(0) /* 1: USB3S0_CLK_P */
/* USB30_SSC_SET */
#define SSC_SET_SSC_EN BIT(12)
#define SSC_SET_RANGE_SHIFT 9
#define SSC_SET_RANGE_4980 (0x0 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4492 (0x1 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4003 (0x2 << SSC_SET_RANGE_SHIFT)
/* USB30_PHY_ENABLE */
#define PHY_ENABLE_RESET_EN BIT(4)
/* USB30_VBUS_EN */
#define VBUS_EN_VBUS_EN BIT(1)
struct rcar_gen3_usb3 {
void __iomem *base;
struct phy *phy;
u32 ssc_range;
bool usb3s_clk;
bool usb_extal;
};
static void write_clkset1_for_usb_extal(struct rcar_gen3_usb3 *r, bool reset)
{
u16 val = CLKSET1_USB30_PLL_MULTI_USB_EXTAL |
CLKSET1_REF_CLKDIV | CLKSET1_PRIVATE_2_1;
if (reset)
val |= CLKSET1_PHYRESET;
writew(val, r->base + USB30_CLKSET1);
}
static void rcar_gen3_phy_usb3_enable_ssc(struct rcar_gen3_usb3 *r)
{
u16 val = SSC_SET_SSC_EN;
switch (r->ssc_range) {
case 4980:
val |= SSC_SET_RANGE_4980;
break;
case 4492:
val |= SSC_SET_RANGE_4492;
break;
case 4003:
val |= SSC_SET_RANGE_4003;
break;
default:
dev_err(&r->phy->dev, "%s: unsupported range (%x)\n", __func__,
r->ssc_range);
return;
}
writew(val, r->base + USB30_SSC_SET);
}
static void rcar_gen3_phy_usb3_select_usb_extal(struct rcar_gen3_usb3 *r)
{
write_clkset1_for_usb_extal(r, false);
if (r->ssc_range)
rcar_gen3_phy_usb3_enable_ssc(r);
writew(CLKSET0_PRIVATE | CLKSET0_USB30_FSEL_USB_EXTAL,
r->base + USB30_CLKSET0);
writew(PHY_ENABLE_RESET_EN, r->base + USB30_PHY_ENABLE);
write_clkset1_for_usb_extal(r, true);
usleep_range(10, 20);
write_clkset1_for_usb_extal(r, false);
}
static int rcar_gen3_phy_usb3_init(struct phy *p)
{
struct rcar_gen3_usb3 *r = phy_get_drvdata(p);
dev_vdbg(&r->phy->dev, "%s: enter (%d, %d, %d)\n", __func__,
r->usb3s_clk, r->usb_extal, r->ssc_range);
if (!r->usb3s_clk && r->usb_extal)
rcar_gen3_phy_usb3_select_usb_extal(r);
/* Enables VBUS detection anyway */
writew(VBUS_EN_VBUS_EN, r->base + USB30_VBUS_EN);
return 0;
}
static const struct phy_ops rcar_gen3_phy_usb3_ops = {
.init = rcar_gen3_phy_usb3_init,
.owner = THIS_MODULE,
};
static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = {
{ .compatible = "renesas,rcar-gen3-usb3-phy" },
{ }
};
MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table);
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;
if (!dev->of_node) {
dev_err(dev, "This driver needs device tree\n");
return -EINVAL;
}
r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
if (!r)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
r->base = devm_ioremap_resource(dev, res);
if (IS_ERR(r->base))
return PTR_ERR(r->base);
clk = devm_clk_get(dev, "usb3s_clk");
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
r->usb3s_clk = !!clk_get_rate(clk);
clk_disable_unprepare(clk);
}
clk = devm_clk_get(dev, "usb_extal");
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
r->usb_extal = !!clk_get_rate(clk);
clk_disable_unprepare(clk);
}
if (!r->usb3s_clk && !r->usb_extal) {
dev_err(dev, "This driver needs usb3s_clk and/or usb_extal\n");
ret = -EINVAL;
goto error;
}
/*
* devm_phy_create() will call pm_runtime_enable(&phy->dev);
* And then, phy-core will manage runtime pm for this device.
*/
pm_runtime_enable(dev);
r->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb3_ops);
if (IS_ERR(r->phy)) {
dev_err(dev, "Failed to create USB3 PHY\n");
ret = PTR_ERR(r->phy);
goto error;
}
of_property_read_u32(dev->of_node, "renesas,ssc-range", &r->ssc_range);
platform_set_drvdata(pdev, r);
phy_set_drvdata(r->phy, r);
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(provider)) {
dev_err(dev, "Failed to register PHY provider\n");
ret = PTR_ERR(provider);
goto error;
}
return 0;
error:
pm_runtime_disable(dev);
return ret;
}
static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
return 0;
};
static struct platform_driver rcar_gen3_phy_usb3_driver = {
.driver = {
.name = "phy_rcar_gen3_usb3",
.of_match_table = rcar_gen3_phy_usb3_match_table,
},
.probe = rcar_gen3_phy_usb3_probe,
.remove = rcar_gen3_phy_usb3_remove,
};
module_platform_driver(rcar_gen3_phy_usb3_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 3.0 PHY");
MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
#
# Phy drivers for Rockchip platforms
#
config PHY_ROCKCHIP_DP
tristate "Rockchip Display Port PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip Display Port PHY.
config PHY_ROCKCHIP_EMMC
tristate "Rockchip EMMC PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip EMMC PHY.
config PHY_ROCKCHIP_INNO_USB2
tristate "Rockchip INNO USB2PHY Driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
depends on COMMON_CLK
depends on EXTCON
depends on USB_SUPPORT
select GENERIC_PHY
select USB_COMMON
help
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
config PHY_ROCKCHIP_PCIE
tristate "Rockchip PCIe PHY Driver"
depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the Rockchip PCIe PHY.
config PHY_ROCKCHIP_TYPEC
tristate "Rockchip TYPEC PHY Driver"
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
select EXTCON
select GENERIC_PHY
select RESET_CONTROLLER
help
Enable this to support the Rockchip USB TYPEC PHY.
config PHY_ROCKCHIP_USB
tristate "Rockchip USB2 PHY Driver"
depends on ARCH_ROCKCHIP && OF
select GENERIC_PHY
help
Enable this to support the Rockchip USB 2.0 PHY.
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
......@@ -406,7 +406,8 @@ static int rockchip_usb2phy_init(struct phy *phy)
mutex_lock(&rport->mutex);
if (rport->port_id == USB2PHY_PORT_OTG) {
if (rport->mode != USB_DR_MODE_HOST) {
if (rport->mode != USB_DR_MODE_HOST &&
rport->mode != USB_DR_MODE_UNKNOWN) {
/* clear bvalid status and enable bvalid detect irq */
ret = property_enable(rphy,
&rport->port_cfg->bvalid_det_clr,
......@@ -421,7 +422,7 @@ static int rockchip_usb2phy_init(struct phy *phy)
goto out;
schedule_delayed_work(&rport->otg_sm_work,
OTG_SCHEDULE_DELAY);
OTG_SCHEDULE_DELAY * 3);
} else {
/* If OTG works in host only mode, do nothing. */
dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
......@@ -463,6 +464,9 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
if (ret)
return ret;
/* waiting for the utmi_clk to become stable */
usleep_range(1500, 2000);
rport->suspended = false;
return 0;
}
......@@ -493,7 +497,8 @@ static int rockchip_usb2phy_exit(struct phy *phy)
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
if (rport->port_id == USB2PHY_PORT_OTG &&
rport->mode != USB_DR_MODE_HOST) {
rport->mode != USB_DR_MODE_HOST &&
rport->mode != USB_DR_MODE_UNKNOWN) {
cancel_delayed_work_sync(&rport->otg_sm_work);
cancel_delayed_work_sync(&rport->chg_work);
} else if (rport->port_id == USB2PHY_PORT_HOST)
......@@ -970,7 +975,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
mutex_init(&rport->mutex);
rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
if (rport->mode == USB_DR_MODE_HOST) {
if (rport->mode == USB_DR_MODE_HOST ||
rport->mode == USB_DR_MODE_UNKNOWN) {
ret = 0;
goto out;
}
......@@ -1138,6 +1144,65 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
return ret;
}
static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
{
.reg = 0x760,
.num_ports = 2,
.clkout_ctl = { 0x0768, 4, 4, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
.bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
.bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
.ls_det_en = { 0x0680, 2, 2, 0, 1 },
.ls_det_st = { 0x0690, 2, 2, 0, 1 },
.ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
.utmi_bvalid = { 0x0480, 4, 4, 0, 1 },
.utmi_ls = { 0x0480, 3, 2, 0, 1 },
},
[USB2PHY_PORT_HOST] = {
.phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0680, 4, 4, 0, 1 },
.ls_det_st = { 0x0690, 4, 4, 0, 1 },
.ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
}
},
.chg_det = {
.opmode = { 0x0760, 3, 0, 5, 1 },
.cp_det = { 0x0884, 4, 4, 0, 1 },
.dcp_det = { 0x0884, 3, 3, 0, 1 },
.dp_det = { 0x0884, 5, 5, 0, 1 },
.idm_sink_en = { 0x0768, 8, 8, 0, 1 },
.idp_sink_en = { 0x0768, 7, 7, 0, 1 },
.idp_src_en = { 0x0768, 9, 9, 0, 1 },
.rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 },
.vdm_src_en = { 0x0768, 12, 12, 0, 1 },
.vdp_src_en = { 0x0768, 11, 11, 0, 1 },
},
},
{
.reg = 0x800,
.num_ports = 2,
.clkout_ctl = { 0x0808, 4, 4, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0684, 0, 0, 0, 1 },
.ls_det_st = { 0x0694, 0, 0, 0, 1 },
.ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
},
[USB2PHY_PORT_HOST] = {
.phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x0684, 1, 1, 0, 1 },
.ls_det_st = { 0x0694, 1, 1, 0, 1 },
.ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
}
},
},
{ /* sentinel */ }
};
static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
{
.reg = 0x100,
......@@ -1263,6 +1328,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
};
static const struct of_device_id rockchip_usb2phy_dt_match[] = {
{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
......
#
# Phy drivers for Samsung platforms
#
config PHY_EXYNOS_DP_VIDEO
tristate "EXYNOS SoC series Display Port PHY driver"
depends on OF
depends on ARCH_EXYNOS || COMPILE_TEST
default ARCH_EXYNOS
select GENERIC_PHY
help
Support for Display Port PHY found on Samsung EXYNOS SoCs.
config PHY_EXYNOS_MIPI_VIDEO
tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
depends on HAS_IOMEM
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
select GENERIC_PHY
default y if ARCH_S5PV210 || ARCH_EXYNOS
help
Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
and EXYNOS SoCs.
config PHY_EXYNOS_PCIE
bool "Exynos PCIe PHY driver"
depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
select GENERIC_PHY
help
Enable PCIe PHY support for Exynos SoC series.
This driver provides PHY interface for Exynos PCIe controller.
config PHY_SAMSUNG_USB2
tristate "Samsung USB 2.0 PHY driver"
depends on HAS_IOMEM
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
select GENERIC_PHY
select MFD_SYSCON
default ARCH_EXYNOS
help
Enable this to support the Samsung USB 2.0 PHY driver for Samsung
SoCs. This driver provides the interface for USB 2.0 PHY. Support
for particular PHYs will be enabled based on the SoC type in addition
to this driver.
config PHY_EXYNOS4210_USB2
bool
depends on PHY_SAMSUNG_USB2
default CPU_EXYNOS4210
config PHY_EXYNOS4X12_USB2
bool
depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
config PHY_EXYNOS5250_USB2
bool
depends on PHY_SAMSUNG_USB2
default SOC_EXYNOS5250 || SOC_EXYNOS5420
config PHY_S5PV210_USB2
bool "Support for S5PV210"
depends on PHY_SAMSUNG_USB2
depends on ARCH_S5PV210
help
Enable USB PHY support for S5PV210. This option requires that Samsung
USB 2.0 PHY driver is enabled and means that support for this
particular SoC is compiled in the driver. In case of S5PV210 two phys
are available - device and host.
config PHY_EXYNOS5_USBDRD
tristate "Exynos5 SoC series USB DRD PHY driver"
depends on ARCH_EXYNOS && OF
depends on HAS_IOMEM
depends on USB_DWC3_EXYNOS
select GENERIC_PHY
select MFD_SYSCON
default y
help
Enable USB DRD PHY support for Exynos 5 SoC series.
This driver provides PHY interface for USB 3.0 DRD controller
present on Exynos5 SoC series.
config PHY_EXYNOS5250_SATA
tristate "Exynos5250 Sata SerDes/PHY driver"
depends on SOC_EXYNOS5250
depends on HAS_IOMEM
depends on OF
select GENERIC_PHY
select I2C
select I2C_S3C2410
select MFD_SYSCON
help
Enable this to support SATA SerDes/Phy found on Samsung's
Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s,
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
port to accept one SATA device.
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
phy-exynos-usb2-y += phy-samsung-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
#
# Phy drivers for STMicro platforms
#
config PHY_MIPHY28LP
tristate "STMicroelectronics MIPHY28LP PHY driver for STiH407"
depends on ARCH_STI
select GENERIC_PHY
help
Enable this to support the miphy transceiver (for SATA/PCIE/USB3)
that is part of STMicroelectronics STiH407 SoC.
config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
select GENERIC_PHY
depends on MACH_SPEAR1310 || COMPILE_TEST
help
Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA.
config PHY_ST_SPEAR1340_MIPHY
tristate "ST SPEAR1340-MIPHY driver"
select GENERIC_PHY
depends on MACH_SPEAR1340 || COMPILE_TEST
help
Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
config PHY_STIH407_USB
tristate "STMicroelectronics USB2 picoPHY driver for STiH407 family"
depends on RESET_CONTROLLER
depends on ARCH_STI || COMPILE_TEST
select GENERIC_PHY
help
Enable this support to enable the picoPHY device used by USB2
and USB3 controllers on STMicroelectronics STiH407 SoC families.
obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
#
# Phy drivers for TI platforms
#
config PHY_DA8XX_USB
tristate "TI DA8xx USB PHY Driver"
depends on ARCH_DAVINCI_DA8XX
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the USB PHY on DA8xx SoCs.
This driver controls both the USB 1.1 PHY and the USB 2.0 PHY.
config PHY_DM816X_USB
tristate "TI dm816x USB PHY driver"
depends on ARCH_OMAP2PLUS
depends on USB_SUPPORT
select GENERIC_PHY
select USB_PHY
help
Enable this for dm816x USB to work.
config OMAP_CONTROL_PHY
tristate "OMAP CONTROL PHY Driver"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
help
Enable this to add support for the PHY part present in the control
module. This driver has API to power on the USB2 PHY and to write to
the mailbox. The mailbox is present only in omap4 and the register to
power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
additional register to power on USB3 PHY/SATA PHY/PCIE PHY
(PIPE3 PHY).
config OMAP_USB2
tristate "OMAP USB2 PHY Driver"
depends on ARCH_OMAP2PLUS
depends on USB_SUPPORT
select GENERIC_PHY
select USB_PHY
select OMAP_CONTROL_PHY
depends on OMAP_OCP2SCP
help
Enable this to support the transceiver that is part of SOC. This
driver takes care of all the PHY functionality apart from comparator.
The USB OTG controller communicates with the comparator using this
driver.
config TI_PIPE3
tristate "TI PIPE3 PHY Driver"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
select GENERIC_PHY
select OMAP_CONTROL_PHY
depends on OMAP_OCP2SCP
help
Enable this to support the PIPE3 PHY that is part of TI SOCs. This
driver takes care of all the PHY functionality apart from comparator.
This driver interacts with the "OMAP Control PHY Driver" to power
on/off the PHY.
config PHY_TUSB1210
tristate "TI TUSB1210 ULPI PHY module"
depends on USB_ULPI_BUS
select GENERIC_PHY
help
Support for TI TUSB1210 USB ULPI PHY.
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
depends on USB_SUPPORT
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't 'y'
select GENERIC_PHY
select USB_PHY
help
Enable this to support the USB OTG transceiver on TWL4030
family chips (including the TWL5030 and TPS659x0 devices).
This transceiver supports high and full speed devices plus,
in host mode, low speed.
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o
obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
......@@ -11,9 +11,9 @@
*/
#include <linux/module.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
#include "ulpi_phy.h"
#include <linux/phy/ulpi_phy.h>
#define TUSB1210_VENDOR_SPECIFIC2 0x80
#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT 0
......@@ -53,9 +53,43 @@ static int tusb1210_power_off(struct phy *phy)
return 0;
}
static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
int ret;
ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL);
if (ret < 0)
return ret;
switch (mode) {
case PHY_MODE_USB_HOST:
ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT
| ULPI_OTG_CTRL_ID_PULLUP
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
ret |= ULPI_OTG_CTRL_DRVVBUS;
break;
case PHY_MODE_USB_DEVICE:
ret &= ~(ULPI_OTG_CTRL_DRVVBUS
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
break;
default:
/* nothing */
return 0;
}
return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
}
static const struct phy_ops phy_ops = {
.power_on = tusb1210_power_on,
.power_off = tusb1210_power_off,
.set_mode = tusb1210_set_mode,
.owner = THIS_MODULE,
};
......@@ -125,7 +159,8 @@ static void tusb1210_remove(struct ulpi *ulpi)
#define TI_VENDOR_ID 0x0451
static const struct ulpi_device_id tusb1210_ulpi_id[] = {
{ TI_VENDOR_ID, 0x1507, },
{ TI_VENDOR_ID, 0x1507, }, /* TUSB1210 */
{ TI_VENDOR_ID, 0x1508, }, /* TUSB1211 */
{ },
};
MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment