diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-11-28 08:44:54 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-11-28 08:44:54 +0100 |
| commit | cdefb95bfc0de9a60b91b748f15e65eddb4f116e (patch) | |
| tree | 0d5ae76297cbe07a709cf773155ec982e16ac855 /drivers/phy | |
| parent | 0edbf9e55295585bbe9df61b646ca5bf80a8e1eb (diff) | |
| parent | 5e253dfbdbea97ab3f462cdd75a6d1cae2292901 (diff) | |
| download | linux-cdefb95bfc0de9a60b91b748f15e65eddb4f116e.tar.gz linux-cdefb95bfc0de9a60b91b748f15e65eddb4f116e.tar.bz2 linux-cdefb95bfc0de9a60b91b748f15e65eddb4f116e.zip | |
Merge tag 'phy-for-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next
Kishon writes:
phy: for 4.10
Merge contains:
*) Add new usb2 phy driver for Meson8b and GXBB
*) Remove phy drivers added for miphy365 and STiH415/6 (as support for
these SoCs are removed from the kernel)
*) Add a sysfs entry to facilitate usb role swap in rcar SoC
*) Add support for otg port in rk3399
*) misc fixes in various phy drivers and cleanups
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
| -rw-r--r-- | drivers/phy/Kconfig | 33 | ||||
| -rw-r--r-- | drivers/phy/Makefile | 3 | ||||
| -rw-r--r-- | drivers/phy/phy-berlin-sata.c | 3 | ||||
| -rw-r--r-- | drivers/phy/phy-brcm-sata.c | 6 | ||||
| -rw-r--r-- | drivers/phy/phy-da8xx-usb.c | 5 | ||||
| -rw-r--r-- | drivers/phy/phy-exynos-mipi-video.c | 15 | ||||
| -rw-r--r-- | drivers/phy/phy-exynos4210-usb2.c | 4 | ||||
| -rw-r--r-- | drivers/phy/phy-exynos4x12-usb2.c | 4 | ||||
| -rw-r--r-- | drivers/phy/phy-exynos5250-usb2.c | 2 | ||||
| -rw-r--r-- | drivers/phy/phy-meson8b-usb2.c | 286 | ||||
| -rw-r--r-- | drivers/phy/phy-miphy365x.c | 625 | ||||
| -rw-r--r-- | drivers/phy/phy-rcar-gen3-usb2.c | 118 | ||||
| -rw-r--r-- | drivers/phy/phy-rockchip-emmc.c | 2 | ||||
| -rw-r--r-- | drivers/phy/phy-rockchip-inno-usb2.c | 607 | ||||
| -rw-r--r-- | drivers/phy/phy-s5pv210-usb2.c | 4 | ||||
| -rw-r--r-- | drivers/phy/phy-stih41x-usb.c | 188 | ||||
| -rw-r--r-- | drivers/phy/phy-sun4i-usb.c | 14 | ||||
| -rw-r--r-- | drivers/phy/phy-ti-pipe3.c | 10 | ||||
| -rw-r--r-- | drivers/phy/phy-twl4030-usb.c | 3 | ||||
| -rw-r--r-- | drivers/phy/tegra/xusb-tegra124.c | 3 | ||||
| -rw-r--r-- | drivers/phy/tegra/xusb.c | 10 |
21 files changed, 1024 insertions, 921 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index fe00f9134d51..e8eb7f225a88 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -129,16 +129,6 @@ config PHY_MIPHY28LP Enable this to support the miphy transceiver (for SATA/PCIE/USB3) that is part of STMicroelectronics STiH407 SoC. -config PHY_MIPHY365X - tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series" - depends on ARCH_STI - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - help - Enable this to support the miphy transceiver (for SATA/PCIE) - that is part of STMicroelectronics STiH41x SoC series. - config PHY_RCAR_GEN2 tristate "Renesas R-Car generation 2 USB PHY driver" depends on ARCH_RENESAS @@ -373,7 +363,9 @@ config PHY_ROCKCHIP_INNO_USB2 tristate "Rockchip INNO USB2PHY Driver" depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF depends on COMMON_CLK + depends on USB_SUPPORT select GENERIC_PHY + select USB_COMMON help Support for Rockchip USB2.0 PHY with Innosilicon IP block. @@ -438,14 +430,6 @@ config PHY_STIH407_USB Enable this support to enable the picoPHY device used by USB2 and USB3 controllers on STMicroelectronics STiH407 SoC families. -config PHY_STIH41X_USB - tristate "STMicroelectronics USB2 PHY driver for STiH41x series" - depends on ARCH_STI - select GENERIC_PHY - help - Enable this to support the USB transceiver that is part of - STMicroelectronics STiH41x SoC series. - config PHY_QCOM_UFS tristate "Qualcomm UFS PHY driver" depends on OF && ARCH_QCOM @@ -489,4 +473,17 @@ config PHY_NS2_PCIE help Enable this to support the Broadcom Northstar2 PCIe PHY. If unsure, say N. + +config PHY_MESON8B_USB2 + tristate "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 Meson8b + and GXBB SoCs. + If unsure, say N. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index a534cf5be07d..65eb2f436a41 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -18,7 +18,6 @@ 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_MIPHY365X) += phy-miphy365x.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 @@ -50,7 +49,6 @@ 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_STIH41X_USB) += phy-stih41x-usb.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 @@ -60,3 +58,4 @@ 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 diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c index f84a33a1bdd9..2c7a57f2d595 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/phy-berlin-sata.c @@ -85,7 +85,6 @@ static int phy_berlin_sata_power_on(struct phy *phy) struct phy_berlin_desc *desc = phy_get_drvdata(phy); struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent); void __iomem *ctrl_reg = priv->base + 0x60 + (desc->index * 0x80); - int ret = 0; u32 regval; clk_prepare_enable(priv->clk); @@ -130,7 +129,7 @@ static int phy_berlin_sata_power_on(struct phy *phy) clk_disable_unprepare(priv->clk); - return ret; + return 0; } static int phy_berlin_sata_power_off(struct phy *phy) diff --git a/drivers/phy/phy-brcm-sata.c b/drivers/phy/phy-brcm-sata.c index 8ffc44afdb75..ccbc3d994998 100644 --- a/drivers/phy/phy-brcm-sata.c +++ b/drivers/phy/phy-brcm-sata.c @@ -140,7 +140,7 @@ static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port) default: dev_err(priv->dev, "invalid phy version\n"); break; - }; + } return priv->phy_base + (port->portnum * size); } @@ -157,7 +157,7 @@ static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port) default: dev_err(priv->dev, "invalid phy version\n"); break; - }; + } return priv->ctrl_base + (port->portnum * size); } @@ -365,7 +365,7 @@ static int brcm_sata_phy_init(struct phy *phy) break; default: rc = -ENODEV; - }; + } return rc; } diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c index c85fb0b59729..1b82bff6330f 100644 --- a/drivers/phy/phy-da8xx-usb.c +++ b/drivers/phy/phy-da8xx-usb.c @@ -23,6 +23,8 @@ #include <linux/platform_device.h> #include <linux/regmap.h> +#define PHY_INIT_BITS (CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN) + struct da8xx_usb_phy { struct phy_provider *phy_provider; struct phy *usb11_phy; @@ -208,6 +210,9 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev) dev_warn(dev, "Failed to create usb20 phy lookup\n"); } + regmap_write_bits(d_phy->regmap, CFGCHIP(2), + PHY_INIT_BITS, PHY_INIT_BITS); + return 0; } diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 8b851f718123..6bee04cc4d53 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -229,19 +229,6 @@ struct exynos_mipi_video_phy { spinlock_t slock; }; -static inline int __is_running(const struct exynos_mipi_phy_desc *data, - struct exynos_mipi_video_phy *state) -{ - u32 val; - int ret; - - ret = regmap_read(state->regmaps[data->resetn_map], data->resetn_reg, &val); - if (ret) - return 0; - - return val & data->resetn_val; -} - static int __set_phy_state(const struct exynos_mipi_phy_desc *data, struct exynos_mipi_video_phy *state, unsigned int on) { @@ -251,7 +238,7 @@ static int __set_phy_state(const struct exynos_mipi_phy_desc *data, /* disable in PMU sysreg */ if (!on && data->coupled_phy_id >= 0 && - !__is_running(state->phys[data->coupled_phy_id].data, state)) { + state->phys[data->coupled_phy_id].phy->power_count == 0) { regmap_read(state->regmaps[data->enable_map], data->enable_reg, &val); val &= ~data->enable_val; diff --git a/drivers/phy/phy-exynos4210-usb2.c b/drivers/phy/phy-exynos4210-usb2.c index f30bbb0fb3b2..1f50e1004828 100644 --- a/drivers/phy/phy-exynos4210-usb2.c +++ b/drivers/phy/phy-exynos4210-usb2.c @@ -141,7 +141,7 @@ static void exynos4210_isol(struct samsung_usb2_phy_instance *inst, bool on) break; default: return; - }; + } regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); } @@ -179,7 +179,7 @@ static void exynos4210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) rstbits = EXYNOS_4210_URSTCON_PHY1_P1P2 | EXYNOS_4210_URSTCON_HOST_LINK_P2; break; - }; + } if (on) { clk = readl(drv->reg_phy + EXYNOS_4210_UPHYCLK); diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c index 765da90a536f..7f27a91acf87 100644 --- a/drivers/phy/phy-exynos4x12-usb2.c +++ b/drivers/phy/phy-exynos4x12-usb2.c @@ -187,7 +187,7 @@ static void exynos4x12_isol(struct samsung_usb2_phy_instance *inst, bool on) break; default: return; - }; + } regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); } @@ -237,7 +237,7 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) rstbits = EXYNOS_4x12_URSTCON_HSIC1 | EXYNOS_4x12_URSTCON_HOST_LINK_P1; break; - }; + } if (on) { pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c index 2ed1735a076a..aad806272305 100644 --- a/drivers/phy/phy-exynos5250-usb2.c +++ b/drivers/phy/phy-exynos5250-usb2.c @@ -192,7 +192,7 @@ static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) break; default: return; - }; + } regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); } diff --git a/drivers/phy/phy-meson8b-usb2.c b/drivers/phy/phy-meson8b-usb2.c new file mode 100644 index 000000000000..33c9f4ba157d --- /dev/null +++ b/drivers/phy/phy-meson8b-usb2.c @@ -0,0 +1,286 @@ +/* + * Meson8b and GXBB USB2 PHY driver + * + * Copyright (C) 2016 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/clk.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/reset.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/usb/of.h> + +#define REG_CONFIG 0x00 + #define REG_CONFIG_CLK_EN BIT(0) + #define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1) + #define REG_CONFIG_CLK_DIV_MASK GENMASK(10, 4) + #define REG_CONFIG_CLK_32k_ALTSEL BIT(15) + #define REG_CONFIG_TEST_TRIG BIT(31) + +#define REG_CTRL 0x04 + #define REG_CTRL_SOFT_PRST BIT(0) + #define REG_CTRL_SOFT_HRESET BIT(1) + #define REG_CTRL_SS_SCALEDOWN_MODE_MASK GENMASK(3, 2) + #define REG_CTRL_CLK_DET_RST BIT(4) + #define REG_CTRL_INTR_SEL BIT(5) + #define REG_CTRL_CLK_DETECTED BIT(8) + #define REG_CTRL_SOF_SENT_RCVD_TGL BIT(9) + #define REG_CTRL_SOF_TOGGLE_OUT BIT(10) + #define REG_CTRL_POWER_ON_RESET BIT(15) + #define REG_CTRL_SLEEPM BIT(16) + #define REG_CTRL_TX_BITSTUFF_ENN_H BIT(17) + #define REG_CTRL_TX_BITSTUFF_ENN BIT(18) + #define REG_CTRL_COMMON_ON BIT(19) + #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) + #define REG_CTRL_REF_CLK_SEL_SHIFT 20 + #define REG_CTRL_FSEL_MASK GENMASK(24, 22) + #define REG_CTRL_FSEL_SHIFT 22 + #define REG_CTRL_PORT_RESET BIT(25) + #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) + +#define REG_ENDP_INTR 0x08 + +/* bits [31:26], [24:21] and [15:3] seem to be read-only */ +#define REG_ADP_BC 0x0c + #define REG_ADP_BC_VBUS_VLD_EXT_SEL BIT(0) + #define REG_ADP_BC_VBUS_VLD_EXT BIT(1) + #define REG_ADP_BC_OTG_DISABLE BIT(2) + #define REG_ADP_BC_ID_PULLUP BIT(3) + #define REG_ADP_BC_DRV_VBUS BIT(4) + #define REG_ADP_BC_ADP_PRB_EN BIT(5) + #define REG_ADP_BC_ADP_DISCHARGE BIT(6) + #define REG_ADP_BC_ADP_CHARGE BIT(7) + #define REG_ADP_BC_SESS_END BIT(8) + #define REG_ADP_BC_DEVICE_SESS_VLD BIT(9) + #define REG_ADP_BC_B_VALID BIT(10) + #define REG_ADP_BC_A_VALID BIT(11) + #define REG_ADP_BC_ID_DIG BIT(12) + #define REG_ADP_BC_VBUS_VALID BIT(13) + #define REG_ADP_BC_ADP_PROBE BIT(14) + #define REG_ADP_BC_ADP_SENSE BIT(15) + #define REG_ADP_BC_ACA_ENABLE BIT(16) + #define REG_ADP_BC_DCD_ENABLE BIT(17) + #define REG_ADP_BC_VDAT_DET_EN_B BIT(18) + #define REG_ADP_BC_VDAT_SRC_EN_B BIT(19) + #define REG_ADP_BC_CHARGE_SEL BIT(20) + #define REG_ADP_BC_CHARGE_DETECT BIT(21) + #define REG_ADP_BC_ACA_PIN_RANGE_C BIT(22) + #define REG_ADP_BC_ACA_PIN_RANGE_B BIT(23) + #define REG_ADP_BC_ACA_PIN_RANGE_A BIT(24) + #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_TEST 0x18 + #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) + #define REG_TEST_DATA_OUT_SEL BIT(12) + #define REG_TEST_CLK BIT(13) + #define REG_TEST_VA_TEST_EN_B_MASK GENMASK(15, 14) + #define REG_TEST_DATA_OUT_MASK GENMASK(19, 16) + #define REG_TEST_DISABLE_ID_PULLUP BIT(20) + +#define REG_TUNE 0x1c + #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) + #define REG_TUNE_TX_RISE_TUNE_MASK GENMASK(9, 8) + #define REG_TUNE_TX_PREEMP_PULSE_TUNE BIT(10) + #define REG_TUNE_TX_PREEMP_AMP_TUNE_MASK GENMASK(12, 11) + #define REG_TUNE_TX_FSLS_TUNE_MASK GENMASK(16, 13) + #define REG_TUNE_SQRX_TUNE_MASK GENMASK(19, 17) + #define REG_TUNE_OTG_TUNE GENMASK(22, 20) + #define REG_TUNE_COMP_DIS_TUNE GENMASK(25, 23) + #define REG_TUNE_HOST_DM_PULLDOWN BIT(26) + #define REG_TUNE_HOST_DP_PULLDOWN BIT(27) + +#define RESET_COMPLETE_TIME 500 +#define ACA_ENABLE_COMPLETE_TIME 50 + +struct phy_meson8b_usb2_priv { + void __iomem *regs; + enum usb_dr_mode dr_mode; + struct clk *clk_usb_general; + struct clk *clk_usb; + struct reset_control *reset; +}; + +static u32 phy_meson8b_usb2_read(struct phy_meson8b_usb2_priv *phy_priv, + u32 reg) +{ + return readl(phy_priv->regs + reg); +} + +static void phy_meson8b_usb2_mask_bits(struct phy_meson8b_usb2_priv *phy_priv, + u32 reg, u32 mask, u32 value) +{ + u32 data; + + data = phy_meson8b_usb2_read(phy_priv, reg); + data &= ~mask; + data |= (value & mask); + + writel(data, phy_priv->regs + reg); +} + +static int phy_meson8b_usb2_power_on(struct phy *phy) +{ + struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); + int ret; + + if (!IS_ERR_OR_NULL(priv->reset)) { + ret = reset_control_reset(priv->reset); + if (ret) { + dev_err(&phy->dev, "Failed to trigger USB reset\n"); + return ret; + } + } + + ret = clk_prepare_enable(priv->clk_usb_general); + if (ret) { + dev_err(&phy->dev, "Failed to enable USB general clock\n"); + return ret; + } + + ret = clk_prepare_enable(priv->clk_usb); + if (ret) { + dev_err(&phy->dev, "Failed to enable USB DDR clock\n"); + clk_disable_unprepare(priv->clk_usb_general); + return ret; + } + + phy_meson8b_usb2_mask_bits(priv, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, + REG_CONFIG_CLK_32k_ALTSEL); + + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, + 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); + + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_FSEL_MASK, + 0x5 << REG_CTRL_FSEL_SHIFT); + + /* reset the PHY */ + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET, + REG_CTRL_POWER_ON_RESET); + udelay(RESET_COMPLETE_TIME); + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); + udelay(RESET_COMPLETE_TIME); + + phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, + REG_CTRL_SOF_TOGGLE_OUT); + + if (priv->dr_mode == USB_DR_MODE_HOST) { + phy_meson8b_usb2_mask_bits(priv, REG_ADP_BC, + REG_ADP_BC_ACA_ENABLE, + REG_ADP_BC_ACA_ENABLE); + + udelay(ACA_ENABLE_COMPLETE_TIME); + + if (phy_meson8b_usb2_read(priv, REG_ADP_BC) & + REG_ADP_BC_ACA_PIN_FLOAT) { + dev_warn(&phy->dev, "USB ID detect failed!\n"); + clk_disable_unprepare(priv->clk_usb); + clk_disable_unprepare(priv->clk_usb_general); + return -EINVAL; + } + } + + return 0; +} + +static int phy_meson8b_usb2_power_off(struct phy *phy) +{ + struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); + + clk_disable_unprepare(priv->clk_usb); + clk_disable_unprepare(priv->clk_usb_general); + + return 0; +} + +static const struct phy_ops phy_meson8b_usb2_ops = { + .power_on = phy_meson8b_usb2_power_on, + .power_off = phy_meson8b_usb2_power_off, + .owner = THIS_MODULE, +}; + +static int phy_meson8b_usb2_probe(struct platform_device *pdev) +{ + struct phy_meson8b_usb2_priv *priv; + struct resource *res; + struct phy *phy; + struct phy_provider *phy_provider; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + priv->clk_usb_general = devm_clk_get(&pdev->dev, "usb_general"); + if (IS_ERR(priv->clk_usb_general)) + return PTR_ERR(priv->clk_usb_general); + + priv->clk_usb = devm_clk_get(&pdev->dev, "usb"); + if (IS_ERR(priv->clk_usb)) + return PTR_ERR(priv->clk_usb); + + priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL); + if (PTR_ERR(priv->reset) == -EPROBE_DEFER) + return PTR_ERR(priv->reset); + + priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1); + if (priv->dr_mode == USB_DR_MODE_UNKNOWN) { + dev_err(&pdev->dev, + "missing dual role configuration of the controller\n"); + return -EINVAL; + } + + phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops); + if (IS_ERR(phy)) { + dev_err(&pdev->dev, "failed to create PHY\n"); + return PTR_ERR(phy); + } + + phy_set_drvdata(phy, priv); + + phy_provider = + devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id phy_meson8b_usb2_of_match[] = { + { .compatible = "amlogic,meson8b-usb2-phy", }, + { .compatible = "amlogic,meson-gxbb-usb2-phy", }, + { }, +}; +MODULE_DEVICE_TABLE(of, phy_meson8b_usb2_of_match); + +static struct platform_driver phy_meson8b_usb2_driver = { + .probe = phy_meson8b_usb2_probe, + .driver = { + .name = "phy-meson-usb2", + .of_match_table = phy_meson8b_usb2_of_match, + }, +}; +module_platform_driver(phy_meson8b_usb2_driver); + +MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); +MODULE_DESCRIPTION("Meson8b and GXBB USB2 PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c deleted file mode 100644 index e661f3b36eaa..000000000000 --- a/drivers/phy/phy-miphy365x.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Copyright (C) 2014 STMicroelectronics – All Rights Reserved - * - * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416). - * - * Authors: Alexandre Torgue <alexandre.torgue@st.com> - * Lee Jones <lee.jones@linaro.org> - * - * 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/platform_device.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/of_platform.h> -#include <linux/of_address.h> -#include <linux/clk.h> -#include <linux/phy/phy.h> -#include <linux/delay.h> -#include <linux/mfd/syscon.h> -#include <linux/regmap.h> - -#include <dt-bindings/phy/phy.h> - -#define HFC_TIMEOUT 100 - -#define SYSCFG_SELECT_SATA_MASK BIT(1) -#define SYSCFG_SELECT_SATA_POS 1 - -/* MiPHY365x register definitions */ -#define RESET_REG 0x00 -#define RST_PLL BIT(1) -#define RST_PLL_CAL BIT(2) -#define RST_RX BIT(4) -#define RST_MACRO BIT(7) - -#define STATUS_REG 0x01 -#define IDLL_RDY BIT(0) -#define PLL_RDY BIT(1) -#define DES_BIT_LOCK BIT(2) -#define DES_SYMBOL_LOCK BIT(3) - -#define CTRL_REG 0x02 -#define TERM_EN BIT(0) -#define PCI_EN BIT(2) -#define DES_BIT_LOCK_EN BIT(3) -#define TX_POL BIT(5) - -#define INT_CTRL_REG 0x03 - -#define BOUNDARY1_REG 0x10 -#define SPDSEL_SEL BIT(0) - -#define BOUNDARY3_REG 0x12 -#define TX_SPDSEL_GEN1_VAL 0 -#define TX_SPDSEL_GEN2_VAL 0x01 -#define TX_SPDSEL_GEN3_VAL 0x02 -#define RX_SPDSEL_GEN1_VAL 0 -#define RX_SPDSEL_GEN2_VAL (0x01 << 3) -#define RX_SPDSEL_GEN3_VAL (0x02 << 3) - -#define PCIE_REG 0x16 - -#define BUF_SEL_REG 0x20 -#define CONF_GEN_SEL_GEN3 0x02 -#define CONF_GEN_SEL_GEN2 0x01 -#define PD_VDDTFILTER BIT(4) - -#define TXBUF1_REG 0x21 -#define SWING_VAL 0x04 -#define SWING_VAL_GEN1 0x03 -#define PREEMPH_VAL (0x3 << 5) - -#define TXBUF2_REG 0x22 -#define TXSLEW_VAL 0x2 -#define TXSLEW_VAL_GEN1 0x4 - -#define RXBUF_OFFSET_CTRL_REG 0x23 - -#define RXBUF_REG 0x25 -#define SDTHRES_VAL 0x01 -#define EQ_ON3 (0x03 << 4) -#define EQ_ON1 (0x01 << 4) - -#define COMP_CTRL1_REG 0x40 -#define START_COMSR BIT(0) -#define START_COMZC BIT(1) -#define COMSR_DONE BIT(2) -#define COMZC_DONE BIT(3) -#define COMP_AUTO_LOAD BIT(4) - -#define COMP_CTRL2_REG 0x41 -#define COMP_2MHZ_RAT_GEN1 0x1e -#define COMP_2MHZ_RAT 0xf - -#define COMP_CTRL3_REG 0x42 -#define COMSR_COMP_REF 0x33 - -#define COMP_IDLL_REG 0x47 -#define COMZC_IDLL 0x2a - -#define PLL_CTRL1_REG 0x50 -#define PLL_START_CAL BIT(0) -#define BUF_EN BIT(2) -#define SYNCHRO_TX BIT(3) -#define SSC_EN BIT(6) -#define CONFIG_PLL BIT(7) - -#define PLL_CTRL2_REG 0x51 -#define BYPASS_PLL_CAL BIT(1) - -#define PLL_RAT_REG 0x52 - -#define PLL_SSC_STEP_MSB_REG 0x56 -#define PLL_SSC_STEP_MSB_VAL 0x03 - -#define PLL_SSC_STEP_LSB_REG 0x57 -#define PLL_SSC_STEP_LSB_VAL 0x63 - -#define PLL_SSC_PER_MSB_REG 0x58 -#define PLL_SSC_PER_MSB_VAL 0 - -#define PLL_SSC_PER_LSB_REG 0x59 -#define PLL_SSC_PER_LSB_VAL 0xf1 - -#define IDLL_TEST_REG 0x72 -#define START_CLK_HF BIT(6) - -#define DES_BITLOCK_REG 0x86 -#define BIT_LOCK_LEVEL 0x01 -#define BIT_LOCK_CNT_512 (0x03 << 5) - -struct miphy365x_phy { - struct phy *phy; - void __iomem *base; - bool pcie_tx_pol_inv; - bool sata_tx_pol_inv; - u32 sata_gen; - u32 ctrlreg; - u8 type; -}; - -struct miphy365x_dev { - struct device *dev; - struct regmap *regmap; - struct mutex miphy_mutex; - struct miphy365x_phy **phys; - int nphys; -}; - -/* - * These values are represented in Device tree. They are considered to be ABI - * and although they can be extended any existing values must not change. - */ -enum miphy_sata_gen { - SATA_GEN1 = 1, - SATA_GEN2, - SATA_GEN3 -}; - -static u8 rx_tx_spd[] = { - 0, /* GEN0 doesn't exist. */ - TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL, - TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL, - TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL -}; - -/* - * This function selects the system configuration, - * either two SATA, one SATA and one PCIe, or two PCIe lanes. - */ -static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - bool sata = (miphy_phy->type == PHY_TYPE_SATA); - - return regmap_update_bits(miphy_dev->regmap, - miphy_phy->ctrlreg, - SYSCFG_SELECT_SATA_MASK, - sata << SYSCFG_SELECT_SATA_POS); -} - -static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val; - - if (miphy_phy->pcie_tx_pol_inv) { - /* Invert Tx polarity and clear pci_txdetect_pol bit */ - val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL; - writeb_relaxed(val, miphy_phy->base + CTRL_REG); - writeb_relaxed(0x00, miphy_phy->base + PCIE_REG); - } - - return 0; -} - -static inline int miphy365x_hfc_not_rdy(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT); - u8 mask = IDLL_RDY | PLL_RDY; - u8 regval; - - do { - regval = readb_relaxed(miphy_phy->base + STATUS_REG); - if (!(regval & mask)) - return 0; - - usleep_range(2000, 2500); - } while (time_before(jiffies, timeout)); - - dev_err(miphy_dev->dev, "HFC ready timeout!\n"); - return -EBUSY; -} - -static inline int miphy365x_rdy(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT); - u8 mask = IDLL_RDY | PLL_RDY; - u8 regval; - - do { - regval = readb_relaxed(miphy_phy->base + STATUS_REG); - if ((regval & mask) == mask) - return 0; - - usleep_range(2000, 2500); - } while (time_before(jiffies, timeout)); - - dev_err(miphy_dev->dev, "PHY not ready timeout!\n"); - return -EBUSY; -} - -static inline void miphy365x_set_comp(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val, mask; - - if (miphy_phy->sata_gen == SATA_GEN1) - writeb_relaxed(COMP_2MHZ_RAT_GEN1, - miphy_phy->base + COMP_CTRL2_REG); - else - writeb_relaxed(COMP_2MHZ_RAT, - miphy_phy->base + COMP_CTRL2_REG); - - if (miphy_phy->sata_gen != SATA_GEN3) { - writeb_relaxed(COMSR_COMP_REF, - miphy_phy->base + COMP_CTRL3_REG); - /* - * Force VCO current to value defined by address 0x5A - * and disable PCIe100Mref bit - * Enable auto load compensation for pll_i_bias - */ - writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG); - writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG); - } - - /* - * Force restart compensation and enable auto load - * for Comzc_Tx, Comzc_Rx and Comsr on macro - */ - val = START_COMSR | START_COMZC | COMP_AUTO_LOAD; - writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG); - - mask = COMSR_DONE | COMZC_DONE; - while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask) != mask) - cpu_relax(); -} - -static inline void miphy365x_set_ssc(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - u8 val; - - /* - * SSC Settings. SSC will be enabled through Link - * SSC Ampl. = 0.4% - * SSC Freq = 31KHz - */ - writeb_relaxed(PLL_SSC_STEP_MSB_VAL, - miphy_phy->base + PLL_SSC_STEP_MSB_REG); - writeb_relaxed(PLL_SSC_STEP_LSB_VAL, - miphy_phy->base + PLL_SSC_STEP_LSB_REG); - writeb_relaxed(PLL_SSC_PER_MSB_VAL, - miphy_phy->base + PLL_SSC_PER_MSB_REG); - writeb_relaxed(PLL_SSC_PER_LSB_VAL, - miphy_phy->base + PLL_SSC_PER_LSB_REG); - - /* SSC Settings complete */ - if (miphy_phy->sata_gen == SATA_GEN1) { - val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL; - writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG); - } else { - val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL; - writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG); - } -} - -static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy, - struct miphy365x_dev *miphy_dev) -{ - int ret; - u8 val; - - /* - * Force PHY macro reset, PLL calibration reset, PLL reset - * and assert Deserializer Reset - */ - val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO; - writeb_relaxed(val, miphy_phy->base + RESET_REG); - - if (miphy_phy->sata_tx_pol_inv) - writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG); - - /* - * Force macro1 to use rx_lspd, tx_lspd - * Force Rx_Clock on first I-DLL phase - * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3 - */ - write |
