diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-01-17 16:21:48 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-01-20 11:14:25 +0100 |
commit | 75e71639e09d04ec00ef678eed5776f89ea22986 (patch) | |
tree | 2bad8576141a90cf89b3ad0d6020cb97a8750628 /drivers/usb/imx/imx-usb-phy.c | |
parent | bb2e752fb64d13f7872a4e50c00d94246bb984d6 (diff) | |
download | barebox-75e71639e09d04ec00ef678eed5776f89ea22986.tar.gz barebox-75e71639e09d04ec00ef678eed5776f89ea22986.tar.xz |
USB: Add usb phy driver for i.MX
This phy is found on i.MX6 and i.MX23/28. Currently tested only on i.MX6.
For now we take the easy way out. The phy is enabled upon registration.
More elaborated handling can be added later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb/imx/imx-usb-phy.c')
-rw-r--r-- | drivers/usb/imx/imx-usb-phy.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c new file mode 100644 index 0000000000..ce9c93f42d --- /dev/null +++ b/drivers/usb/imx/imx-usb-phy.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de> + * + * 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; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <common.h> +#include <init.h> +#include <io.h> +#include <driver.h> +#include <malloc.h> +#include <linux/clk.h> +#include <linux/err.h> + +#define SET 0x4 +#define CLR 0x8 + +#define USBPHY_CTRL 0x30 + +#define USBPHY_CTRL_SFTRST (1 << 31) +#define USBPHY_CTRL_CLKGATE (1 << 30) +#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15) +#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14) + +struct imx_usbphy { + void __iomem *base; + struct clk *clk; +}; + +static int imx_usbphy_enable(struct imx_usbphy *imxphy) +{ + u32 val; + + clk_enable(imxphy->clk); + + /* reset usbphy */ + writel(USBPHY_CTRL_SFTRST, imxphy->base + USBPHY_CTRL + SET); + + udelay(10); + + /* clr reset and clkgate */ + writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, + imxphy->base + USBPHY_CTRL + CLR); + + /* clr all pwd bits => power up phy */ + writel(0xffffffff, imxphy->base + CLR); + + /* set utmilvl2/3 */ + val = readl(imxphy->base + USBPHY_CTRL); + val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2; + writel(val, imxphy->base + USBPHY_CTRL + SET); + + return 0; +} + +static int imx_usbphy_probe(struct device_d *dev) +{ + int ret; + struct imx_usbphy *imxphy; + + imxphy = xzalloc(sizeof(*imxphy)); + + imxphy->base = dev_request_mem_region(dev, 0); + if (!imxphy->base) { + ret = -ENODEV; + goto err_free; + } + + imxphy->clk = clk_get(dev, NULL); + if (IS_ERR(imxphy->clk)) { + dev_err(dev, "could not get clk: %s\n", strerror(-PTR_ERR(imxphy->clk))); + goto err_clk; + } + + imx_usbphy_enable(imxphy); + + dev_dbg(dev, "phy enabled\n"); + + return 0; + +err_clk: +err_free: + free(imxphy); + + return ret; +}; + +static struct driver_d imx_usbphy_driver = { + .name = "imx-usb-phy", + .probe = imx_usbphy_probe, +}; + +static int imx_usbphy_init(void) +{ + return platform_driver_register(&imx_usbphy_driver); +} +coredevice_initcall(imx_usbphy_init); |