summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt39
-rw-r--r--Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt1
-rw-r--r--drivers/phy/Kconfig9
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/phy-bcm-nsp-usb3.c177
-rw-r--r--drivers/phy/phy-exynos-dp-video.c1
-rw-r--r--drivers/phy/phy-exynos-mipi-video.c32
-rw-r--r--drivers/phy/phy-exynos-pcie.c12
-rw-r--r--drivers/phy/phy-exynos5-usbdrd.c1
-rw-r--r--drivers/phy/phy-meson8b-usb2.c6
-rw-r--r--drivers/phy/phy-sun4i-usb.c57
-rw-r--r--include/linux/mfd/syscon/exynos5-pmu.h30
-rw-r--r--include/linux/soc/samsung/exynos-regs-pmu.h15
13 files changed, 77 insertions, 304 deletions
diff --git a/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt b/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt
deleted file mode 100644
index e68ae5dec9c9..000000000000
--- a/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Broadcom USB3 phy binding for northstar plus SoC
-The USB3 phy is internal to the SoC and is accessed using mdio interface.
-
-Required mdio bus properties:
-- reg: Should be 0x0 for SoC internal USB3 phy
-- #address-cells: must be 1
-- #size-cells: must be 0
-
-Required USB3 PHY properties:
-- compatible: should be "brcm,nsp-usb3-phy"
-- reg: USB3 Phy address on SoC internal MDIO bus and it should be 0x10.
-- usb3-ctrl-syscon: handler of syscon node defining physical address
- of usb3 control register.
-- #phy-cells: must be 0
-
-Required usb3 control properties:
-- compatible: should be "brcm,nsp-usb3-ctrl"
-- reg: offset and length of the control registers
-
-Example:
-
- mdio@0 {
- reg = <0x0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_phy: usb-phy@10 {
- compatible = "brcm,nsp-usb3-phy";
- reg = <0x10>;
- usb3-ctrl-syscon = <&usb3_ctrl>;
- #phy-cells = <0>;
- status = "disabled";
- };
- };
-
- usb3_ctrl: syscon@104408 {
- compatible = "brcm,nsp-usb3-ctrl", "syscon";
- reg = <0x104408 0x3fc>;
- };
diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
index e42334258185..005bc22938ff 100644
--- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
@@ -15,6 +15,7 @@ Required properties:
- reg : a list of offset + length pairs
- reg-names :
* "phy_ctrl"
+ * "pmu0" for H3, V3s and A64
* "pmu1"
* "pmu2" for sun4i, sun6i or sun7i
- #phy-cells : from the generic phy bindings, must be 1
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index dc5277ad1b5a..005cadb7a3f8 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -449,6 +449,7 @@ config PHY_QCOM_UFS
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
@@ -510,12 +511,4 @@ config PHY_MESON8B_USB2
and GXBB SoCs.
If unsure, say N.
-config PHY_NSP_USB3
- tristate "Broadcom NorthStar plus USB3 PHY driver"
- depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
- select GENERIC_PHY
- default ARCH_BCM_NSP
- help
- Enable this to support the Broadcom Northstar plus USB3 PHY.
- If unsure, say N.
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index e7b0feb1e125..dd8f3b5d2918 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -62,4 +62,3 @@ 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_PHY_NSP_USB3) += phy-bcm-nsp-usb3.o
diff --git a/drivers/phy/phy-bcm-nsp-usb3.c b/drivers/phy/phy-bcm-nsp-usb3.c
deleted file mode 100644
index 49024eaa5545..000000000000
--- a/drivers/phy/phy-bcm-nsp-usb3.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mdio.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/phy/phy.h>
-#include <linux/regmap.h>
-
-#define NSP_USB3_RST_CTRL_OFFSET 0x3f8
-
-/* mdio reg access */
-#define NSP_USB3_PHY_BASE_ADDR_REG 0x1f
-
-#define NSP_USB3_PHY_PLL30_BLOCK 0x8000
-#define NSP_USB3_PLL_CONTROL 0x01
-#define NSP_USB3_PLLA_CONTROL0 0x0a
-#define NSP_USB3_PLLA_CONTROL1 0x0b
-
-#define NSP_USB3_PHY_TX_PMD_BLOCK 0x8040
-#define NSP_USB3_TX_PMD_CONTROL1 0x01
-
-#define NSP_USB3_PHY_PIPE_BLOCK 0x8060
-#define NSP_USB3_LFPS_CMP 0x02
-#define NSP_USB3_LFPS_DEGLITCH 0x03
-
-struct nsp_usb3_phy {
- struct regmap *usb3_ctrl;
- struct phy *phy;
- struct mdio_device *mdiodev;
-};
-
-static int nsp_usb3_phy_init(struct phy *phy)
-{
- struct nsp_usb3_phy *iphy = phy_get_drvdata(phy);
- struct mii_bus *bus = iphy->mdiodev->bus;
- int addr = iphy->mdiodev->addr;
- u32 data;
- int rc;
-
- rc = regmap_read(iphy->usb3_ctrl, 0, &data);
- if (rc)
- return rc;
- data |= 1;
- rc = regmap_write(iphy->usb3_ctrl, 0, data);
- if (rc)
- return rc;
-
- rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 1);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
- NSP_USB3_PHY_PLL30_BLOCK);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x1000);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL0, 0x6400);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0xc000);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0x8000);
- if (rc)
- return rc;
-
- rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 0);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x9000);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
- NSP_USB3_PHY_PIPE_BLOCK);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_CMP, 0xf30d);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_DEGLITCH, 0x6302);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
- NSP_USB3_PHY_TX_PMD_BLOCK);
- if (rc)
- return rc;
-
- rc = mdiobus_write(bus, addr, NSP_USB3_TX_PMD_CONTROL1, 0x1003);
-
- return rc;
-}
-
-static struct phy_ops nsp_usb3_phy_ops = {
- .init = nsp_usb3_phy_init,
- .owner = THIS_MODULE,
-};
-
-static int nsp_usb3_phy_probe(struct mdio_device *mdiodev)
-{
- struct device *dev = &mdiodev->dev;
- struct phy_provider *provider;
- struct nsp_usb3_phy *iphy;
-
- iphy = devm_kzalloc(dev, sizeof(*iphy), GFP_KERNEL);
- if (!iphy)
- return -ENOMEM;
- iphy->mdiodev = mdiodev;
-
- iphy->usb3_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "usb3-ctrl-syscon");
- if (IS_ERR(iphy->usb3_ctrl))
- return PTR_ERR(iphy->usb3_ctrl);
-
- iphy->phy = devm_phy_create(dev, dev->of_node, &nsp_usb3_phy_ops);
- if (IS_ERR(iphy->phy)) {
- dev_err(dev, "failed to create PHY\n");
- return PTR_ERR(iphy->phy);
- }
-
- phy_set_drvdata(iphy->phy, iphy);
-
- provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- if (IS_ERR(provider)) {
- dev_err(dev, "could not register PHY provider\n");
- return PTR_ERR(provider);
- }
-
- return 0;
-}
-
-static const struct of_device_id nsp_usb3_phy_of_match[] = {
- {.compatible = "brcm,nsp-usb3-phy",},
- { /* sentinel */ }
-};
-
-static struct mdio_driver nsp_usb3_phy_driver = {
- .mdiodrv = {
- .driver = {
- .name = "nsp-usb3-phy",
- .of_match_table = nsp_usb3_phy_of_match,
- },
- },
- .probe = nsp_usb3_phy_probe,
-};
-
-mdio_module_driver(nsp_usb3_phy_driver);
-
-MODULE_DESCRIPTION("Broadcom NSP USB3 PHY driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com");
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
index 34b06154e5d9..d72193188980 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -20,6 +20,7 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-regs-pmu.h>
struct exynos_dp_video_phy_drvdata {
u32 phy_ctrl_offset;
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
index 6bee04cc4d53..acef1d92691e 100644
--- a/drivers/phy/phy-exynos-mipi-video.c
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -12,7 +12,6 @@
#include <linux/err.h>
#include <linux/io.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/of.h>
@@ -21,6 +20,7 @@
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
+#include <linux/soc/samsung/exynos-regs-pmu.h>
#include <linux/mfd/syscon.h>
enum exynos_mipi_phy_id {
@@ -110,46 +110,46 @@ static const struct mipi_phy_device_desc exynos5420_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_CSIS0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+ .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
- .resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+ .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, {
/* EXYNOS_MIPI_PHY_ID_DSIM0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+ .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN,
- .resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+ .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(0),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, {
/* EXYNOS_MIPI_PHY_ID_CSIS1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+ .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
- .resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+ .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, {
/* EXYNOS_MIPI_PHY_ID_DSIM1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+ .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN,
- .resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+ .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(1),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
}, {
/* EXYNOS_MIPI_PHY_ID_CSIS2 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5420_MIPI_PHY2_CONTROL,
+ .enable_reg = EXYNOS5420_MIPI_PHY_CONTROL(2),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
- .resetn_reg = EXYNOS5420_MIPI_PHY2_CONTROL,
+ .resetn_reg = EXYNOS5420_MIPI_PHY_CONTROL(2),
.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
},
},
@@ -173,7 +173,7 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_CSIS0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL,
+ .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
@@ -182,7 +182,7 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_DSIM0 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL,
+ .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
@@ -191,7 +191,7 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_CSIS1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL,
+ .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(1),
.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
@@ -200,7 +200,7 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_DSIM1 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL,
+ .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(1),
.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
@@ -209,7 +209,7 @@ static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
/* EXYNOS_MIPI_PHY_ID_CSIS2 */
.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
.enable_val = EXYNOS5_PHY_ENABLE,
- .enable_reg = EXYNOS5433_MIPI_PHY2_CONTROL,
+ .enable_reg = EXYNOS4_MIPI_PHY_CONTROL(2),
.enable_map = EXYNOS_MIPI_REGMAP_PMU,
.resetn_val = BIT(0),
.resetn_reg = EXYNOS5433_SYSREG_CAM1_MIPI_DPHY_CON,
diff --git a/drivers/phy/phy-exynos-pcie.c b/drivers/phy/phy-exynos-pcie.c
index 4f60b83641d5..a89c12faff39 100644
--- a/drivers/phy/phy-exynos-pcie.c
+++ b/drivers/phy/phy-exynos-pcie.c
@@ -14,8 +14,8 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iopoll.h>
+#include <linux/init.h>
#include <linux/mfd/syscon.h>
-#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -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)
{
@@ -254,8 +253,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
exynos_phy->blk_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(exynos_phy->phy_base))
- return PTR_ERR(exynos_phy->phy_base);
+ if (IS_ERR(exynos_phy->blk_base))
+ return PTR_ERR(exynos_phy->blk_base);
exynos_phy->drv_data = drv_data;
@@ -278,8 +277,5 @@ static struct platform_driver exynos_pcie_phy_driver = {
.name = "exynos_pcie_phy",
}
};
-module_platform_driver(exynos_pcie_phy_driver);
-MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC PCIe PHY driver");
-MODULE_AUTHOR("Jaehoon Chung <jh80.chung@samsung.com>");
-MODULE_LICENSE("GPL v2");
+builtin_platform_driver(exynos_pcie_phy_driver);
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c
index 07ed608905ac..7c896d0cda18 100644
--- a/drivers/phy/phy-exynos5-usbdrd.c
+++ b/drivers/phy/phy-exynos5-usbdrd.c
@@ -25,6 +25,7 @@
#include <linux/mfd/syscon/exynos5-pmu.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/soc/samsung/exynos-regs-pmu.h>
/* Exynos USB PHY registers */
#define EXYNOS5_FSEL_9MHZ6 0x0
diff --git a/drivers/phy/phy-meson8b-usb2.c b/drivers/phy/phy-meson8b-usb2.c
index 33c9f4ba157d..30f56a6a411f 100644
--- a/drivers/phy/phy-meson8b-usb2.c
+++ b/drivers/phy/phy-meson8b-usb2.c
@@ -81,9 +81,9 @@
#define REG_ADP_BC_ACA_PIN_GND BIT(25)
#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_EN_MASK GENMASK(7, 4)
#define REG_TEST_ADDR_MASK GENMASK(11, 8)
@@ -93,7 +93,7 @@
#define REG_TEST_DATA_OUT_MASK GENMASK(19, 16)
#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_HSXV_TUNE_MASK GENMASK(3, 2)
#define REG_TUNE_TX_VREF_TUNE_MASK GENMASK(7, 4)
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index a21b5f24a340..f86a2574b953 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -49,12 +49,14 @@
#define REG_PHYBIST 0x08
#define REG_PHYTUNE 0x0c
#define REG_PHYCTL_A33 0x10
-#define REG_PHY_UNK_H3 0x20
+#define REG_PHY_OTGCTL 0x20
#define REG_PMU_UNK1 0x10
#define PHYCTL_DATA BIT(7)
+#define OTGCTL_ROUTE_MUSB BIT(0)
+
#define SUNXI_AHB_ICHR8_EN BIT(10)
#define SUNXI_AHB_INCR4_BURST_EN BIT(9)
#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8)
@@ -110,6 +112,7 @@ struct sun4i_usb_phy_cfg {
u8 phyctl_offset;
bool dedicated_clocks;
bool enable_pmu_unk1;
+ bool phy0_dual_route;
};
struct sun4i_usb_phy_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);
- if (phy_data->cfg->type == sun8i_a33_phy ||
- phy_data->cfg->type == sun50i_a64_phy ||
- phy_data->cfg->type == sun8i_v3s_phy) {
- /* A33 or A64 needs us to set phyctl to 0 explicitly */
+ if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
+ /* SoCs newer than A33 need us to set phyctl to 0 explicitly */
writel(0, phyctl);
}
@@ -271,23 +272,16 @@ static int sun4i_usb_phy_init(struct phy *_phy)
writel(val & ~2, phy->pmu + REG_PMU_UNK1);
}
- if (data->cfg->type == sun8i_h3_phy) {
- if (phy->index == 0) {
- val = readl(data->base + REG_PHY_UNK_H3);
- 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);
+ /* 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 */
- sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
+ /* Adjust PHY's magnitude and rate */
+ sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
- /* Disconnect threshold adjustment */
- sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
- data->cfg->disc_thresh, 2);
- }
+ /* Disconnect threshold adjustment */
+ sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
+ data->cfg->disc_thresh, 2);
sun4i_usb_phy_passby(phy, 1);
@@ -486,6 +480,21 @@ static const struct phy_ops sun4i_usb_phy_ops = {
.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)
{
struct sun4i_usb_phy_data *data =
@@ -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);
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)
@@ -700,7 +713,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
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);
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, name);
@@ -823,8 +836,10 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
.num_phys = 4,
.type = sun8i_h3_phy,
.disc_thresh = 3,
+ .phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.enable_pmu_unk1 = true,
+ .phy0_dual_route = true,
};
static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h
index c28ff21ca4d2..0a4ddabc395e 100644
--- a/include/linux/mfd/syscon/exynos5-pmu.h
+++ b/include/linux/mfd/syscon/exynos5-pmu.h
@@ -12,36 +12,6 @@
#ifndef _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_MIPI_PHY_S_RESETN BIT(1)
#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2)
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 49df0a01a2cc..c261ed927e1e 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2010-2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* EXYNOS - Power management unit definition
@@ -50,6 +50,13 @@
#define S5P_WAKEUP_MASK 0x0608
#define S5P_WAKEUP_MASK2 0x0614
+/* MIPI_PHYn_CONTROL, valid for Exynos3250, Exynos4, Exynos5250 and Exynos5433 */
+#define EXYNOS4_MIPI_PHY_CONTROL(n) (0x0710 + (n) * 4)
+#define EXYNOS4_MIPI_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_INFORM1 0x0804
#define S5P_INFORM5 0x0814
@@ -342,6 +349,8 @@
#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408
#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_SYS_WDTRESET (1 << 20)
@@ -495,6 +504,9 @@
#define EXYNOS5420_KFC_CORE_RESET(_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_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024
#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028
@@ -632,6 +644,7 @@
| EXYNOS5420_KFC_USE_STANDBY_WFI3)
/* For EXYNOS5433 */
+#define EXYNOS5433_USBHOST30_PHY_CONTROL (0x0728)
#define EXYNOS5433_PAD_RETENTION_AUD_OPTION (0x3028)
#define EXYNOS5433_PAD_RETENTION_MMC2_OPTION (0x30C8)
#define EXYNOS5433_PAD_RETENTION_TOP_OPTION (0x3108)