• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/arm/plat-mxc/
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
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
53/* USB_CTRL */
54#define MXC_OTG_UCTRL_OWIE_BIT		(1 << 27)	/* OTG wakeup intr enable */
55#define MXC_OTG_UCTRL_OPM_BIT		(1 << 24)	/* OTG power mask */
56#define MXC_H1_UCTRL_H1UIE_BIT		(1 << 12)	/* Host1 ULPI interrupt enable */
57#define MXC_H1_UCTRL_H1WIE_BIT		(1 << 11)	/* HOST1 wakeup intr enable */
58#define MXC_H1_UCTRL_H1PM_BIT		(1 <<  8)		/* HOST1 power mask */
59
60/* USB_PHY_CTRL_FUNC */
61#define MXC_OTG_PHYCTRL_OC_DIS_BIT	(1 << 8)	/* OTG Disable Overcurrent Event */
62#define MXC_H1_OC_DIS_BIT			(1 << 5)	/* UH1 Disable Overcurrent Event */
63
64#define MXC_USBCMD_OFFSET			0x140
65
66/* USBCMD */
67#define MXC_UCMD_ITC_NO_THRESHOLD_MASK	(~(0xff << 16))	/* Interrupt Threshold Control */
68
69int mxc_initialize_usb_hw(int port, unsigned int flags)
70{
71	unsigned int v;
72#if defined(CONFIG_ARCH_MX25)
73	if (cpu_is_mx25()) {
74		v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
75				     USBCTRL_OTGBASE_OFFSET));
76
77		switch (port) {
78		case 0:	/* OTG port */
79			v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
80			v |= (flags & MXC_EHCI_INTERFACE_MASK)
81					<< MX35_OTG_SIC_SHIFT;
82			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
83				v |= MX35_OTG_PM_BIT;
84
85			break;
86		case 1: /* H1 port */
87			v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
88				MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
89			v |= (flags & MXC_EHCI_INTERFACE_MASK)
90						<< MX35_H1_SIC_SHIFT;
91			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
92				v |= MX35_H1_PM_BIT;
93
94			if (!(flags & MXC_EHCI_TTL_ENABLED))
95				v |= MX35_H1_TLL_BIT;
96
97			if (flags & MXC_EHCI_INTERNAL_PHY)
98				v |= MX35_H1_USBTE_BIT;
99
100			if (flags & MXC_EHCI_IPPUE_DOWN)
101				v |= MX35_H1_IPPUE_DOWN_BIT;
102
103			if (flags & MXC_EHCI_IPPUE_UP)
104				v |= MX35_H1_IPPUE_UP_BIT;
105
106			break;
107		default:
108			return -EINVAL;
109		}
110
111		writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
112				     USBCTRL_OTGBASE_OFFSET));
113		return 0;
114	}
115#endif /* CONFIG_ARCH_MX25 */
116#if defined(CONFIG_ARCH_MX3)
117	if (cpu_is_mx31()) {
118		v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
119				     USBCTRL_OTGBASE_OFFSET));
120
121		switch (port) {
122		case 0:	/* OTG port */
123			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
124			v |= (flags & MXC_EHCI_INTERFACE_MASK)
125					<< MX31_OTG_SIC_SHIFT;
126			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
127				v |= MX31_OTG_PM_BIT;
128
129			break;
130		case 1: /* H1 port */
131			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
132			v |= (flags & MXC_EHCI_INTERFACE_MASK)
133						<< MX31_H1_SIC_SHIFT;
134			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
135				v |= MX31_H1_PM_BIT;
136
137			if (!(flags & MXC_EHCI_TTL_ENABLED))
138				v |= MX31_H1_DT_BIT;
139
140			break;
141		case 2:	/* H2 port */
142			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
143			v |= (flags & MXC_EHCI_INTERFACE_MASK)
144						<< MX31_H2_SIC_SHIFT;
145			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
146				v |= MX31_H2_PM_BIT;
147
148			if (!(flags & MXC_EHCI_TTL_ENABLED))
149				v |= MX31_H2_DT_BIT;
150
151			break;
152		default:
153			return -EINVAL;
154		}
155
156		writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
157				     USBCTRL_OTGBASE_OFFSET));
158		return 0;
159	}
160
161	if (cpu_is_mx35()) {
162		v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
163				     USBCTRL_OTGBASE_OFFSET));
164
165		switch (port) {
166		case 0:	/* OTG port */
167			v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
168			v |= (flags & MXC_EHCI_INTERFACE_MASK)
169					<< MX35_OTG_SIC_SHIFT;
170			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
171				v |= MX35_OTG_PM_BIT;
172
173			break;
174		case 1: /* H1 port */
175			v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
176				MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
177			v |= (flags & MXC_EHCI_INTERFACE_MASK)
178						<< MX35_H1_SIC_SHIFT;
179			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
180				v |= MX35_H1_PM_BIT;
181
182			if (!(flags & MXC_EHCI_TTL_ENABLED))
183				v |= MX35_H1_TLL_BIT;
184
185			if (flags & MXC_EHCI_INTERNAL_PHY)
186				v |= MX35_H1_USBTE_BIT;
187
188			if (flags & MXC_EHCI_IPPUE_DOWN)
189				v |= MX35_H1_IPPUE_DOWN_BIT;
190
191			if (flags & MXC_EHCI_IPPUE_UP)
192				v |= MX35_H1_IPPUE_UP_BIT;
193
194			break;
195		default:
196			return -EINVAL;
197		}
198
199		writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
200				     USBCTRL_OTGBASE_OFFSET));
201		return 0;
202	}
203#endif /* CONFIG_ARCH_MX3 */
204#ifdef CONFIG_MACH_MX27
205	if (cpu_is_mx27()) {
206		/* On i.MX27 we can use the i.MX31 USBCTRL bits, they
207		 * are identical
208		 */
209		v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
210				     USBCTRL_OTGBASE_OFFSET));
211		switch (port) {
212		case 0:	/* OTG port */
213			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
214			v |= (flags & MXC_EHCI_INTERFACE_MASK)
215					<< MX31_OTG_SIC_SHIFT;
216			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
217				v |= MX31_OTG_PM_BIT;
218			break;
219		case 1: /* H1 port */
220			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
221			v |= (flags & MXC_EHCI_INTERFACE_MASK)
222						<< MX31_H1_SIC_SHIFT;
223			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
224				v |= MX31_H1_PM_BIT;
225
226			if (!(flags & MXC_EHCI_TTL_ENABLED))
227				v |= MX31_H1_DT_BIT;
228
229			break;
230		case 2:	/* H2 port */
231			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
232			v |= (flags & MXC_EHCI_INTERFACE_MASK)
233						<< MX31_H2_SIC_SHIFT;
234			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
235				v |= MX31_H2_PM_BIT;
236
237			if (!(flags & MXC_EHCI_TTL_ENABLED))
238				v |= MX31_H2_DT_BIT;
239
240			break;
241		default:
242			return -EINVAL;
243		}
244		writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
245				     USBCTRL_OTGBASE_OFFSET));
246		return 0;
247	}
248#endif /* CONFIG_MACH_MX27 */
249#ifdef CONFIG_ARCH_MX51
250	if (cpu_is_mx51()) {
251		void __iomem *usb_base;
252		u32 usbotg_base;
253		u32 usbother_base;
254		int ret = 0;
255
256		usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
257
258		switch (port) {
259		case 0:	/* OTG port */
260			usbotg_base = usb_base + MXC_OTG_OFFSET;
261			break;
262		case 1:	/* Host 1 port */
263			usbotg_base = usb_base + MXC_H1_OFFSET;
264			break;
265		default:
266			printk(KERN_ERR"%s no such port %d\n", __func__, port);
267			ret = -ENOENT;
268			goto error;
269		}
270		usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
271
272		switch (port) {
273		case 0:	/*OTG port */
274			if (flags & MXC_EHCI_INTERNAL_PHY) {
275				v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
276
277				if (flags & MXC_EHCI_POWER_PINS_ENABLED)
278					v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */
279				else
280					v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */
281				__raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
282
283				v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
284				if (flags & MXC_EHCI_WAKEUP_ENABLED)
285					v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
286				else
287					v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
288				__raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
289			}
290			break;
291		case 1:	/* Host 1 */
292			/*Host ULPI */
293			v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
294			if (flags & MXC_EHCI_WAKEUP_ENABLED)
295				v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
296			else
297				v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
298
299			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
300				v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
301			else
302				v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
303			__raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
304
305			v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
306			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
307				v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
308			else
309				v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
310			__raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
311
312			v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
313			if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
314				/* Interrupt Threshold Control:Immediate (no threshold) */
315				v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
316			__raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
317			break;
318		}
319
320error:
321		iounmap(usb_base);
322		return ret;
323	}
324#endif
325	printk(KERN_WARNING
326		"%s() unable to setup USBCONTROL for this CPU\n", __func__);
327	return -EINVAL;
328}
329EXPORT_SYMBOL(mxc_initialize_usb_hw);
330