aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-01-03 04:33:01 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-02-11 02:34:17 -0500
commitcb07625d1f84fb48e6849cb530762ffcc6f8e458 (patch)
treee3eecfdc41e5ee5236c339303d8705938a490fae /arch
parentf19693a17c6705e197eb24d4618060eaac1b535c (diff)
ARM i.MX ehci: factor out soc specific functions
Currently we have a mxc_initialize_usb_hw which is called on every i.MX SoC. This function dispatches the different SoC types, which is quite ugly. This patch moves the SoC specific USB initialization to their correspondive mach directories. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/Makefile4
-rw-r--r--arch/arm/mach-imx/ehci-imx25.c80
-rw-r--r--arch/arm/mach-imx/ehci-imx27.c82
-rw-r--r--arch/arm/mach-mx3/Makefile4
-rw-r--r--arch/arm/mach-mx3/ehci-imx31.c83
-rw-r--r--arch/arm/mach-mx3/ehci-imx35.c80
-rw-r--r--arch/arm/mach-mx5/Makefile2
-rw-r--r--arch/arm/mach-mx5/ehci.c156
-rw-r--r--arch/arm/plat-mxc/ehci.c343
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_ehci.h6
10 files changed, 502 insertions, 338 deletions
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 3e49ae0618aa..b85794d27991 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -9,10 +9,10 @@ obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
9obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o 9obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
10obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o 10obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
11 11
12obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o 12obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o ehci-imx25.o
13 13
14obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o 14obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
15obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o 15obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
16 16
17# Support for CMOS sensor interface 17# Support for CMOS sensor interface
18obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o 18obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
new file mode 100644
index 000000000000..865daf0b09e9
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx25.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <mach/hardware.h>
20#include <mach/mxc_ehci.h>
21
22#define USBCTRL_OTGBASE_OFFSET 0x600
23
24#define MX25_OTG_SIC_SHIFT 29
25#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
26#define MX25_OTG_PM_BIT (1 << 24)
27
28#define MX25_H1_SIC_SHIFT 21
29#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
30#define MX25_H1_PM_BIT (1 << 8)
31#define MX25_H1_IPPUE_UP_BIT (1 << 7)
32#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
33#define MX25_H1_TLL_BIT (1 << 5)
34#define MX25_H1_USBTE_BIT (1 << 4)
35
36int mx25_initialize_usb_hw(int port, unsigned int flags)
37{
38 unsigned int v;
39
40 v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
41
42 switch (port) {
43 case 0: /* OTG port */
44 v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT);
45 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
46
47 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
48 v |= MX25_OTG_PM_BIT;
49
50 break;
51 case 1: /* H1 port */
52 v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_TLL_BIT |
53 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
54 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
55
56 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
57 v |= MX25_H1_PM_BIT;
58
59 if (!(flags & MXC_EHCI_TTL_ENABLED))
60 v |= MX25_H1_TLL_BIT;
61
62 if (flags & MXC_EHCI_INTERNAL_PHY)
63 v |= MX25_H1_USBTE_BIT;
64
65 if (flags & MXC_EHCI_IPPUE_DOWN)
66 v |= MX25_H1_IPPUE_DOWN_BIT;
67
68 if (flags & MXC_EHCI_IPPUE_UP)
69 v |= MX25_H1_IPPUE_UP_BIT;
70
71 break;
72 default:
73 return -EINVAL;
74 }
75
76 writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
77
78 return 0;
79}
80
diff --git a/arch/arm/mach-imx/ehci-imx27.c b/arch/arm/mach-imx/ehci-imx27.c
new file mode 100644
index 000000000000..fa69419eabdd
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx27.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <mach/hardware.h>
20#include <mach/mxc_ehci.h>
21
22#define USBCTRL_OTGBASE_OFFSET 0x600
23
24#define MX27_OTG_SIC_SHIFT 29
25#define MX27_OTG_SIC_MASK (0x3 << MX27_OTG_SIC_SHIFT)
26#define MX27_OTG_PM_BIT (1 << 24)
27
28#define MX27_H2_SIC_SHIFT 21
29#define MX27_H2_SIC_MASK (0x3 << MX27_H2_SIC_SHIFT)
30#define MX27_H2_PM_BIT (1 << 16)
31#define MX27_H2_DT_BIT (1 << 5)
32
33#define MX27_H1_SIC_SHIFT 13
34#define MX27_H1_SIC_MASK (0x3 << MX27_H1_SIC_SHIFT)
35#define MX27_H1_PM_BIT (1 << 8)
36#define MX27_H1_DT_BIT (1 << 4)
37
38int mx27_initialize_usb_hw(int port, unsigned int flags)
39{
40 unsigned int v;
41
42 v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
43
44 switch (port) {
45 case 0: /* OTG port */
46 v &= ~(MX27_OTG_SIC_MASK | MX27_OTG_PM_BIT);
47 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_OTG_SIC_SHIFT;
48
49 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
50 v |= MX27_OTG_PM_BIT;
51 break;
52 case 1: /* H1 port */
53 v &= ~(MX27_H1_SIC_MASK | MX27_H1_PM_BIT | MX27_H1_DT_BIT);
54 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H1_SIC_SHIFT;
55
56 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
57 v |= MX27_H1_PM_BIT;
58
59 if (!(flags & MXC_EHCI_TTL_ENABLED))
60 v |= MX27_H1_DT_BIT;
61
62 break;
63 case 2: /* H2 port */
64 v &= ~(MX27_H2_SIC_MASK | MX27_H2_PM_BIT | MX27_H2_DT_BIT);
65 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H2_SIC_SHIFT;
66
67 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
68 v |= MX27_H2_PM_BIT;
69
70 if (!(flags & MXC_EHCI_TTL_ENABLED))
71 v |= MX27_H2_DT_BIT;
72
73 break;
74 default:
75 return -EINVAL;
76 }
77
78 writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
79
80 return 0;
81}
82
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index bc7294f87011..224d07a79d7e 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -5,8 +5,8 @@
5# Object file lists. 5# Object file lists.
6 6
7obj-y := mm.o devices.o cpu.o 7obj-y := mm.o devices.o cpu.o
8obj-$(CONFIG_SOC_IMX31) += clock-imx31.o iomux-imx31.o 8obj-$(CONFIG_SOC_IMX31) += clock-imx31.o iomux-imx31.o ehci-imx31.o
9obj-$(CONFIG_SOC_IMX35) += clock-imx35.o 9obj-$(CONFIG_SOC_IMX35) += clock-imx35.o ehci-imx35.o
10obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o 10obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
11obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o 11obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o
12obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o 12obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o
diff --git a/arch/arm/mach-mx3/ehci-imx31.c b/arch/arm/mach-mx3/ehci-imx31.c
new file mode 100644
index 000000000000..314a983ac614
--- /dev/null
+++ b/arch/arm/mach-mx3/ehci-imx31.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <mach/hardware.h>
20#include <mach/mxc_ehci.h>
21
22#define USBCTRL_OTGBASE_OFFSET 0x600
23
24#define MX31_OTG_SIC_SHIFT 29
25#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
26#define MX31_OTG_PM_BIT (1 << 24)
27
28#define MX31_H2_SIC_SHIFT 21
29#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT)
30#define MX31_H2_PM_BIT (1 << 16)
31#define MX31_H2_DT_BIT (1 << 5)
32
33#define MX31_H1_SIC_SHIFT 13
34#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT)
35#define MX31_H1_PM_BIT (1 << 8)
36#define MX31_H1_DT_BIT (1 << 4)
37
38int mx31_initialize_usb_hw(int port, unsigned int flags)
39{
40 unsigned int v;
41
42 v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
43
44 switch (port) {
45 case 0: /* OTG port */
46 v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
47 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT;
48
49 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
50 v |= MX31_OTG_PM_BIT;
51
52 break;
53 case 1: /* H1 port */
54 v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
55 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT;
56
57 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
58 v |= MX31_H1_PM_BIT;
59
60 if (!(flags & MXC_EHCI_TTL_ENABLED))
61 v |= MX31_H1_DT_BIT;
62
63 break;
64 case 2: /* H2 port */
65 v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
66 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT;
67
68 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
69 v |= MX31_H2_PM_BIT;
70
71 if (!(flags & MXC_EHCI_TTL_ENABLED))
72 v |= MX31_H2_DT_BIT;
73
74 break;
75 default:
76 return -EINVAL;
77 }
78
79 writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
80
81 return 0;
82}
83
diff --git a/arch/arm/mach-mx3/ehci-imx35.c b/arch/arm/mach-mx3/ehci-imx35.c
new file mode 100644
index 000000000000..33983a478c6b
--- /dev/null
+++ b/arch/arm/mach-mx3/ehci-imx35.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <mach/hardware.h>
20#include <mach/mxc_ehci.h>
21
22#define USBCTRL_OTGBASE_OFFSET 0x600
23
24#define MX35_OTG_SIC_SHIFT 29
25#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
26#define MX35_OTG_PM_BIT (1 << 24)
27
28#define MX35_H1_SIC_SHIFT 21
29#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
30#define MX35_H1_PM_BIT (1 << 8)
31#define MX35_H1_IPPUE_UP_BIT (1 << 7)
32#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
33#define MX35_H1_TLL_BIT (1 << 5)
34#define MX35_H1_USBTE_BIT (1 << 4)
35
36int mx35_initialize_usb_hw(int port, unsigned int flags)
37{
38 unsigned int v;
39
40 v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
41
42 switch (port) {
43 case 0: /* OTG port */
44 v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
45 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT;
46
47 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
48 v |= MX35_OTG_PM_BIT;
49
50 break;
51 case 1: /* H1 port */
52 v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
53 MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
54 v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT;
55
56 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
57 v |= MX35_H1_PM_BIT;
58
59 if (!(flags & MXC_EHCI_TTL_ENABLED))
60 v |= MX35_H1_TLL_BIT;
61
62 if (flags & MXC_EHCI_INTERNAL_PHY)
63 v |= MX35_H1_USBTE_BIT;
64
65 if (flags & MXC_EHCI_IPPUE_DOWN)
66 v |= MX35_H1_IPPUE_DOWN_BIT;
67
68 if (flags & MXC_EHCI_IPPUE_UP)
69 v |= MX35_H1_IPPUE_UP_BIT;
70
71 break;
72 default:
73 return -EINVAL;
74 }
75
76 writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
77
78 return 0;
79}
80
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 0d43be98e51c..dc2728823fdd 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Object file lists. 5# Object file lists.
6obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o 6obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
7obj-$(CONFIG_SOC_IMX50) += mm-mx50.o 7obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
8 8
9obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o 9obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
diff --git a/arch/arm/mach-mx5/ehci.c b/arch/arm/mach-mx5/ehci.c
new file mode 100644
index 000000000000..7ce12c804a32
--- /dev/null
+++ b/arch/arm/mach-mx5/ehci.c
@@ -0,0 +1,156 @@
1/*
2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <mach/hardware.h>
20#include <mach/mxc_ehci.h>
21
22#define MXC_OTG_OFFSET 0
23#define MXC_H1_OFFSET 0x200
24#define MXC_H2_OFFSET 0x400
25
26/* USB_CTRL */
27#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
28#define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
29#define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
30#define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
31#define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
32
33/* USB_PHY_CTRL_FUNC */
34#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
35#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
36
37/* USBH2CTRL */
38#define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
39#define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
40#define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
41
42#define MXC_USBCMD_OFFSET 0x140
43
44/* USBCMD */
45#define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */
46
47int mx51_initialize_usb_hw(int port, unsigned int flags)
48{
49 unsigned int v;
50 void __iomem *usb_base;
51 void __iomem *usbotg_base;
52 void __iomem *usbother_base;
53 int ret = 0;
54
55 usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
56 if (!usb_base) {
57 printk(KERN_ERR "%s(): ioremap failed\n", __func__);
58 return -ENOMEM;
59 }
60
61 switch (port) {
62 case 0: /* OTG port */
63 usbotg_base = usb_base + MXC_OTG_OFFSET;
64 break;
65 case 1: /* Host 1 port */
66 usbotg_base = usb_base + MXC_H1_OFFSET;
67 break;
68 case 2: /* Host 2 port */
69 usbotg_base = usb_base + MXC_H2_OFFSET;
70 break;
71 default:
72 printk(KERN_ERR"%s no such port %d\n", __func__, port);
73 ret = -ENOENT;
74 goto error;
75 }
76 usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
77
78 switch (port) {
79 case 0: /*OTG port */
80 if (flags & MXC_EHCI_INTERNAL_PHY) {
81 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
82
83 if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
84 /* OC/USBPWR is not used */
85 v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
86 } else {
87 /* OC/USBPWR is used */
88 v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
89 }
90 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
91
92 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
93 if (flags & MXC_EHCI_WAKEUP_ENABLED)
94 v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
95 else
96 v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
97 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
98 v |= MXC_OTG_UCTRL_OPM_BIT;
99 else
100 v &= ~MXC_OTG_UCTRL_OPM_BIT;
101 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
102 }
103 break;
104 case 1: /* Host 1 */
105 /*Host ULPI */
106 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
107 if (flags & MXC_EHCI_WAKEUP_ENABLED) {
108 /* HOST1 wakeup/ULPI intr enable */
109 v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
110 } else {
111 /* HOST1 wakeup/ULPI intr disable */
112 v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
113 }
114
115 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
116 v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
117 else
118 v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
119 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
120
121 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
122 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
123 v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
124 else
125 v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
126 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
127
128 v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
129 if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
130 /* Interrupt Threshold Control:Immediate (no threshold) */
131 v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
132 __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
133 break;
134 case 2: /* Host 2 ULPI */
135 v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
136 if (flags & MXC_EHCI_WAKEUP_ENABLED) {
137 /* HOST1 wakeup/ULPI intr enable */
138 v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
139 } else {
140 /* HOST1 wakeup/ULPI intr disable */
141 v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
142 }
143
144 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
145 v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
146 else
147 v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
148 __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
149 break;
150 }
151
152error:
153 iounmap(usb_base);
154 return ret;
155}
156
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 8772ce346a58..06fb3a4d7c27 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -14,352 +14,29 @@
14 */ 14 */
15 15
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/io.h>
18 17
19#include <mach/hardware.h> 18#include <mach/hardware.h>
20#include <mach/mxc_ehci.h> 19#include <mach/mxc_ehci.h>
21 20
22#define USBCTRL_OTGBASE_OFFSET 0x600
23
24#define MX31_OTG_SIC_SHIFT 29
25#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
26#define MX31_OTG_PM_BIT (1 << 24)
27
28#define MX31_H2_SIC_SHIFT 21
29#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT)
30#define MX31_H2_PM_BIT (1 << 16)
31#define MX31_H2_DT_BIT (1 << 5)
32
33#define MX31_H1_SIC_SHIFT 13
34#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT)
35#define MX31_H1_PM_BIT (1 << 8)
36#define MX31_H1_DT_BIT (1 << 4)
37
38#define MX35_OTG_SIC_SHIFT 29
39#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
40#define MX35_OTG_PM_BIT (1 << 24)
41
42#define MX35_H1_SIC_SHIFT 21
43#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
44#define MX35_H1_PM_BIT (1 << 8)
45#define MX35_H1_IPPUE_UP_BIT (1 << 7)
46#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
47#define MX35_H1_TLL_BIT (1 << 5)
48#define MX35_H1_USBTE_BIT (1 << 4)
49
50#define MXC_OTG_OFFSET 0
51#define MXC_H1_OFFSET 0x200
52#define MXC_H2_OFFSET 0x400
53
54/* USB_CTRL */
55#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
56#define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
57#define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
58#define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
59#define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
60
61/* USB_PHY_CTRL_FUNC */
62#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
63#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
64
65/* USBH2CTRL */
66#define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
67#define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
68#define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
69
70#define MXC_USBCMD_OFFSET 0x140
71
72/* USBCMD */
73#define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */
74
75int mxc_initialize_usb_hw(int port, unsigned int flags) 21int mxc_initialize_usb_hw(int port, unsigned int flags)
76{ 22{
77 unsigned int v;
78#if defined(CONFIG_SOC_IMX25) 23#if defined(CONFIG_SOC_IMX25)
79 if (cpu_is_mx25()) { 24 if (cpu_is_mx25())
80 v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + 25 return mx25_initialize_usb_hw(port, flags);
81 USBCTRL_OTGBASE_OFFSET));
82
83 switch (port) {
84 case 0: /* OTG port */
85 v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
86 v |= (flags & MXC_EHCI_INTERFACE_MASK)
87 << MX35_OTG_SIC_SHIFT;
88 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
89 v |= MX35_OTG_PM_BIT;
90
91 break;
92 case 1: /* H1 port */
93 v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
94 MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
95 v |= (flags & MXC_EHCI_INTERFACE_MASK)
96 << MX35_H1_SIC_SHIFT;
97 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
98 v |= MX35_H1_PM_BIT;
99
100 if (!(flags & MXC_EHCI_TTL_ENABLED))
101 v |= MX35_H1_TLL_BIT;
102
103 if (flags & MXC_EHCI_INTERNAL_PHY)
104 v |= MX35_H1_USBTE_BIT;
105
106 if (flags & MXC_EHCI_IPPUE_DOWN)
107 v |= MX35_H1_IPPUE_DOWN_BIT;
108
109 if (flags & MXC_EHCI_IPPUE_UP)
110 v |= MX35_H1_IPPUE_UP_BIT;
111
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR +
118 USBCTRL_OTGBASE_OFFSET));
119 return 0;
120 }
121#endif /* if defined(CONFIG_SOC_IMX25) */ 26#endif /* if defined(CONFIG_SOC_IMX25) */
122#if defined(CONFIG_ARCH_MX3) 27#if defined(CONFIG_ARCH_MX3)
123 if (cpu_is_mx31()) { 28 if (cpu_is_mx31())
124 v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + 29 return mx31_initialize_usb_hw(port, flags);
125 USBCTRL_OTGBASE_OFFSET)); 30 if (cpu_is_mx35())
126 31 return mx35_initialize_usb_hw(port, flags);
127 switch (port) {
128 case 0: /* OTG port */
129 v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
130 v |= (flags & MXC_EHCI_INTERFACE_MASK)
131 << MX31_OTG_SIC_SHIFT;
132 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
133 v |= MX31_OTG_PM_BIT;
134
135 break;
136 case 1: /* H1 port */
137 v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
138 v |= (flags & MXC_EHCI_INTERFACE_MASK)
139 << MX31_H1_SIC_SHIFT;
140 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
141 v |= MX31_H1_PM_BIT;
142
143 if (!(flags & MXC_EHCI_TTL_ENABLED))
144 v |= MX31_H1_DT_BIT;
145
146 break;
147 case 2: /* H2 port */
148 v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
149 v |= (flags & MXC_EHCI_INTERFACE_MASK)
150 << MX31_H2_SIC_SHIFT;
151 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
152 v |= MX31_H2_PM_BIT;
153
154 if (!(flags & MXC_EHCI_TTL_ENABLED))
155 v |= MX31_H2_DT_BIT;
156
157 break;
158 default:
159 return -EINVAL;
160 }
161
162 writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR +
163 USBCTRL_OTGBASE_OFFSET));
164 return 0;
165 }
166
167 if (cpu_is_mx35()) {
168 v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
169 USBCTRL_OTGBASE_OFFSET));
170
171 switch (port) {
172 case 0: /* OTG port */
173 v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
174 v |= (flags & MXC_EHCI_INTERFACE_MASK)
175 << MX35_OTG_SIC_SHIFT;
176 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
177 v |= MX35_OTG_PM_BIT;
178
179 break;
180 case 1: /* H1 port */
181 v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
182 MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
183 v |= (flags & MXC_EHCI_INTERFACE_MASK)
184 << MX35_H1_SIC_SHIFT;
185 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
186 v |= MX35_H1_PM_BIT;
187
188 if (!(flags & MXC_EHCI_TTL_ENABLED))
189 v |= MX35_H1_TLL_BIT;
190
191 if (flags & MXC_EHCI_INTERNAL_PHY)
192 v |= MX35_H1_USBTE_BIT;
193
194 if (flags & MXC_EHCI_IPPUE_DOWN)
195 v |= MX35_H1_IPPUE_DOWN_BIT;
196
197 if (flags & MXC_EHCI_IPPUE_UP)
198 v |= MX35_H1_IPPUE_UP_BIT;
199
200 break;
201 default:
202 return -EINVAL;
203 }
204
205 writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
206 USBCTRL_OTGBASE_OFFSET));
207 return 0;
208 }
209#endif /* CONFIG_ARCH_MX3 */ 32#endif /* CONFIG_ARCH_MX3 */
210#ifdef CONFIG_MACH_MX27 33#ifdef CONFIG_MACH_MX27
211 if (cpu_is_mx27()) { 34 if (cpu_is_mx27())
212 /* On i.MX27 we can use the i.MX31 USBCTRL bits, they 35 return mx27_initialize_usb_hw(port, flags);
213 * are identical
214 */
215 v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
216 USBCTRL_OTGBASE_OFFSET));
217 switch (port) {
218 case 0: /* OTG port */
219 v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
220 v |= (flags & MXC_EHCI_INTERFACE_MASK)
221 << MX31_OTG_SIC_SHIFT;
222 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
223 v |= MX31_OTG_PM_BIT;
224 break;
225 case 1: /* H1 port */
226 v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
227 v |= (flags & MXC_EHCI_INTERFACE_MASK)
228 << MX31_H1_SIC_SHIFT;
229 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
230 v |= MX31_H1_PM_BIT;
231
232 if (!(flags & MXC_EHCI_TTL_ENABLED))
233 v |= MX31_H1_DT_BIT;
234
235 break;
236 case 2: /* H2 port */
237 v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
238 v |= (flags & MXC_EHCI_INTERFACE_MASK)
239 << MX31_H2_SIC_SHIFT;
240 if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
241 v |= MX31_H2_PM_BIT;
242
243 if (!(flags & MXC_EHCI_TTL_ENABLED))
244 v |= MX31_H2_DT_BIT;
245
246 break;
247 default:
248 return -EINVAL;
249 }
250 writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
251 USBCTRL_OTGBASE_OFFSET));
252 return 0;
253 }
254#endif /* CONFIG_MACH_MX27 */ 36#endif /* CONFIG_MACH_MX27 */
255#ifdef CONFIG_SOC_IMX51 37#ifdef CONFIG_SOC_IMX51
256 if (cpu_is_mx51()) { 38 if (cpu_is_mx51())
257 void __iomem *usb_base; 39 return mx51_initialize_usb_hw(port, flags);
258 void __iomem *usbotg_base;
259 void __iomem *usbother_base;
260 int ret = 0;
261
262 usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
263 if (!usb_base) {
264 printk(KERN_ERR "%s(): ioremap failed\n", __func__);
265 return -ENOMEM;
266 }
267
268 switch (port) {
269 case 0: /* OTG port */
270 usbotg_base = usb_base + MXC_OTG_OFFSET;
271 break;
272 case 1: /* Host 1 port */
273 usbotg_base = usb_base + MXC_H1_OFFSET;
274 break;
275 case 2: /* Host 2 port */
276 usbotg_base = usb_base + MXC_H2_OFFSET;
277 break;
278 default:
279 printk(KERN_ERR"%s no such port %d\n", __func__, port);
280 ret = -ENOENT;
281 goto error;
282 }
283 usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
284
285 switch (port) {
286 case 0: /*OTG port */
287 if (flags & MXC_EHCI_INTERNAL_PHY) {
288 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
289
290 if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
291 /* OC/USBPWR is not used */
292 v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
293 } else {
294 /* OC/USBPWR is used */
295 v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
296 }
297 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
298
299 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
300 if (flags & MXC_EHCI_WAKEUP_ENABLED)
301 v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
302 else
303 v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
304 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
305 v |= MXC_OTG_UCTRL_OPM_BIT;
306 else
307 v &= ~MXC_OTG_UCTRL_OPM_BIT;
308 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
309 }
310 break;
311 case 1: /* Host 1 */
312 /*Host ULPI */
313 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
314 if (flags & MXC_EHCI_WAKEUP_ENABLED) {
315 /* HOST1 wakeup/ULPI intr enable */
316 v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
317 } else {
318 /* HOST1 wakeup/ULPI intr disable */
319 v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
320 }
321
322 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
323 v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
324 else
325 v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
326 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
327
328 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
329 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
330 v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
331 else
332 v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
333 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
334
335 v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
336 if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
337 /* Interrupt Threshold Control:Immediate (no threshold) */
338 v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
339 __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
340 break;
341 case 2: /* Host 2 ULPI */
342 v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
343 if (flags & MXC_EHCI_WAKEUP_ENABLED) {
344 /* HOST1 wakeup/ULPI intr enable */
345 v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
346 } else {
347 /* HOST1 wakeup/ULPI intr disable */
348 v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
349 }
350
351 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
352 v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
353 else
354 v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
355 __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
356 break;
357 }
358
359error:
360 iounmap(usb_base);
361 return ret;
362 }
363#endif 40#endif
364 printk(KERN_WARNING 41 printk(KERN_WARNING
365 "%s() unable to setup USBCONTROL for this CPU\n", __func__); 42 "%s() unable to setup USBCONTROL for this CPU\n", __func__);
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
index a523a4079299..7e555a1f4a4a 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -50,5 +50,11 @@ struct mxc_usbh_platform_data {
50 50
51int mxc_initialize_usb_hw(int port, unsigned int flags); 51int mxc_initialize_usb_hw(int port, unsigned int flags);
52 52
53int mx51_initialize_usb_hw(int port, unsigned int flags);
54int mx25_initialize_usb_hw(int port, unsigned int flags);
55int mx31_initialize_usb_hw(int port, unsigned int flags);
56int mx35_initialize_usb_hw(int port, unsigned int flags);
57int mx27_initialize_usb_hw(int port, unsigned int flags);
58
53#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */ 59#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
54 60