diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 20:17:35 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 20:17:35 -0700 |
| commit | e6445f52d9c8b0e6557a45fa7d0e8e088d430a8c (patch) | |
| tree | 0c9dbec3a5655beda1848b321c4d9dbeb27987a6 /drivers/usb/phy/phy-mxs-usb.c | |
| parent | e6dce825fba05f447bd22c865e27233182ab3d79 (diff) | |
| parent | ab21b63e8aedfc73565dd9cdd51eb338341177cb (diff) | |
Merge tag 'usb-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull usb/phy/extcon updates from Greg KH:
"Here is the big USB, and PHY, and extcon, patchsets for 4.9-rc1.
Full details are in the shortlog, but generally a lot of new hardware
support, usb gadget updates, and Wolfram's great cleanup of USB error
message handling, making the kernel image a tad bit smaller.
All of this has been in linux-next with no reported issues"
* tag 'usb-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (343 commits)
Revert "usbtmc: convert to devm_kzalloc"
USB: serial: cp210x: Add ID for a Juniper console
usb: Kconfig: using select for USB_COMMON dependency
bluetooth: bcm203x: don't print error when allocating urb fails
mmc: host: vub300: don't print error when allocating urb fails
usb: hub: change CLEAR_FEATURE to SET_FEATURE
usb: core: Introduce a USB port LED trigger
USB: bcma: drop Northstar PHY 2.0 initialization code
usb: core: hcd: add missing header dependencies
usb: musb: da8xx: fix error handling message in probe
usb: musb: Fix session based PM for first invalid VBUS
usb: musb: Fix PM runtime for disconnect after unconfigure
musb: Export musb_root_disconnect for use in modules
usb: misc: legousbtower: Fix NULL pointer deference
cdc-acm: hardening against malicious devices
Revert "usb: gadget: NCM: Protect dev->port_usb using dev->lock"
include: extcon: Fix compilation error caused because of incomplete merge
MAINTAINERS: add tree entry for USB Serial
phy-twl4030-usb: initialize charging-related stuff via pm_runtime
phy-twl4030-usb: better handle musb_mailbox() failure
...
Diffstat (limited to 'drivers/usb/phy/phy-mxs-usb.c')
| -rw-r--r-- | drivers/usb/phy/phy-mxs-usb.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 00bfea01be65..0e2f1a36d315 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -27,6 +27,7 @@ #define DRIVER_NAME "mxs_phy" #define HW_USBPHY_PWD 0x00 +#define HW_USBPHY_TX 0x10 #define HW_USBPHY_CTRL 0x30 #define HW_USBPHY_CTRL_SET 0x34 #define HW_USBPHY_CTRL_CLR 0x38 @@ -38,6 +39,10 @@ #define HW_USBPHY_IP_SET 0x94 #define HW_USBPHY_IP_CLR 0x98 +#define GM_USBPHY_TX_TXCAL45DP(x) (((x) & 0xf) << 16) +#define GM_USBPHY_TX_TXCAL45DN(x) (((x) & 0xf) << 8) +#define GM_USBPHY_TX_D_CAL(x) (((x) & 0xf) << 0) + #define BM_USBPHY_CTRL_SFTRST BIT(31) #define BM_USBPHY_CTRL_CLKGATE BIT(30) #define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27) @@ -115,6 +120,12 @@ */ #define MXS_PHY_NEED_IP_FIX BIT(3) +/* Minimum and maximum values for device tree entries */ +#define MXS_PHY_TX_CAL45_MIN 30 +#define MXS_PHY_TX_CAL45_MAX 55 +#define MXS_PHY_TX_D_CAL_MIN 79 +#define MXS_PHY_TX_D_CAL_MAX 119 + struct mxs_phy_data { unsigned int flags; }; @@ -164,6 +175,8 @@ struct mxs_phy { const struct mxs_phy_data *data; struct regmap *regmap_anatop; int port_id; + u32 tx_reg_set; + u32 tx_reg_mask; }; static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy) @@ -185,6 +198,20 @@ static void mxs_phy_clock_switch_delay(void) usleep_range(300, 400); } +static void mxs_phy_tx_init(struct mxs_phy *mxs_phy) +{ + void __iomem *base = mxs_phy->phy.io_priv; + u32 phytx; + + /* Update TX register if there is anything to write */ + if (mxs_phy->tx_reg_mask) { + phytx = readl(base + HW_USBPHY_TX); + phytx &= ~mxs_phy->tx_reg_mask; + phytx |= mxs_phy->tx_reg_set; + writel(phytx, base + HW_USBPHY_TX); + } +} + static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) { int ret; @@ -214,6 +241,8 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); + mxs_phy_tx_init(mxs_phy); + return 0; } @@ -459,6 +488,7 @@ static int mxs_phy_probe(struct platform_device *pdev) int ret; const struct of_device_id *of_id; struct device_node *np = pdev->dev.of_node; + u32 val; of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev); if (!of_id) @@ -491,6 +521,37 @@ static int mxs_phy_probe(struct platform_device *pdev) } } + /* Precompute which bits of the TX register are to be updated, if any */ + if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) && + val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) { + /* Scale to a 4-bit value */ + val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF + / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN); + mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0); + mxs_phy->tx_reg_set |= GM_USBPHY_TX_TXCAL45DN(val); + } + + if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) && + val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) { + /* Scale to a 4-bit value. */ + val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF + / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN); + mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0); + mxs_phy->tx_reg_set |= GM_USBPHY_TX_TXCAL45DP(val); + } + + if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) && + val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) { + /* Scale to a 4-bit value. Round up the values and heavily + * weight the rounding by adding 2/3 of the denominator. + */ + val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF + + (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3) + / (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN); + mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0); + mxs_phy->tx_reg_set |= GM_USBPHY_TX_D_CAL(val); + } + ret = of_alias_get_id(np, "usbphy"); if (ret < 0) dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret); |
