summaryrefslogtreecommitdiffstats
path: root/drivers/phy/amlogic/phy-meson-gxl-usb2.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman2018-03-20 10:10:46 +0100
committerGreg Kroah-Hartman2018-03-20 10:10:46 +0100
commit85a09bf492333300ca0a09199bce4cf1a5bdd5cb (patch)
tree8209918ef0d536cb401247f315a3aba60b15bdf5 /drivers/phy/amlogic/phy-meson-gxl-usb2.c
parentMerge branch 4.16-rc6 into usb-next (diff)
parentphy: tegra: xusb: Uncomment register write (diff)
downloadkernel-qcow2-linux-85a09bf492333300ca0a09199bce4cf1a5bdd5cb.tar.gz
kernel-qcow2-linux-85a09bf492333300ca0a09199bce4cf1a5bdd5cb.tar.xz
kernel-qcow2-linux-85a09bf492333300ca0a09199bce4cf1a5bdd5cb.zip
Merge tag 'phy-for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next
Kishon writes: phy: for 4.17 *) Add USB PHY driver for MDM6600 on Droid *) Add USB PHY driver for STM32 USB PHY Controller *) Add inno-usb2-phy driver for hi3798cv200 SoC *) Add combo phy driver (SATA/USB/PCIE) for HiSilicon STB SoCs *) Add USB3 PHY driver for Meson GXL and GXM *) Add support for R8A77965 Gen3 USB 2.0 PHY in phy-rcar-gen3-usb2 driver *) Add support for qualcomm QUSB2 V2 and QMP V3 USB3 PHY in phy-qcom-qusb2 and phy-qcom-qmp PHY driver respectively *) Add support for runtime PM in phy-qcom-qusb2 and phy-qcom-qmp PHY drivers *) Add support for Allwinner R40 USB PHY in sun4i-usb PHY driver *) Add support in rockchip-typec PHY driver to make extcon optional and fallback to working in host mode if extcon is missing *) Add support in rockchip-typec PHY driver to mux PHYs connected to DP *) Add support to configure slew rate parameters in phy-mtk-tphy PHY driver *) Add workaround for missing Vbus det interrupts on Allwinner A23/A33 *) Add USB speed related PHY modes in phy core *) Fix PHY 'structure' documentation *) Force rockchip-typec PHY to USB2 if DP-only mode is used *) Fix phy-qcom-qusb2 and phy-qcom-qmp PHY drivers to follow PHY reset and initialization sequence as per hardware programming manual *) Fix Marvell BG2CD SoC USB failure in phy-berlin-usb driver *) Minor fixes in lpc18xx-usb-otg, xusb-tegra210 and phy-rockchip-emmc PHY drivers Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy/amlogic/phy-meson-gxl-usb2.c')
-rw-r--r--drivers/phy/amlogic/phy-meson-gxl-usb2.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
index e90c4ee25dfe..9f9b5414b97a 100644
--- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
@@ -11,14 +11,15 @@
* 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/regmap.h>
+#include <linux/reset.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
-#include <linux/usb/of.h>
/* bits [31:27] are read-only */
#define U2P_R0 0x0
@@ -70,12 +71,11 @@
/* bits [31:14] are read-only */
#define U2P_R2 0x8
- #define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
- #define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
- #define U2P_R2_ADDR_MASK GENMASK(11, 8)
- #define U2P_R2_DATA_OUT_SEL BIT(12)
- #define U2P_R2_CLK BIT(13)
- #define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
+ #define U2P_R2_TESTDATA_IN_MASK GENMASK(7, 0)
+ #define U2P_R2_TESTADDR_MASK GENMASK(11, 8)
+ #define U2P_R2_TESTDATA_OUT_SEL BIT(12)
+ #define U2P_R2_TESTCLK BIT(13)
+ #define U2P_R2_TESTDATA_OUT_MASK GENMASK(17, 14)
#define U2P_R2_ACA_PIN_RANGE_C BIT(18)
#define U2P_R2_ACA_PIN_RANGE_B BIT(19)
#define U2P_R2_ACA_PIN_RANGE_A BIT(20)
@@ -99,6 +99,8 @@ struct phy_meson_gxl_usb2_priv {
struct regmap *regmap;
enum phy_mode mode;
int is_enabled;
+ struct clk *clk;
+ struct reset_control *reset;
};
static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
@@ -108,6 +110,31 @@ static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
.max_register = U2P_R3,
};
+static int phy_meson_gxl_usb2_init(struct phy *phy)
+{
+ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
+ int ret;
+
+ ret = reset_control_reset(priv->reset);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb2_exit(struct phy *phy)
+{
+ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
+
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
static int phy_meson_gxl_usb2_reset(struct phy *phy)
{
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
@@ -195,6 +222,8 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
}
static const struct phy_ops phy_meson_gxl_usb2_ops = {
+ .init = phy_meson_gxl_usb2_init,
+ .exit = phy_meson_gxl_usb2_exit,
.power_on = phy_meson_gxl_usb2_power_on,
.power_off = phy_meson_gxl_usb2_power_off,
.set_mode = phy_meson_gxl_usb2_set_mode,
@@ -210,6 +239,7 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
struct phy_meson_gxl_usb2_priv *priv;
struct phy *phy;
void __iomem *base;
+ int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -222,28 +252,34 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- switch (of_usb_get_dr_mode_by_phy(dev->of_node, -1)) {
- case USB_DR_MODE_PERIPHERAL:
- priv->mode = PHY_MODE_USB_DEVICE;
- break;
- case USB_DR_MODE_OTG:
- priv->mode = PHY_MODE_USB_OTG;
- break;
- case USB_DR_MODE_HOST:
- default:
- priv->mode = PHY_MODE_USB_HOST;
- break;
- }
+ /* start in host mode */
+ priv->mode = PHY_MODE_USB_HOST;
priv->regmap = devm_regmap_init_mmio(dev, base,
&phy_meson_gxl_usb2_regmap_conf);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
+ priv->clk = devm_clk_get(dev, "phy");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ if (ret == -ENOENT)
+ priv->clk = NULL;
+ else
+ return ret;
+ }
+
+ priv->reset = devm_reset_control_get_optional_shared(dev, "phy");
+ if (IS_ERR(priv->reset))
+ return PTR_ERR(priv->reset);
+
phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops);
if (IS_ERR(phy)) {
- dev_err(dev, "failed to create PHY\n");
- return PTR_ERR(phy);
+ ret = PTR_ERR(phy);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "failed to create PHY\n");
+
+ return ret;
}
phy_set_drvdata(phy, priv);