Commit a6308d70 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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

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

Kishon writes:

phy: for 4.12

 *) Add new PHY driver for Qualcomm's QMP PHY (used by PCIe, UFS and USB)
 *) Add new PHY driver for Qualcomm's QUSB2 PHY
 *) Add support for vbus regulator in rockchip-usb driver
 *) Add support for usb2-phy in rk3328 to rockchip-inno-usb2 driver
 *) Add support for a new version of PHY in phy-mt65xx-usb3 driver
 *) Add support for Allwinner A64 PHY to switch between MUSB and EHCI/OHCI
 *) Cleanups in Exynos driver and phy-mt65xx-usb3 driver
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parents 37e47d5c 6239879b
...@@ -6,12 +6,11 @@ This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC. ...@@ -6,12 +6,11 @@ This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC.
Required properties (controller (parent) node): Required properties (controller (parent) node):
- compatible : should be one of - compatible : should be one of
"mediatek,mt2701-u3phy" "mediatek,mt2701-u3phy"
"mediatek,mt2712-u3phy"
"mediatek,mt8173-u3phy" "mediatek,mt8173-u3phy"
- reg : offset and length of register for phy, exclude port's - clocks : (deprecated, use port's clocks instead) a list of phandle +
register. clock-specifier pairs, one for each entry in clock-names
- clocks : a list of phandle + clock-specifier pairs, one for each - clock-names : (deprecated, use port's one instead) must contain
entry in clock-names
- clock-names : must contain
"u3phya_ref": for reference clock of usb3.0 analog phy. "u3phya_ref": for reference clock of usb3.0 analog phy.
Required nodes : a sub-node is required for each port the controller Required nodes : a sub-node is required for each port the controller
...@@ -19,8 +18,19 @@ Required nodes : a sub-node is required for each port the controller ...@@ -19,8 +18,19 @@ Required nodes : a sub-node is required for each port the controller
'reg' property is used inside these nodes to describe 'reg' property is used inside these nodes to describe
the controller's topology. the controller's topology.
Optional properties (controller (parent) node):
- reg : offset and length of register shared by multiple ports,
exclude port's private register. It is needed on mt2701
and mt8173, but not on mt2712.
Required properties (port (child) node): Required properties (port (child) node):
- reg : address and length of the register set for the port. - reg : address and length of the register set for the port.
- clocks : a list of phandle + clock-specifier pairs, one for each
entry in clock-names
- clock-names : must contain
"ref": 48M reference clock for HighSpeed analog phy; and 26M
reference clock for SuperSpeed analog phy, sometimes is
24M, 25M or 27M, depended on platform.
- #phy-cells : should be 1 (See second example) - #phy-cells : should be 1 (See second example)
cell after port phandle is phy type from: cell after port phandle is phy type from:
- PHY_TYPE_USB2 - PHY_TYPE_USB2
...@@ -31,21 +41,31 @@ Example: ...@@ -31,21 +41,31 @@ Example:
u3phy: usb-phy@11290000 { u3phy: usb-phy@11290000 {
compatible = "mediatek,mt8173-u3phy"; compatible = "mediatek,mt8173-u3phy";
reg = <0 0x11290000 0 0x800>; reg = <0 0x11290000 0 0x800>;
clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
clock-names = "u3phya_ref";
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
ranges; ranges;
status = "okay"; status = "okay";
phy_port0: port@11290800 { u2port0: usb-phy@11290800 {
reg = <0 0x11290800 0 0x800>; reg = <0 0x11290800 0 0x100>;
clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
clock-names = "ref";
#phy-cells = <1>; #phy-cells = <1>;
status = "okay"; status = "okay";
}; };
phy_port1: port@11291000 { u3port0: usb-phy@11290900 {
reg = <0 0x11291000 0 0x800>; reg = <0 0x11290800 0 0x700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
u2port1: usb-phy@11291000 {
reg = <0 0x11291000 0 0x100>;
clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
clock-names = "ref";
#phy-cells = <1>; #phy-cells = <1>;
status = "okay"; status = "okay";
}; };
...@@ -64,7 +84,54 @@ Example: ...@@ -64,7 +84,54 @@ Example:
usb30: usb@11270000 { usb30: usb@11270000 {
... ...
phys = <&phy_port0 PHY_TYPE_USB3>; phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>;
phy-names = "usb3-0"; phy-names = "usb2-0", "usb3-0";
... ...
}; };
Layout differences of banks between mt8173/mt2701 and mt2712
-------------------------------------------------------------
mt8173 and mt2701:
port offset bank
shared 0x0000 SPLLC
0x0100 FMREG
u2 port0 0x0800 U2PHY_COM
u3 port0 0x0900 U3PHYD
0x0a00 U3PHYD_BANK2
0x0b00 U3PHYA
0x0c00 U3PHYA_DA
u2 port1 0x1000 U2PHY_COM
u3 port1 0x1100 U3PHYD
0x1200 U3PHYD_BANK2
0x1300 U3PHYA
0x1400 U3PHYA_DA
u2 port2 0x1800 U2PHY_COM
...
mt2712:
port offset bank
u2 port0 0x0000 MISC
0x0100 FMREG
0x0300 U2PHY_COM
u3 port0 0x0700 SPLLC
0x0800 CHIP
0x0900 U3PHYD
0x0a00 U3PHYD_BANK2
0x0b00 U3PHYA
0x0c00 U3PHYA_DA
u2 port1 0x1000 MISC
0x1100 FMREG
0x1300 U2PHY_COM
u3 port1 0x1700 SPLLC
0x1800 CHIP
0x1900 U3PHYD
0x1a00 U3PHYD_BANK2
0x1b00 U3PHYA
0x1c00 U3PHYA_DA
u2 port2 0x2000 MISC
...
SPLLC shared by u3 ports and FMREG shared by u2 ports on
mt8173/mt2701 are put back into each port; a new bank MISC for
u2 ports and CHIP for u3 ports are added on mt2712.
...@@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK ...@@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK
Required properties (phy (parent) node): Required properties (phy (parent) node):
- compatible : should be one of the listed compatibles: - compatible : should be one of the listed compatibles:
* "rockchip,rk3328-usb2phy"
* "rockchip,rk3366-usb2phy" * "rockchip,rk3366-usb2phy"
* "rockchip,rk3399-usb2phy" * "rockchip,rk3399-usb2phy"
- reg : the address offset of grf for usb-phy configuration. - reg : the address offset of grf for usb-phy configuration.
...@@ -11,6 +12,11 @@ Required properties (phy (parent) node): ...@@ -11,6 +12,11 @@ Required properties (phy (parent) node):
Optional properties: Optional properties:
- clocks : phandle + phy specifier pair, for the input clock of phy. - clocks : phandle + phy specifier pair, for the input clock of phy.
- clock-names : input clock name of phy, must be "phyclk". - clock-names : input clock name of phy, must be "phyclk".
- assigned-clocks : phandle of usb 480m clock.
- assigned-clock-parents : parent of usb 480m clock, select between
usb-phy output 480m and xin24m.
Refer to clk/clock-bindings.txt for generic clock
consumer properties.
Required nodes : a sub-node is required for each port the phy provides. Required nodes : a sub-node is required for each port the phy provides.
The sub-node name is used to identify host or otg port, The sub-node name is used to identify host or otg port,
......
Qualcomm QMP PHY controller
===========================
QMP phy controller supports physical layer functionality for a number of
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
Required properties:
- compatible: compatible list, contains:
"qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
"qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
- reg: offset and length of register set for PHY's common serdes block.
- #clock-cells: must be 1
- Phy pll outputs a bunch of clocks for Tx, Rx and Pipe
interface (for pipe based PHYs). These clock are then gate-controlled
by gcc.
- #address-cells: must be 1
- #size-cells: must be 1
- ranges: must be present
- clocks: a list of phandles and clock-specifier pairs,
one for each entry in clock-names.
- clock-names: "cfg_ahb" for phy config clock,
"aux" for phy aux clock,
"ref" for 19.2 MHz ref clk,
For "qcom,msm8996-qmp-pcie-phy" must contain:
"aux", "cfg_ahb", "ref".
For "qcom,msm8996-qmp-usb3-phy" must contain:
"aux", "cfg_ahb", "ref".
- resets: a list of phandles and reset controller specifier pairs,
one for each entry in reset-names.
- reset-names: "phy" for reset of phy block,
"common" for phy common block reset,
"cfg" for phy's ahb cfg block reset (Optional).
For "qcom,msm8996-qmp-pcie-phy" must contain:
"phy", "common", "cfg".
For "qcom,msm8996-qmp-usb3-phy" must contain
"phy", "common".
- vdda-phy-supply: Phandle to a regulator supply to PHY core block.
- vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
Optional properties:
- vddp-ref-clk-supply: Phandle to a regulator supply to any specific refclk
pll block.
Required nodes:
- Each device node of QMP phy is required to have as many child nodes as
the number of lanes the PHY has.
Required properties for child node:
- reg: list of offset and length pairs of register sets for PHY blocks -
tx, rx and pcs.
- #phy-cells: must be 0
- clocks: a list of phandles and clock-specifier pairs,
one for each entry in clock-names.
- clock-names: Must contain following for pcie and usb qmp phys:
"pipe<lane-number>" for pipe clock specific to each lane.
- resets: a list of phandles and reset controller specifier pairs,
one for each entry in reset-names.
- reset-names: Must contain following for pcie qmp phys:
"lane<lane-number>" for reset specific to each lane.
Example:
phy@34000 {
compatible = "qcom,msm8996-qmp-pcie-phy";
reg = <0x34000 0x488>;
#clock-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
<&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
<&gcc GCC_PCIE_CLKREF_CLK>;
clock-names = "aux", "cfg_ahb", "ref";
vdda-phy-supply = <&pm8994_l28>;
vdda-pll-supply = <&pm8994_l12>;
resets = <&gcc GCC_PCIE_PHY_BCR>,
<&gcc GCC_PCIE_PHY_COM_BCR>,
<&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
reset-names = "phy", "common", "cfg";
pciephy_0: lane@35000 {
reg = <0x35000 0x130>,
<0x35200 0x200>,
<0x35400 0x1dc>;
#phy-cells = <0>;
clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
clock-names = "pipe0";
resets = <&gcc GCC_PCIE_0_PHY_BCR>;
reset-names = "lane0";
};
pciephy_1: lane@36000 {
...
...
};
Qualcomm QUSB2 phy controller
=============================
QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets.
Required properties:
- compatible: compatible list, contains "qcom,msm8996-qusb2-phy".
- reg: offset and length of the PHY register set.
- #phy-cells: must be 0.
- clocks: a list of phandles and clock-specifier pairs,
one for each entry in clock-names.
- clock-names: must be "cfg_ahb" for phy config clock,
"ref" for 19.2 MHz ref clk,
"iface" for phy interface clock (Optional).
- vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
- vdda-phy-dpdm-supply: Phandle to 3.1V regulator supply to Dp/Dm port signals.
- resets: Phandle to reset to phy block.
Optional properties:
- nvmem-cells: Phandle to nvmem cell that contains 'HS Tx trim'
tuning parameter value for qusb2 phy.
- qcom,tcsr-syscon: Phandle to TCSR syscon register region.
Example:
hsusb_phy: phy@7411000 {
compatible = "qcom,msm8996-qusb2-phy";
reg = <0x7411000 0x180>;
#phy-cells = <0>;
clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
<&gcc GCC_RX1_USB2_CLKREF_CLK>,
clock-names = "cfg_ahb", "ref";
vdda-pll-supply = <&pm8994_l12>;
vdda-phy-dpdm-supply = <&pm8994_l24>;
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
nvmem-cells = <&qusb2p_hstx_trim>;
};
...@@ -30,6 +30,7 @@ Optional Properties: ...@@ -30,6 +30,7 @@ Optional Properties:
- reset-names: Only allow the following entries: - reset-names: Only allow the following entries:
- phy-reset - phy-reset
- resets: Must contain an entry for each entry in reset-names. - resets: Must contain an entry for each entry in reset-names.
- vbus-supply: power-supply phandle for vbus power source
Example: Example:
......
...@@ -15,6 +15,7 @@ Required properties: ...@@ -15,6 +15,7 @@ Required properties:
- reg : a list of offset + length pairs - reg : a list of offset + length pairs
- reg-names : - reg-names :
* "phy_ctrl" * "phy_ctrl"
* "pmu0" for H3, V3s and A64
* "pmu1" * "pmu1"
* "pmu2" for sun4i, sun6i or sun7i * "pmu2" for sun4i, sun6i or sun7i
- #phy-cells : from the generic phy bindings, must be 1 - #phy-cells : from the generic phy bindings, must be 1
......
...@@ -8,6 +8,8 @@ From RK3368 SoCs, the GRF is divided into two sections, ...@@ -8,6 +8,8 @@ From RK3368 SoCs, the GRF is divided into two sections,
- SGRF, used for general secure system, - SGRF, used for general secure system,
- PMUGRF, used for always on system - PMUGRF, used for always on system
On RK3328 SoCs, the GRF adds a section for USB2PHYGRF,
Required Properties: Required Properties:
- compatible: GRF should be one of the following: - compatible: GRF should be one of the following:
...@@ -23,6 +25,8 @@ Required Properties: ...@@ -23,6 +25,8 @@ Required Properties:
- "rockchip,rk3399-pmugrf", "syscon": for rk3399 - "rockchip,rk3399-pmugrf", "syscon": for rk3399
- compatible: SGRF should be one of the following - compatible: SGRF should be one of the following
- "rockchip,rk3288-sgrf", "syscon": for rk3288 - "rockchip,rk3288-sgrf", "syscon": for rk3288
- compatible: USB2PHYGRF should be one of the followings
- "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/exynos5-pmu.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include <linux/types.h> #include <linux/types.h>
/* LPASS Top register definitions */ /* LPASS Top register definitions */
...@@ -83,7 +83,7 @@ static void exynos_lpass_enable(struct exynos_lpass *lpass) ...@@ -83,7 +83,7 @@ static void exynos_lpass_enable(struct exynos_lpass *lpass)
/* Activate related PADs from retention state */ /* Activate related PADs from retention state */
regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION,
EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR); EXYNOS_WAKEUP_FROM_LOWPWR);
exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET);
exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET); exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET);
......
...@@ -439,6 +439,25 @@ config PHY_STIH407_USB ...@@ -439,6 +439,25 @@ config PHY_STIH407_USB
Enable this support to enable the picoPHY device used by USB2 Enable this support to enable the picoPHY device used by USB2
and USB3 controllers on STMicroelectronics STiH407 SoC families. and USB3 controllers on STMicroelectronics STiH407 SoC families.
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 config PHY_QCOM_UFS
tristate "Qualcomm UFS PHY driver" tristate "Qualcomm UFS PHY driver"
depends on OF && ARCH_QCOM depends on OF && ARCH_QCOM
......
...@@ -50,6 +50,8 @@ obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o ...@@ -50,6 +50,8 @@ obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.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.o
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.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_UFS) += phy-qcom-ufs-qmp-14nm.o
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Broadcom Northstar USB 3.0 PHY Driver * Broadcom Northstar USB 3.0 PHY Driver
* *
* Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl> * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
* Copyright (C) 2016 Broadcom
* *
* All magic values used for initialization (and related comments) were obtained * All magic values used for initialization (and related comments) were obtained
* from Broadcom's SDK: * from Broadcom's SDK:
...@@ -23,6 +24,23 @@ ...@@ -23,6 +24,23 @@
#define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000 /* usecs */ #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
#define BCM_NS_USB3_PHY_PIPE_BLOCK 0x8060
/* Registers of PLL30 block */
#define BCM_NS_USB3_PLL_CONTROL 0x01
#define BCM_NS_USB3_PLLA_CONTROL0 0x0a
#define BCM_NS_USB3_PLLA_CONTROL1 0x0b
/* Registers of TX PMD block */
#define BCM_NS_USB3_TX_PMD_CONTROL1 0x01
/* Registers of PIPE block */
#define BCM_NS_USB3_LFPS_CMP 0x02
#define BCM_NS_USB3_LFPS_DEGLITCH 0x03
enum bcm_ns_family { enum bcm_ns_family {
BCM_NS_UNKNOWN, BCM_NS_UNKNOWN,
BCM_NS_AX, BCM_NS_AX,
...@@ -76,8 +94,10 @@ static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3) ...@@ -76,8 +94,10 @@ static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US)); usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
} }
static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value) static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
u16 value)
{ {
u32 tmp = 0;
int err; int err;
err = bcm_ns_usb3_mii_mng_wait_idle(usb3); err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
...@@ -86,7 +106,11 @@ static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value) ...@@ -86,7 +106,11 @@ static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value)
return err; return err;
} }
writel(value, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); /* 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 0;
} }
...@@ -102,21 +126,22 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) ...@@ -102,21 +126,22 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
udelay(2); udelay(2);
/* USB3 PLL Block */ /* USB3 PLL Block */
err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK);
if (err < 0) if (err < 0)
return err; return err;
/* Assert Ana_Pllseq start */ /* Assert Ana_Pllseq start */
bcm_ns_usb3_mii_mng_write32(usb3, 0x58061000); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x1000);
/* Assert CML Divider ratio to 26 */ /* Assert CML Divider ratio to 26 */
bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL0, 0x6400);
/* Asserting PLL Reset */ /* Asserting PLL Reset */
bcm_ns_usb3_mii_mng_write32(usb3, 0x582ec000); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0xc000);
/* Deaaserting PLL Reset */ /* Deaaserting PLL Reset */
bcm_ns_usb3_mii_mng_write32(usb3, 0x582e8000); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000);
/* Waiting MII Mgt interface idle */ /* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3); bcm_ns_usb3_mii_mng_wait_idle(usb3);
...@@ -125,22 +150,24 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) ...@@ -125,22 +150,24 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
writel(0, usb3->dmp + BCMA_RESET_CTL); writel(0, usb3->dmp + BCMA_RESET_CTL);
/* PLL frequency monitor enable */ /* PLL frequency monitor enable */
bcm_ns_usb3_mii_mng_write32(usb3, 0x58069000); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x9000);
/* PIPE Block */ /* PIPE Block */
bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8060); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PIPE_BLOCK);
/* CMPMAX & CMPMINTH setting */ /* CMPMAX & CMPMINTH setting */
bcm_ns_usb3_mii_mng_write32(usb3, 0x580af30d); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_LFPS_CMP, 0xf30d);
/* DEGLITCH MIN & MAX setting */ /* DEGLITCH MIN & MAX setting */
bcm_ns_usb3_mii_mng_write32(usb3, 0x580e6302); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_LFPS_DEGLITCH, 0x6302);
/* TXPMD block */ /* TXPMD block */
bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8040); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_TX_PMD_BLOCK);
/* Enabling SSC */ /* Enabling SSC */
bcm_ns_usb3_mii_mng_write32(usb3, 0x58061003); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */ /* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3); bcm_ns_usb3_mii_mng_wait_idle(usb3);
...@@ -159,22 +186,24 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3) ...@@ -159,22 +186,24 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
udelay(2); udelay(2);
/* PLL30 block */ /* PLL30 block */
err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_PLL30_BLOCK);
if (err < 0) if (err < 0)
return err; return err;
bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL0, 0x6400);
bcm_ns_usb3_mii_mng_write32(usb3, 0x587e80e0); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, 0x80e0);
bcm_ns_usb3_mii_mng_write32(usb3, 0x580a009c); bcm_ns_usb3_mdio_phy_write(usb3, 0x02, 0x009c);
/* Enable SSC */ /* Enable SSC */
bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8040); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
BCM_NS_USB3_PHY_TX_PMD_BLOCK);
bcm_ns_usb3_mii_mng_write32(usb3, 0x580a21d3); bcm_ns_usb3_mdio_phy_write(usb3, 0x02, 0x21d3);
bcm_ns_usb3_mii_mng_write32(usb3, 0x58061003); bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
/* Waiting MII Mgt interface idle */ /* Waiting MII Mgt interface idle */
bcm_ns_usb3_mii_mng_wait_idle(usb3); bcm_ns_usb3_mii_mng_wait_idle(usb3);
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/exynos5-pmu.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
struct exynos_dp_video_phy_drvdata { struct exynos_dp_video_phy_drvdata {
u32 phy_ctrl_offset; u32 phy_ctrl_offset;
...@@ -36,7 +36,7 @@ static int exynos_dp_video_phy_power_on(struct phy *phy) ...@@ -36,7 +36,7 @@ static int exynos_dp_video_phy_power_on(struct phy *phy)
/* Disable power isolation on DP-PHY */ /* Disable power isolation on DP-PHY */
return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
EXYNOS5_PHY_ENABLE, EXYNOS5_PHY_ENABLE); EXYNOS4_PHY_ENABLE, EXYNOS4_PHY_ENABLE);
} }
static int exynos_dp_video_phy_power_off(struct phy *phy) static int exynos_dp_video_phy_power_off(struct phy *phy)
...@@ -45,7 +45,7 @@ static int exynos_dp_video_phy_power_off(struct phy *phy) ...@@ -45,7 +45,7 @@ static int exynos_dp_video_phy_power_off(struct phy *phy)
/* Enable power isolation on DP-PHY */ /* Enable power isolation on DP-PHY */
return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
EXYNOS5_PHY_ENABLE, 0); EXYNOS4_PHY_ENABLE, 0);
} }
static const struct phy_ops exynos_dp_video_phy_ops = { static const struct phy_ops exynos_dp_video_phy_ops = {
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mfd/syscon/exynos4-pmu.h>
#include <linux/mfd/syscon/exynos5-pmu.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -21,6 +19,7 @@ ...@@ -21,6 +19,7 @@
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
enum exynos_mipi_phy_id { enum exynos_mipi_phy_id {
...@@ -64,7 +63,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = { ...@@ -64,7 +63,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = {
{ {
/* EXYNOS_MIPI_PHY_ID_CSIS0 */ /* EXYNOS_MIPI_PHY_ID_CSIS0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
.enable_val = EXYNOS4_MIPI_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0), .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS4_MIPI_PHY_SRESETN, .resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
...@@ -73,7 +72,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = { ...@@ -73,7 +72,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM0 */ /* EXYNOS_MIPI_PHY_ID_DSIM0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
.enable_val = EXYNOS4_MIPI_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0), .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS4_MIPI_PHY_MRESETN, .resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
...@@ -82,7 +81,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = { ...@@ -82,7 +81,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_CSIS1 */ /* EXYNOS_MIPI_PHY_ID_CSIS1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1,
.enable_val = EXYNOS4_MIPI_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1), .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS4_MIPI_PHY_SRESETN, .resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
...@@ -91,7 +90,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = { ...@@ -91,7 +90,7 @@ static const struct mipi_phy_device_desc s5pv210_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM1 */ /* EXYNOS_MIPI_PHY_ID_DSIM1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1,
.enable_val = EXYNOS4_MIPI_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1), .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS4_MIPI_PHY_MRESETN, .resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
...@@ -109,47 +108,47 @@ static const struct mipi_phy_device_desc exynos5420_mipi_phy = { ...@@ -109,47 +108,47 @@ static const struct mipi_phy_device_desc exynos5420_mipi_phy = {
{ {
/* EXYNOS_MIPI_PHY_ID_CSIS0 */ /* EXYNOS_MIPI_PHY_ID_CSIS0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL, .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN, .resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
.resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL, .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU, .resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM0 */ /* EXYNOS_MIPI_PHY_ID_DSIM0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL, .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN, .resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
.resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL, .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU, .resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, { }, {
/* EXYNOS_MIPI_PHY_ID_CSIS1 */ /* EXYNOS_MIPI_PHY_ID_CSIS1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL, .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN, .resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
.resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL, .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU, .resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM1 */ /* EXYNOS_MIPI_PHY_ID_DSIM1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL, .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN, .resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
.resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL, .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU, .resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, { }, {
/* EXYNOS_MIPI_PHY_ID_CSIS2 */ /* EXYNOS_MIPI_PHY_ID_CSIS2 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5420_MIPI_PHY2_CONTROL, .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(2),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN, .resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
.resetn_reg = EXYNOS5420_MIPI_PHY2_CONTROL, .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(2),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU, .resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, },
}, },
...@@ -172,8 +171,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = { ...@@ -172,8 +171,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
{ {
/* EXYNOS_MIPI_PHY_ID_CSIS0 */ /* EXYNOS_MIPI_PHY_ID_CSIS0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL, .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0), .resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON, .resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
...@@ -181,8 +180,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = { ...@@ -181,8 +180,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM0 */ /* EXYNOS_MIPI_PHY_ID_DSIM0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL, .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0), .resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY, .resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
...@@ -190,8 +189,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = { ...@@ -190,8 +189,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_CSIS1 */ /* EXYNOS_MIPI_PHY_ID_CSIS1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL, .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(1), .resetn_val = BIT(1),
.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON, .resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
...@@ -199,8 +198,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = { ...@@ -199,8 +198,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_DSIM1 */ /* EXYNOS_MIPI_PHY_ID_DSIM1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL, .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(1), .resetn_val = BIT(1),
.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY, .resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
...@@ -208,8 +207,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = { ...@@ -208,8 +207,8 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
}, { }, {
/* EXYNOS_MIPI_PHY_ID_CSIS2 */ /* EXYNOS_MIPI_PHY_ID_CSIS2 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE, .coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE, .enable_val = EXYNOS4_PHY_ENABLE,
.enable_reg = EXYNOS5433_MIPI_PHY2_CONTROL, .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(2),
.enable_map = EXYNOS_MIPI_REGMAP_PMU, .enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0), .resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_CAM1_MIPI_DPHY_CON, .resetn_reg = EXYNOS5433_SYSREG_CAM1_MIPI_DPHY_CON,
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/init.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
...@@ -228,7 +228,6 @@ static const struct of_device_id exynos_pcie_phy_match[] = { ...@@ -228,7 +228,6 @@ static const struct of_device_id exynos_pcie_phy_match[] = {
}, },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, exynos_pcie_phy_match);
static int exynos_pcie_phy_probe(struct platform_device *pdev) static int exynos_pcie_phy_probe(struct platform_device *pdev)
{ {
...@@ -278,8 +277,5 @@ static struct platform_driver exynos_pcie_phy_driver = { ...@@ -278,8 +277,5 @@ static struct platform_driver exynos_pcie_phy_driver = {
.name = "exynos_pcie_phy", .name = "exynos_pcie_phy",
} }
}; };
module_platform_driver(exynos_pcie_phy_driver);
MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC PCIe PHY driver"); builtin_platform_driver(exynos_pcie_phy_driver);
MODULE_AUTHOR("Jaehoon Chung <jh80.chung@samsung.com>");
MODULE_LICENSE("GPL v2");
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/exynos5-pmu.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
/* Exynos USB PHY registers */ /* Exynos USB PHY registers */
#define EXYNOS5_FSEL_9MHZ6 0x0 #define EXYNOS5_FSEL_9MHZ6 0x0
...@@ -235,10 +235,10 @@ static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst, ...@@ -235,10 +235,10 @@ static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst,
if (!inst->reg_pmu) if (!inst->reg_pmu)
return; return;
val = on ? 0 : EXYNOS5_PHY_ENABLE; val = on ? 0 : EXYNOS4_PHY_ENABLE;
regmap_update_bits(inst->reg_pmu, inst->pmu_offset, regmap_update_bits(inst->reg_pmu, inst->pmu_offset,
EXYNOS5_PHY_ENABLE, val); EXYNOS4_PHY_ENABLE, val);
} }
/* /*
......
...@@ -81,9 +81,9 @@ ...@@ -81,9 +81,9 @@
#define REG_ADP_BC_ACA_PIN_GND BIT(25) #define REG_ADP_BC_ACA_PIN_GND BIT(25)
#define REG_ADP_BC_ACA_PIN_FLOAT BIT(26) #define REG_ADP_BC_ACA_PIN_FLOAT BIT(26)
#define REG_DBG_UART 0x14 #define REG_DBG_UART 0x10
#define REG_TEST 0x18 #define REG_TEST 0x14
#define REG_TEST_DATA_IN_MASK GENMASK(3, 0) #define REG_TEST_DATA_IN_MASK GENMASK(3, 0)
#define REG_TEST_EN_MASK GENMASK(7, 4) #define REG_TEST_EN_MASK GENMASK(7, 4)
#define REG_TEST_ADDR_MASK GENMASK(11, 8) #define REG_TEST_ADDR_MASK GENMASK(11, 8)
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
#define REG_TEST_DATA_OUT_MASK GENMASK(19, 16) #define REG_TEST_DATA_OUT_MASK GENMASK(19, 16)
#define REG_TEST_DISABLE_ID_PULLUP BIT(20) #define REG_TEST_DISABLE_ID_PULLUP BIT(20)
#define REG_TUNE 0x1c #define REG_TUNE 0x18
#define REG_TUNE_TX_RES_TUNE_MASK GENMASK(1, 0) #define REG_TUNE_TX_RES_TUNE_MASK GENMASK(1, 0)
#define REG_TUNE_TX_HSXV_TUNE_MASK GENMASK(3, 2) #define REG_TUNE_TX_HSXV_TUNE_MASK GENMASK(3, 2)
#define REG_TUNE_TX_VREF_TUNE_MASK GENMASK(7, 4) #define REG_TUNE_TX_VREF_TUNE_MASK GENMASK(7, 4)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -395,7 +396,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -395,7 +396,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
struct rcar_gen3_chan *channel; struct rcar_gen3_chan *channel;
struct phy_provider *provider; struct phy_provider *provider;
struct resource *res; struct resource *res;
int irq; int irq, ret = 0;
if (!dev->of_node) { if (!dev->of_node) {
dev_err(dev, "This driver needs device tree\n"); dev_err(dev, "This driver needs device tree\n");
...@@ -434,17 +435,24 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -434,17 +435,24 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
} }
} }
/* devm_phy_create() will call pm_runtime_enable(dev); */ /*
* 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);
channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops); channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops);
if (IS_ERR(channel->phy)) { if (IS_ERR(channel->phy)) {
dev_err(dev, "Failed to create USB2 PHY\n"); dev_err(dev, "Failed to create USB2 PHY\n");
return PTR_ERR(channel->phy); ret = PTR_ERR(channel->phy);
goto error;
} }
channel->vbus = devm_regulator_get_optional(dev, "vbus"); channel->vbus = devm_regulator_get_optional(dev, "vbus");
if (IS_ERR(channel->vbus)) { if (IS_ERR(channel->vbus)) {
if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) {
return PTR_ERR(channel->vbus); ret = PTR_ERR(channel->vbus);
goto error;
}
channel->vbus = NULL; channel->vbus = NULL;
} }
...@@ -454,15 +462,22 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -454,15 +462,22 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(provider)) { if (IS_ERR(provider)) {
dev_err(dev, "Failed to register PHY provider\n"); dev_err(dev, "Failed to register PHY provider\n");
ret = PTR_ERR(provider);
goto error;
} else if (channel->has_otg) { } else if (channel->has_otg) {
int ret; int ret;
ret = device_create_file(dev, &dev_attr_role); ret = device_create_file(dev, &dev_attr_role);
if (ret < 0) if (ret < 0)
return ret; goto error;
} }
return PTR_ERR_OR_ZERO(provider); return 0;
error:
pm_runtime_disable(dev);
return ret;
} }
static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
...@@ -472,6 +487,8 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) ...@@ -472,6 +487,8 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
if (channel->has_otg) if (channel->has_otg)
device_remove_file(&pdev->dev, &dev_attr_role); device_remove_file(&pdev->dev, &dev_attr_role);
pm_runtime_disable(&pdev->dev);
return 0; return 0;
}; };
......
...@@ -554,8 +554,7 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) ...@@ -554,8 +554,7 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
case USB_CHG_STATE_DETECTED: case USB_CHG_STATE_DETECTED:
switch (rphy->chg_type) { switch (rphy->chg_type) {
case POWER_SUPPLY_TYPE_USB: case POWER_SUPPLY_TYPE_USB:
dev_dbg(&rport->phy->dev, dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
"sdp cable is connecetd\n");
rockchip_usb2phy_power_on(rport->phy); rockchip_usb2phy_power_on(rport->phy);
rport->state = OTG_STATE_B_PERIPHERAL; rport->state = OTG_STATE_B_PERIPHERAL;
notify_charger = true; notify_charger = true;
...@@ -563,16 +562,14 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) ...@@ -563,16 +562,14 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
cable = EXTCON_CHG_USB_SDP; cable = EXTCON_CHG_USB_SDP;
break; break;
case POWER_SUPPLY_TYPE_USB_DCP: case POWER_SUPPLY_TYPE_USB_DCP:
dev_dbg(&rport->phy->dev, dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
"dcp cable is connecetd\n");
rockchip_usb2phy_power_off(rport->phy); rockchip_usb2phy_power_off(rport->phy);
notify_charger = true; notify_charger = true;
sch_work = true; sch_work = true;
cable = EXTCON_CHG_USB_DCP; cable = EXTCON_CHG_USB_DCP;
break; break;
case POWER_SUPPLY_TYPE_USB_CDP: case POWER_SUPPLY_TYPE_USB_CDP:
dev_dbg(&rport->phy->dev, dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
"cdp cable is connecetd\n");
rockchip_usb2phy_power_on(rport->phy); rockchip_usb2phy_power_on(rport->phy);
rport->state = OTG_STATE_B_PERIPHERAL; rport->state = OTG_STATE_B_PERIPHERAL;
notify_charger = true; notify_charger = true;
...@@ -1141,6 +1138,49 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) ...@@ -1141,6 +1138,49 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
return ret; return ret;
} }
static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
{
.reg = 0x100,
.num_ports = 2,
.clkout_ctl = { 0x108, 4, 4, 1, 0 },
.port_cfgs = {
[USB2PHY_PORT_OTG] = {
.phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
.bvalid_det_en = { 0x0110, 2, 2, 0, 1 },
.bvalid_det_st = { 0x0114, 2, 2, 0, 1 },
.bvalid_det_clr = { 0x0118, 2, 2, 0, 1 },
.ls_det_en = { 0x0110, 0, 0, 0, 1 },
.ls_det_st = { 0x0114, 0, 0, 0, 1 },
.ls_det_clr = { 0x0118, 0, 0, 0, 1 },
.utmi_avalid = { 0x0120, 10, 10, 0, 1 },
.utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
.utmi_ls = { 0x0120, 5, 4, 0, 1 },
},
[USB2PHY_PORT_HOST] = {
.phy_sus = { 0x104, 15, 0, 0, 0x1d1 },
.ls_det_en = { 0x110, 1, 1, 0, 1 },
.ls_det_st = { 0x114, 1, 1, 0, 1 },
.ls_det_clr = { 0x118, 1, 1, 0, 1 },
.utmi_ls = { 0x120, 17, 16, 0, 1 },
.utmi_hstdet = { 0x120, 19, 19, 0, 1 }
}
},
.chg_det = {
.opmode = { 0x0100, 3, 0, 5, 1 },
.cp_det = { 0x0120, 24, 24, 0, 1 },
.dcp_det = { 0x0120, 23, 23, 0, 1 },
.dp_det = { 0x0120, 25, 25, 0, 1 },
.idm_sink_en = { 0x0108, 8, 8, 0, 1 },
.idp_sink_en = { 0x0108, 7, 7, 0, 1 },
.idp_src_en = { 0x0108, 9, 9, 0, 1 },
.rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
.vdm_src_en = { 0x0108, 12, 12, 0, 1 },
.vdp_src_en = { 0x0108, 11, 11, 0, 1 },
},
},
{ /* sentinel */ }
};
static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = { static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
{ {
.reg = 0x700, .reg = 0x700,
...@@ -1223,6 +1263,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { ...@@ -1223,6 +1263,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
}; };
static const struct of_device_id rockchip_usb2phy_dt_match[] = { static const struct of_device_id rockchip_usb2phy_dt_match[] = {
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
{} {}
......
...@@ -66,6 +66,7 @@ struct rockchip_usb_phy { ...@@ -66,6 +66,7 @@ struct rockchip_usb_phy {
struct phy *phy; struct phy *phy;
bool uart_enabled; bool uart_enabled;
struct reset_control *reset; struct reset_control *reset;
struct regulator *vbus;
}; };
static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
...@@ -88,6 +89,9 @@ static void rockchip_usb_phy480m_disable(struct clk_hw *hw) ...@@ -88,6 +89,9 @@ static void rockchip_usb_phy480m_disable(struct clk_hw *hw)
struct rockchip_usb_phy, struct rockchip_usb_phy,
clk480m_hw); clk480m_hw);
if (phy->vbus)
regulator_disable(phy->vbus);
/* Power down usb phy analog blocks by set siddq 1 */ /* Power down usb phy analog blocks by set siddq 1 */
rockchip_usb_phy_power(phy, 1); rockchip_usb_phy_power(phy, 1);
} }
...@@ -143,6 +147,14 @@ static int rockchip_usb_phy_power_on(struct phy *_phy) ...@@ -143,6 +147,14 @@ static int rockchip_usb_phy_power_on(struct phy *_phy)
if (phy->uart_enabled) if (phy->uart_enabled)
return -EBUSY; return -EBUSY;
if (phy->vbus) {
int ret;
ret = regulator_enable(phy->vbus);
if (ret)
return ret;
}
return clk_prepare_enable(phy->clk480m); return clk_prepare_enable(phy->clk480m);
} }
...@@ -268,6 +280,13 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, ...@@ -268,6 +280,13 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
} }
phy_set_drvdata(rk_phy->phy, rk_phy); phy_set_drvdata(rk_phy->phy, rk_phy);
rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
if (IS_ERR(rk_phy->vbus)) {
if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
return PTR_ERR(rk_phy->vbus);
rk_phy->vbus = NULL;
}
/* /*
* When acting as uart-pipe, just keep clock on otherwise * When acting as uart-pipe, just keep clock on otherwise
* only power up usb phy when it use, so disable it when init * only power up usb phy when it use, so disable it when init
......
...@@ -49,12 +49,14 @@ ...@@ -49,12 +49,14 @@
#define REG_PHYBIST 0x08 #define REG_PHYBIST 0x08
#define REG_PHYTUNE 0x0c #define REG_PHYTUNE 0x0c
#define REG_PHYCTL_A33 0x10 #define REG_PHYCTL_A33 0x10
#define REG_PHY_UNK_H3 0x20 #define REG_PHY_OTGCTL 0x20
#define REG_PMU_UNK1 0x10 #define REG_PMU_UNK1 0x10
#define PHYCTL_DATA BIT(7) #define PHYCTL_DATA BIT(7)
#define OTGCTL_ROUTE_MUSB BIT(0)
#define SUNXI_AHB_ICHR8_EN BIT(10) #define SUNXI_AHB_ICHR8_EN BIT(10)
#define SUNXI_AHB_INCR4_BURST_EN BIT(9) #define SUNXI_AHB_INCR4_BURST_EN BIT(9)
#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) #define SUNXI_AHB_INCRX_ALIGN_EN BIT(8)
...@@ -110,6 +112,7 @@ struct sun4i_usb_phy_cfg { ...@@ -110,6 +112,7 @@ struct sun4i_usb_phy_cfg {
u8 phyctl_offset; u8 phyctl_offset;
bool dedicated_clocks; bool dedicated_clocks;
bool enable_pmu_unk1; bool enable_pmu_unk1;
bool phy0_dual_route;
}; };
struct sun4i_usb_phy_data { struct sun4i_usb_phy_data {
...@@ -188,10 +191,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, ...@@ -188,10 +191,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
spin_lock_irqsave(&phy_data->reg_lock, flags); spin_lock_irqsave(&phy_data->reg_lock, flags);
if (phy_data->cfg->type == sun8i_a33_phy || if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
phy_data->cfg->type == sun50i_a64_phy || /* SoCs newer than A33 need us to set phyctl to 0 explicitly */
phy_data->cfg->type == sun8i_v3s_phy) {
/* A33 or A64 needs us to set phyctl to 0 explicitly */
writel(0, phyctl); writel(0, phyctl);
} }
...@@ -271,23 +272,16 @@ static int sun4i_usb_phy_init(struct phy *_phy) ...@@ -271,23 +272,16 @@ static int sun4i_usb_phy_init(struct phy *_phy)
writel(val & ~2, phy->pmu + REG_PMU_UNK1); writel(val & ~2, phy->pmu + REG_PMU_UNK1);
} }
if (data->cfg->type == sun8i_h3_phy) { /* Enable USB 45 Ohm resistor calibration */
if (phy->index == 0) { if (phy->index == 0)
val = readl(data->base + REG_PHY_UNK_H3); sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
writel(val & ~1, data->base + REG_PHY_UNK_H3);
}
} else {
/* Enable USB 45 Ohm resistor calibration */
if (phy->index == 0)
sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
/* Adjust PHY's magnitude and rate */ /* Adjust PHY's magnitude and rate */
sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
/* Disconnect threshold adjustment */ /* Disconnect threshold adjustment */
sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
data->cfg->disc_thresh, 2); data->cfg->disc_thresh, 2);
}
sun4i_usb_phy_passby(phy, 1); sun4i_usb_phy_passby(phy, 1);
...@@ -486,6 +480,21 @@ static const struct phy_ops sun4i_usb_phy_ops = { ...@@ -486,6 +480,21 @@ static const struct phy_ops sun4i_usb_phy_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, int id_det)
{
u32 regval;
regval = readl(data->base + REG_PHY_OTGCTL);
if (id_det == 0) {
/* Host mode. Route phy0 to EHCI/OHCI */
regval &= ~OTGCTL_ROUTE_MUSB;
} else {
/* Peripheral mode. Route phy0 to MUSB */
regval |= OTGCTL_ROUTE_MUSB;
}
writel(regval, data->base + REG_PHY_OTGCTL);
}
static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
{ {
struct sun4i_usb_phy_data *data = struct sun4i_usb_phy_data *data =
...@@ -546,6 +555,10 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) ...@@ -546,6 +555,10 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
sun4i_usb_phy0_set_vbus_detect(phy0, 1); sun4i_usb_phy0_set_vbus_detect(phy0, 1);
mutex_unlock(&phy0->mutex); mutex_unlock(&phy0->mutex);
} }
/* Re-route PHY0 if necessary */
if (data->cfg->phy0_dual_route)
sun4i_usb_phy0_reroute(data, id_det);
} }
if (vbus_notify) if (vbus_notify)
...@@ -700,7 +713,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) ...@@ -700,7 +713,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->reset); return PTR_ERR(phy->reset);
} }
if (i) { /* No pmu for usbc0 */ if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */
snprintf(name, sizeof(name), "pmu%d", i); snprintf(name, sizeof(name), "pmu%d", i);
res = platform_get_resource_byname(pdev, res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, name); IORESOURCE_MEM, name);
...@@ -823,8 +836,10 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { ...@@ -823,8 +836,10 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
.num_phys = 4, .num_phys = 4,
.type = sun8i_h3_phy, .type = sun8i_h3_phy,
.disc_thresh = 3, .disc_thresh = 3,
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true, .dedicated_clocks = true,
.enable_pmu_unk1 = true, .enable_pmu_unk1 = true,
.phy0_dual_route = true,
}; };
static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
...@@ -843,6 +858,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { ...@@ -843,6 +858,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
.phyctl_offset = REG_PHYCTL_A33, .phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true, .dedicated_clocks = true,
.enable_pmu_unk1 = true, .enable_pmu_unk1 = true,
.phy0_dual_route = true,
}; };
static const struct of_device_id sun4i_usb_phy_of_match[] = { static const struct of_device_id sun4i_usb_phy_of_match[] = {
......
...@@ -12,36 +12,6 @@ ...@@ -12,36 +12,6 @@
#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ #ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
#define _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ #define _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
/* Exynos5 PMU register definitions */
#define EXYNOS5_HDMI_PHY_CONTROL (0x700)
#define EXYNOS5_USBDRD_PHY_CONTROL (0x704)
/* Exynos5250 specific register definitions */
#define EXYNOS5_USBHOST_PHY_CONTROL (0x708)
#define EXYNOS5_EFNAND_PHY_CONTROL (0x70c)
#define EXYNOS5_MIPI_PHY0_CONTROL (0x710)
#define EXYNOS5_MIPI_PHY1_CONTROL (0x714)
#define EXYNOS5_ADC_PHY_CONTROL (0x718)
#define EXYNOS5_MTCADC_PHY_CONTROL (0x71c)
#define EXYNOS5_DPTX_PHY_CONTROL (0x720)
#define EXYNOS5_SATA_PHY_CONTROL (0x724)
/* Exynos5420 specific register definitions */
#define EXYNOS5420_USBDRD1_PHY_CONTROL (0x708)
#define EXYNOS5420_USBHOST_PHY_CONTROL (0x70c)
#define EXYNOS5420_MIPI_PHY0_CONTROL (0x714)
#define EXYNOS5420_MIPI_PHY1_CONTROL (0x718)
#define EXYNOS5420_MIPI_PHY2_CONTROL (0x71c)
#define EXYNOS5420_ADC_PHY_CONTROL (0x720)
#define EXYNOS5420_MTCADC_PHY_CONTROL (0x724)
#define EXYNOS5420_DPTX_PHY_CONTROL (0x728)
/* Exynos5433 specific register definitions */
#define EXYNOS5433_USBHOST30_PHY_CONTROL (0x728)
#define EXYNOS5433_MIPI_PHY0_CONTROL (0x710)
#define EXYNOS5433_MIPI_PHY1_CONTROL (0x714)
#define EXYNOS5433_MIPI_PHY2_CONTROL (0x718)
#define EXYNOS5_PHY_ENABLE BIT(0) #define EXYNOS5_PHY_ENABLE BIT(0)
#define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1)
#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) #define EXYNOS5_MIPI_PHY_M_RESETN BIT(2)
......
/* /*
* Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * Copyright (c) 2010-2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
* EXYNOS - Power management unit definition * EXYNOS - Power management unit definition
...@@ -50,6 +50,14 @@ ...@@ -50,6 +50,14 @@
#define S5P_WAKEUP_MASK 0x0608 #define S5P_WAKEUP_MASK 0x0608
#define S5P_WAKEUP_MASK2 0x0614 #define S5P_WAKEUP_MASK2 0x0614
/* MIPI_PHYn_CONTROL, valid for Exynos3250, Exynos4, Exynos5250 and Exynos5433 */
#define EXYNOS4_MIPI_PHY_CONTROL(n) (0x0710 + (n) * 4)
/* Phy enable bit, common for all phy registers, not only MIPI */
#define EXYNOS4_PHY_ENABLE (1 << 0)
#define EXYNOS4_MIPI_PHY_SRESETN (1 << 1)
#define EXYNOS4_MIPI_PHY_MRESETN (1 << 2)
#define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1)
#define S5P_INFORM0 0x0800 #define S5P_INFORM0 0x0800
#define S5P_INFORM1 0x0804 #define S5P_INFORM1 0x0804
#define S5P_INFORM5 0x0814 #define S5P_INFORM5 0x0814
...@@ -342,6 +350,8 @@ ...@@ -342,6 +350,8 @@
#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 #define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408
#define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C #define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C
#define EXYNOS5_USBDRD_PHY_CONTROL 0x0704
#define EXYNOS5_DPTX_PHY_CONTROL 0x0720
#define EXYNOS5_USE_RETENTION BIT(4) #define EXYNOS5_USE_RETENTION BIT(4)
#define EXYNOS5_SYS_WDTRESET (1 << 20) #define EXYNOS5_SYS_WDTRESET (1 << 20)
...@@ -495,6 +505,9 @@ ...@@ -495,6 +505,9 @@
#define EXYNOS5420_KFC_CORE_RESET(_nr) \ #define EXYNOS5420_KFC_CORE_RESET(_nr) \
((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr)) ((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
#define EXYNOS5420_USBDRD1_PHY_CONTROL 0x0708
#define EXYNOS5420_MIPI_PHY_CONTROL(n) (0x0714 + (n) * 4)
#define EXYNOS5420_DPTX_PHY_CONTROL 0x0728
#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020 #define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020
#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024 #define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024
#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028 #define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028
...@@ -632,6 +645,7 @@ ...@@ -632,6 +645,7 @@
| EXYNOS5420_KFC_USE_STANDBY_WFI3) | EXYNOS5420_KFC_USE_STANDBY_WFI3)
/* For EXYNOS5433 */ /* For EXYNOS5433 */
#define EXYNOS5433_USBHOST30_PHY_CONTROL (0x0728)
#define EXYNOS5433_PAD_RETENTION_AUD_OPTION (0x3028) #define EXYNOS5433_PAD_RETENTION_AUD_OPTION (0x3028)
#define EXYNOS5433_PAD_RETENTION_MMC2_OPTION (0x30C8) #define EXYNOS5433_PAD_RETENTION_MMC2_OPTION (0x30C8)
#define EXYNOS5433_PAD_RETENTION_TOP_OPTION (0x3108) #define EXYNOS5433_PAD_RETENTION_TOP_OPTION (0x3108)
......
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