diff options
Diffstat (limited to 'drivers/usb/phy/phy-mv-u3d-usb.c')
-rw-r--r-- | drivers/usb/phy/phy-mv-u3d-usb.c | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/drivers/usb/phy/phy-mv-u3d-usb.c b/drivers/usb/phy/phy-mv-u3d-usb.c deleted file mode 100644 index d317903022bf..000000000000 --- a/drivers/usb/phy/phy-mv-u3d-usb.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/usb/otg.h> -#include <linux/platform_data/mv_usb.h> - -#include "phy-mv-u3d-usb.h" - -/* - * struct mv_u3d_phy - transceiver driver state - * @phy: transceiver structure - * @dev: The parent device supplied to the probe function - * @clk: usb phy clock - * @base: usb phy register memory base - */ -struct mv_u3d_phy { - struct usb_phy phy; - struct mv_usb_platform_data *plat; - struct device *dev; - struct clk *clk; - void __iomem *base; -}; - -static u32 mv_u3d_phy_read(void __iomem *base, u32 reg) -{ - void __iomem *addr, *data; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - return readl_relaxed(data); -} - -static void mv_u3d_phy_set(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - u32 tmp; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); - tmp |= value; - writel_relaxed(tmp, data); -} - -static void mv_u3d_phy_clear(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - u32 tmp; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - tmp = readl_relaxed(data); - tmp &= ~value; - writel_relaxed(tmp, data); -} - -static void mv_u3d_phy_write(void __iomem *base, u32 reg, u32 value) -{ - void __iomem *addr, *data; - - addr = base; - data = base + 0x4; - - writel_relaxed(reg, addr); - writel_relaxed(value, data); -} - -static void mv_u3d_phy_shutdown(struct usb_phy *phy) -{ - struct mv_u3d_phy *mv_u3d_phy; - void __iomem *base; - u32 val; - - mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); - base = mv_u3d_phy->base; - - /* Power down Reference Analog current, bit 15 - * Power down PLL, bit 14 - * Power down Receiver, bit 13 - * Power down Transmitter, bit 12 - * of USB3_POWER_PLL_CONTROL register - */ - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_PU); - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - - if (mv_u3d_phy->clk) - clk_disable(mv_u3d_phy->clk); -} - -static int mv_u3d_phy_init(struct usb_phy *phy) -{ - struct mv_u3d_phy *mv_u3d_phy; - void __iomem *base; - u32 val, count; - - /* enable usb3 phy */ - mv_u3d_phy = container_of(phy, struct mv_u3d_phy, phy); - - if (mv_u3d_phy->clk) - clk_enable(mv_u3d_phy->clk); - - base = mv_u3d_phy->base; - - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_PU_MASK); - val |= 0xF << USB3_POWER_PLL_CONTROL_PU_SHIFT; - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - udelay(100); - - mv_u3d_phy_write(base, USB3_RESET_CONTROL, - USB3_RESET_CONTROL_RESET_PIPE); - udelay(100); - - mv_u3d_phy_write(base, USB3_RESET_CONTROL, - USB3_RESET_CONTROL_RESET_PIPE - | USB3_RESET_CONTROL_RESET_PHY); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_POWER_PLL_CONTROL); - val &= ~(USB3_POWER_PLL_CONTROL_REF_FREF_SEL_MASK - | USB3_POWER_PLL_CONTROL_PHY_MODE_MASK); - val |= (USB3_PLL_25MHZ << USB3_POWER_PLL_CONTROL_REF_FREF_SEL_SHIFT) - | (0x5 << USB3_POWER_PLL_CONTROL_PHY_MODE_SHIFT); - mv_u3d_phy_write(base, USB3_POWER_PLL_CONTROL, val); - udelay(100); - - mv_u3d_phy_clear(base, USB3_KVCO_CALI_CONTROL, - USB3_KVCO_CALI_CONTROL_USE_MAX_PLL_RATE_MASK); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_SQUELCH_FFE); - val &= ~(USB3_SQUELCH_FFE_FFE_CAP_SEL_MASK - | USB3_SQUELCH_FFE_FFE_RES_SEL_MASK - | USB3_SQUELCH_FFE_SQ_THRESH_IN_MASK); - val |= ((0xD << USB3_SQUELCH_FFE_FFE_CAP_SEL_SHIFT) - | (0x7 << USB3_SQUELCH_FFE_FFE_RES_SEL_SHIFT) - | (0x8 << USB3_SQUELCH_FFE_SQ_THRESH_IN_SHIFT)); - mv_u3d_phy_write(base, USB3_SQUELCH_FFE, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN1_SET0); - val &= ~USB3_GEN1_SET0_G1_TX_SLEW_CTRL_EN_MASK; - val |= 1 << USB3_GEN1_SET0_G1_TX_EMPH_EN_SHIFT; - mv_u3d_phy_write(base, USB3_GEN1_SET0, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN2_SET0); - val &= ~(USB3_GEN2_SET0_G2_TX_AMP_MASK - | USB3_GEN2_SET0_G2_TX_EMPH_AMP_MASK - | USB3_GEN2_SET0_G2_TX_SLEW_CTRL_EN_MASK); - val |= ((0x14 << USB3_GEN2_SET0_G2_TX_AMP_SHIFT) - | (1 << USB3_GEN2_SET0_G2_TX_AMP_ADJ_SHIFT) - | (0xA << USB3_GEN2_SET0_G2_TX_EMPH_AMP_SHIFT) - | (1 << USB3_GEN2_SET0_G2_TX_EMPH_EN_SHIFT)); - mv_u3d_phy_write(base, USB3_GEN2_SET0, val); - udelay(100); - - mv_u3d_phy_read(base, USB3_TX_EMPPH); - val &= ~(USB3_TX_EMPPH_AMP_MASK - | USB3_TX_EMPPH_EN_MASK - | USB3_TX_EMPPH_AMP_FORCE_MASK - | USB3_TX_EMPPH_PAR1_MASK - | USB3_TX_EMPPH_PAR2_MASK); - val |= ((0xB << USB3_TX_EMPPH_AMP_SHIFT) - | (1 << USB3_TX_EMPPH_EN_SHIFT) - | (1 << USB3_TX_EMPPH_AMP_FORCE_SHIFT) - | (0x1C << USB3_TX_EMPPH_PAR1_SHIFT) - | (1 << USB3_TX_EMPPH_PAR2_SHIFT)); - - mv_u3d_phy_write(base, USB3_TX_EMPPH, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_GEN2_SET1); - val &= ~(USB3_GEN2_SET1_G2_RX_SELMUPI_MASK - | USB3_GEN2_SET1_G2_RX_SELMUPF_MASK - | USB3_GEN2_SET1_G2_RX_SELMUFI_MASK - | USB3_GEN2_SET1_G2_RX_SELMUFF_MASK); - val |= ((1 << USB3_GEN2_SET1_G2_RX_SELMUPI_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUPF_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUFI_SHIFT) - | (1 << USB3_GEN2_SET1_G2_RX_SELMUFF_SHIFT)); - mv_u3d_phy_write(base, USB3_GEN2_SET1, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_DIGITAL_LOOPBACK_EN); - val &= ~USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_MASK; - val |= 1 << USB3_DIGITAL_LOOPBACK_EN_SEL_BITS_SHIFT; - mv_u3d_phy_write(base, USB3_DIGITAL_LOOPBACK_EN, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_IMPEDANCE_TX_SSC); - val &= ~USB3_IMPEDANCE_TX_SSC_SSC_AMP_MASK; - val |= 0xC << USB3_IMPEDANCE_TX_SSC_SSC_AMP_SHIFT; - mv_u3d_phy_write(base, USB3_IMPEDANCE_TX_SSC, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_IMPEDANCE_CALI_CTRL); - val &= ~USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_MASK; - val |= 0x4 << USB3_IMPEDANCE_CALI_CTRL_IMP_CAL_THR_SHIFT; - mv_u3d_phy_write(base, USB3_IMPEDANCE_CALI_CTRL, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_PHY_ISOLATION_MODE); - val &= ~(USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_MASK - | USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_MASK - | USB3_PHY_ISOLATION_MODE_TX_DRV_IDLE_MASK); - val |= ((1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_RX_SHIFT) - | (1 << USB3_PHY_ISOLATION_MODE_PHY_GEN_TX_SHIFT)); - mv_u3d_phy_write(base, USB3_PHY_ISOLATION_MODE, val); - udelay(100); - - val = mv_u3d_phy_read(base, USB3_TXDETRX); - val &= ~(USB3_TXDETRX_VTHSEL_MASK); - val |= 0x1 << USB3_TXDETRX_VTHSEL_SHIFT; - mv_u3d_phy_write(base, USB3_TXDETRX, val); - udelay(100); - - dev_dbg(mv_u3d_phy->dev, "start calibration\n"); - -calstart: - /* Perform Manual Calibration */ - mv_u3d_phy_set(base, USB3_KVCO_CALI_CONTROL, - 1 << USB3_KVCO_CALI_CONTROL_CAL_START_SHIFT); - - mdelay(1); - - count = 0; - while (1) { - val = mv_u3d_phy_read(base, USB3_KVCO_CALI_CONTROL); - if (val & (1 << USB3_KVCO_CALI_CONTROL_CAL_DONE_SHIFT)) - break; - else if (count > 50) { - dev_dbg(mv_u3d_phy->dev, "calibration failure, retry...\n"); - goto calstart; - } - count++; - mdelay(1); - } - - /* active PIPE interface */ - mv_u3d_phy_write(base, USB3_PIPE_SM_CTRL, - 1 << USB3_PIPE_SM_CTRL_PHY_INIT_DONE); - - return 0; -} - -static int mv_u3d_phy_probe(struct platform_device *pdev) -{ - struct mv_u3d_phy *mv_u3d_phy; - struct mv_usb_platform_data *pdata; - struct device *dev = &pdev->dev; - struct resource *res; - void __iomem *phy_base; - int ret; - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "%s: no platform data defined\n", __func__); - return -EINVAL; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - phy_base = devm_ioremap_resource(dev, res); - if (IS_ERR(phy_base)) - return PTR_ERR(phy_base); - - mv_u3d_phy = devm_kzalloc(dev, sizeof(*mv_u3d_phy), GFP_KERNEL); - if (!mv_u3d_phy) - return -ENOMEM; - - mv_u3d_phy->dev = &pdev->dev; - mv_u3d_phy->plat = pdata; - mv_u3d_phy->base = phy_base; - mv_u3d_phy->phy.dev = mv_u3d_phy->dev; - mv_u3d_phy->phy.label = "mv-u3d-phy"; - mv_u3d_phy->phy.init = mv_u3d_phy_init; - mv_u3d_phy->phy.shutdown = mv_u3d_phy_shutdown; - - ret = usb_add_phy(&mv_u3d_phy->phy, USB_PHY_TYPE_USB3); - if (ret) - goto err; - - if (!mv_u3d_phy->clk) - mv_u3d_phy->clk = clk_get(mv_u3d_phy->dev, "u3dphy"); - - platform_set_drvdata(pdev, mv_u3d_phy); - - dev_info(&pdev->dev, "Initialized Marvell USB 3.0 PHY\n"); -err: - return ret; -} - -static int mv_u3d_phy_remove(struct platform_device *pdev) -{ - struct mv_u3d_phy *mv_u3d_phy = platform_get_drvdata(pdev); - - usb_remove_phy(&mv_u3d_phy->phy); - - if (mv_u3d_phy->clk) { - clk_put(mv_u3d_phy->clk); - mv_u3d_phy->clk = NULL; - } - - return 0; -} - -static struct platform_driver mv_u3d_phy_driver = { - .probe = mv_u3d_phy_probe, - .remove = mv_u3d_phy_remove, - .driver = { - .name = "mv-u3d-phy", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(mv_u3d_phy_driver); -MODULE_DESCRIPTION("Marvell USB 3.0 PHY controller"); -MODULE_AUTHOR("Yu Xu <yuxu@marvell.com>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mv-u3d-phy"); |