summaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/usbmisc_imx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 11:31:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 11:31:16 -0700
commit3f17ea6dea8ba5668873afa54628a91aaa3fb1c0 (patch)
treeafbeb2accd4c2199ddd705ae943995b143a0af02 /drivers/usb/chipidea/usbmisc_imx.c
parent1860e379875dfe7271c649058aeddffe5afd9d0d (diff)
parent1a5700bc2d10cd379a795fd2bb377a190af5acd4 (diff)
Merge branch 'next' (accumulated 3.16 merge window patches) into master
Now that 3.15 is released, this merges the 'next' branch into 'master', bringing us to the normal situation where my 'master' branch is the merge window. * accumulated work in next: (6809 commits) ufs: sb mutex merge + mutex_destroy powerpc: update comments for generic idle conversion cris: update comments for generic idle conversion idle: remove cpu_idle() forward declarations nbd: zero from and len fields in NBD_CMD_DISCONNECT. mm: convert some level-less printks to pr_* MAINTAINERS: adi-buildroot-devel is moderated MAINTAINERS: add linux-api for review of API/ABI changes mm/kmemleak-test.c: use pr_fmt for logging fs/dlm/debug_fs.c: replace seq_printf by seq_puts fs/dlm/lockspace.c: convert simple_str to kstr fs/dlm/config.c: convert simple_str to kstr mm: mark remap_file_pages() syscall as deprecated mm: memcontrol: remove unnecessary memcg argument from soft limit functions mm: memcontrol: clean up memcg zoneinfo lookup mm/memblock.c: call kmemleak directly from memblock_(alloc|free) mm/mempool.c: update the kmemleak stack trace for mempool allocations lib/radix-tree.c: update the kmemleak stack trace for radix tree allocations mm: introduce kmemleak_update_trace() mm/kmemleak.c: use %u to print ->checksum ...
Diffstat (limited to 'drivers/usb/chipidea/usbmisc_imx.c')
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index cd061abe350..85293b8b1df 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -21,16 +21,39 @@
#define MX25_USB_PHY_CTRL_OFFSET 0x08
#define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23)
+#define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
+#define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0)
+#define MX25_EHCI_INTERFACE_MASK (0xf)
+
+#define MX25_OTG_SIC_SHIFT 29
+#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
+#define MX25_OTG_PM_BIT BIT(24)
+#define MX25_OTG_PP_BIT BIT(11)
+#define MX25_OTG_OCPOL_BIT BIT(3)
+
+#define MX25_H1_SIC_SHIFT 21
+#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
+#define MX25_H1_PP_BIT BIT(18)
+#define MX25_H1_PM_BIT BIT(16)
+#define MX25_H1_IPPUE_UP_BIT BIT(7)
+#define MX25_H1_IPPUE_DOWN_BIT BIT(6)
+#define MX25_H1_TLL_BIT BIT(5)
+#define MX25_H1_USBTE_BIT BIT(4)
+#define MX25_H1_OCPOL_BIT BIT(2)
+
#define MX27_H1_PM_BIT BIT(8)
#define MX27_H2_PM_BIT BIT(16)
#define MX27_OTG_PM_BIT BIT(24)
#define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08
+#define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c
#define MX53_USB_UH2_CTRL_OFFSET 0x14
#define MX53_USB_UH3_CTRL_OFFSET 0x18
#define MX53_BM_OVER_CUR_DIS_H1 BIT(5)
#define MX53_BM_OVER_CUR_DIS_OTG BIT(8)
#define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
+#define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3
+#define MX53_USB_PLL_DIV_24_MHZ 0x01
#define MX6_BM_OVER_CUR_DIS BIT(7)
@@ -50,6 +73,39 @@ struct imx_usbmisc {
static struct imx_usbmisc *usbmisc;
+static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
+{
+ unsigned long flags;
+ u32 val = 0;
+
+ if (data->index > 1)
+ return -EINVAL;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ switch (data->index) {
+ case 0:
+ val = readl(usbmisc->base);
+ val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT);
+ val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
+ val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT);
+ writel(val, usbmisc->base);
+ break;
+ case 1:
+ val = readl(usbmisc->base);
+ val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT);
+ val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
+ val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT |
+ MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT);
+
+ writel(val, usbmisc->base);
+
+ break;
+ }
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
{
void __iomem *reg;
@@ -111,6 +167,13 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
if (data->index > 3)
return -EINVAL;
+ /* Select a 24 MHz reference clock for the PHY */
+ reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET;
+ val = readl(reg);
+ val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK;
+ val |= MX53_USB_PLL_DIV_24_MHZ;
+ writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
+
if (data->disable_oc) {
spin_lock_irqsave(&usbmisc->lock, flags);
switch (data->index) {
@@ -159,6 +222,7 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
}
static const struct usbmisc_ops imx25_usbmisc_ops = {
+ .init = usbmisc_imx25_init,
.post = usbmisc_imx25_post,
};
@@ -200,6 +264,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
.data = &imx25_usbmisc_ops,
},
{
+ .compatible = "fsl,imx35-usbmisc",
+ .data = &imx25_usbmisc_ops,
+ },
+ {
.compatible = "fsl,imx27-usbmisc",
.data = &imx27_usbmisc_ops,
},