PageRenderTime 47ms CodeModel.GetById 13ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

/Ethereal-msm8939-beta9/arch/mips/alchemy/common/usb.c

https://bitbucket.org/MilosStamenkovic95/etherealos
C | 614 lines | 498 code | 79 blank | 37 comment | 43 complexity | 43b430b28ffc629a20433e72f9e0bc90 MD5 | raw file
  1/*
  2 * USB block power/access management abstraction.
  3 *
  4 * Au1000+: The OHCI block control register is at the far end of the OHCI memory
  5 *	    area. Au1550 has OHCI on different base address. No need to handle
  6 *	    UDC here.
  7 * Au1200:  one register to control access and clocks to O/EHCI, UDC and OTG
  8 *	    as well as the PHY for EHCI and UDC.
  9 *
 10 */
 11
 12#include <linux/init.h>
 13#include <linux/io.h>
 14#include <linux/module.h>
 15#include <linux/spinlock.h>
 16#include <linux/syscore_ops.h>
 17#include <asm/mach-au1x00/au1000.h>
 18
 19/* control register offsets */
 20#define AU1000_OHCICFG	0x7fffc
 21#define AU1550_OHCICFG	0x07ffc
 22#define AU1200_USBCFG	0x04
 23
 24/* Au1000 USB block config bits */
 25#define USBHEN_RD	(1 << 4)		/* OHCI reset-done indicator */
 26#define USBHEN_CE	(1 << 3)		/* OHCI block clock enable */
 27#define USBHEN_E	(1 << 2)		/* OHCI block enable */
 28#define USBHEN_C	(1 << 1)		/* OHCI block coherency bit */
 29#define USBHEN_BE	(1 << 0)		/* OHCI Big-Endian */
 30
 31/* Au1200 USB config bits */
 32#define USBCFG_PFEN	(1 << 31)		/* prefetch enable (undoc) */
 33#define USBCFG_RDCOMB	(1 << 30)		/* read combining (undoc) */
 34#define USBCFG_UNKNOWN	(5 << 20)		/* unknown, leave this way */
 35#define USBCFG_SSD	(1 << 23)		/* serial short detect en */
 36#define USBCFG_PPE	(1 << 19)		/* HS PHY PLL */
 37#define USBCFG_UCE	(1 << 18)		/* UDC clock enable */
 38#define USBCFG_ECE	(1 << 17)		/* EHCI clock enable */
 39#define USBCFG_OCE	(1 << 16)		/* OHCI clock enable */
 40#define USBCFG_FLA(x)	(((x) & 0x3f) << 8)
 41#define USBCFG_UCAM	(1 << 7)		/* coherent access (undoc) */
 42#define USBCFG_GME	(1 << 6)		/* OTG mem access */
 43#define USBCFG_DBE	(1 << 5)		/* UDC busmaster enable */
 44#define USBCFG_DME	(1 << 4)		/* UDC mem enable */
 45#define USBCFG_EBE	(1 << 3)		/* EHCI busmaster enable */
 46#define USBCFG_EME	(1 << 2)		/* EHCI mem enable */
 47#define USBCFG_OBE	(1 << 1)		/* OHCI busmaster enable */
 48#define USBCFG_OME	(1 << 0)		/* OHCI mem enable */
 49#define USBCFG_INIT_AU1200	(USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
 50				 USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
 51				 USBCFG_GME | USBCFG_DBE | USBCFG_DME |	       \
 52				 USBCFG_EBE | USBCFG_EME | USBCFG_OBE |	       \
 53				 USBCFG_OME)
 54
 55/* Au1300 USB config registers */
 56#define USB_DWC_CTRL1		0x00
 57#define USB_DWC_CTRL2		0x04
 58#define USB_VBUS_TIMER		0x10
 59#define USB_SBUS_CTRL		0x14
 60#define USB_MSR_ERR		0x18
 61#define USB_DWC_CTRL3		0x1C
 62#define USB_DWC_CTRL4		0x20
 63#define USB_OTG_STATUS		0x28
 64#define USB_DWC_CTRL5		0x2C
 65#define USB_DWC_CTRL6		0x30
 66#define USB_DWC_CTRL7		0x34
 67#define USB_PHY_STATUS		0xC0
 68#define USB_INT_STATUS		0xC4
 69#define USB_INT_ENABLE		0xC8
 70
 71#define USB_DWC_CTRL1_OTGD	0x04 /* set to DISable OTG */
 72#define USB_DWC_CTRL1_HSTRS	0x02 /* set to ENable EHCI */
 73#define USB_DWC_CTRL1_DCRS	0x01 /* set to ENable UDC */
 74
 75#define USB_DWC_CTRL2_PHY1RS	0x04 /* set to enable PHY1 */
 76#define USB_DWC_CTRL2_PHY0RS	0x02 /* set to enable PHY0 */
 77#define USB_DWC_CTRL2_PHYRS	0x01 /* set to enable PHY */
 78
 79#define USB_DWC_CTRL3_OHCI1_CKEN	(1 << 19)
 80#define USB_DWC_CTRL3_OHCI0_CKEN	(1 << 18)
 81#define USB_DWC_CTRL3_EHCI0_CKEN	(1 << 17)
 82#define USB_DWC_CTRL3_OTG0_CKEN		(1 << 16)
 83
 84#define USB_SBUS_CTRL_SBCA		0x04 /* coherent access */
 85
 86#define USB_INTEN_FORCE			0x20
 87#define USB_INTEN_PHY			0x10
 88#define USB_INTEN_UDC			0x08
 89#define USB_INTEN_EHCI			0x04
 90#define USB_INTEN_OHCI1			0x02
 91#define USB_INTEN_OHCI0			0x01
 92
 93static DEFINE_SPINLOCK(alchemy_usb_lock);
 94
 95static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
 96{
 97	unsigned long r, s;
 98
 99	r = __raw_readl(base + USB_DWC_CTRL2);
100	s = __raw_readl(base + USB_DWC_CTRL3);
101
102	s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
103		USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
104
105	if (enable) {
106		/* simply enable all PHYs */
107		r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
108		     USB_DWC_CTRL2_PHYRS;
109		__raw_writel(r, base + USB_DWC_CTRL2);
110		wmb();
111	} else if (!s) {
112		/* no USB block active, do disable all PHYs */
113		r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
114		       USB_DWC_CTRL2_PHYRS);
115		__raw_writel(r, base + USB_DWC_CTRL2);
116		wmb();
117	}
118}
119
120static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
121{
122	unsigned long r;
123
124	if (enable) {
125		__raw_writel(1, base + USB_DWC_CTRL7);	/* start OHCI clock */
126		wmb();
127
128		r = __raw_readl(base + USB_DWC_CTRL3);	/* enable OHCI block */
129		r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
130			       : USB_DWC_CTRL3_OHCI1_CKEN;
131		__raw_writel(r, base + USB_DWC_CTRL3);
132		wmb();
133
134		__au1300_usb_phyctl(base, enable);	/* power up the PHYs */
135
136		r = __raw_readl(base + USB_INT_ENABLE);
137		r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
138		__raw_writel(r, base + USB_INT_ENABLE);
139		wmb();
140
141		/* reset the OHCI start clock bit */
142		__raw_writel(0, base + USB_DWC_CTRL7);
143		wmb();
144	} else {
145		r = __raw_readl(base + USB_INT_ENABLE);
146		r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
147		__raw_writel(r, base + USB_INT_ENABLE);
148		wmb();
149
150		r = __raw_readl(base + USB_DWC_CTRL3);
151		r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
152				 : USB_DWC_CTRL3_OHCI1_CKEN);
153		__raw_writel(r, base + USB_DWC_CTRL3);
154		wmb();
155
156		__au1300_usb_phyctl(base, enable);
157	}
158}
159
160static inline void __au1300_ehci_control(void __iomem *base, int enable)
161{
162	unsigned long r;
163
164	if (enable) {
165		r = __raw_readl(base + USB_DWC_CTRL3);
166		r |= USB_DWC_CTRL3_EHCI0_CKEN;
167		__raw_writel(r, base + USB_DWC_CTRL3);
168		wmb();
169
170		r = __raw_readl(base + USB_DWC_CTRL1);
171		r |= USB_DWC_CTRL1_HSTRS;
172		__raw_writel(r, base + USB_DWC_CTRL1);
173		wmb();
174
175		__au1300_usb_phyctl(base, enable);
176
177		r = __raw_readl(base + USB_INT_ENABLE);
178		r |= USB_INTEN_EHCI;
179		__raw_writel(r, base + USB_INT_ENABLE);
180		wmb();
181	} else {
182		r = __raw_readl(base + USB_INT_ENABLE);
183		r &= ~USB_INTEN_EHCI;
184		__raw_writel(r, base + USB_INT_ENABLE);
185		wmb();
186
187		r = __raw_readl(base + USB_DWC_CTRL1);
188		r &= ~USB_DWC_CTRL1_HSTRS;
189		__raw_writel(r, base + USB_DWC_CTRL1);
190		wmb();
191
192		r = __raw_readl(base + USB_DWC_CTRL3);
193		r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
194		__raw_writel(r, base + USB_DWC_CTRL3);
195		wmb();
196
197		__au1300_usb_phyctl(base, enable);
198	}
199}
200
201static inline void __au1300_udc_control(void __iomem *base, int enable)
202{
203	unsigned long r;
204
205	if (enable) {
206		r = __raw_readl(base + USB_DWC_CTRL1);
207		r |= USB_DWC_CTRL1_DCRS;
208		__raw_writel(r, base + USB_DWC_CTRL1);
209		wmb();
210
211		__au1300_usb_phyctl(base, enable);
212
213		r = __raw_readl(base + USB_INT_ENABLE);
214		r |= USB_INTEN_UDC;
215		__raw_writel(r, base + USB_INT_ENABLE);
216		wmb();
217	} else {
218		r = __raw_readl(base + USB_INT_ENABLE);
219		r &= ~USB_INTEN_UDC;
220		__raw_writel(r, base + USB_INT_ENABLE);
221		wmb();
222
223		r = __raw_readl(base + USB_DWC_CTRL1);
224		r &= ~USB_DWC_CTRL1_DCRS;
225		__raw_writel(r, base + USB_DWC_CTRL1);
226		wmb();
227
228		__au1300_usb_phyctl(base, enable);
229	}
230}
231
232static inline void __au1300_otg_control(void __iomem *base, int enable)
233{
234	unsigned long r;
235	if (enable) {
236		r = __raw_readl(base + USB_DWC_CTRL3);
237		r |= USB_DWC_CTRL3_OTG0_CKEN;
238		__raw_writel(r, base + USB_DWC_CTRL3);
239		wmb();
240
241		r = __raw_readl(base + USB_DWC_CTRL1);
242		r &= ~USB_DWC_CTRL1_OTGD;
243		__raw_writel(r, base + USB_DWC_CTRL1);
244		wmb();
245
246		__au1300_usb_phyctl(base, enable);
247	} else {
248		r = __raw_readl(base + USB_DWC_CTRL1);
249		r |= USB_DWC_CTRL1_OTGD;
250		__raw_writel(r, base + USB_DWC_CTRL1);
251		wmb();
252
253		r = __raw_readl(base + USB_DWC_CTRL3);
254		r &= ~USB_DWC_CTRL3_OTG0_CKEN;
255		__raw_writel(r, base + USB_DWC_CTRL3);
256		wmb();
257
258		__au1300_usb_phyctl(base, enable);
259	}
260}
261
262static inline int au1300_usb_control(int block, int enable)
263{
264	void __iomem *base =
265		(void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
266	int ret = 0;
267
268	switch (block) {
269	case ALCHEMY_USB_OHCI0:
270		__au1300_ohci_control(base, enable, 0);
271		break;
272	case ALCHEMY_USB_OHCI1:
273		__au1300_ohci_control(base, enable, 1);
274		break;
275	case ALCHEMY_USB_EHCI0:
276		__au1300_ehci_control(base, enable);
277		break;
278	case ALCHEMY_USB_UDC0:
279		__au1300_udc_control(base, enable);
280		break;
281	case ALCHEMY_USB_OTG0:
282		__au1300_otg_control(base, enable);
283		break;
284	default:
285		ret = -ENODEV;
286	}
287	return ret;
288}
289
290static inline void au1300_usb_init(void)
291{
292	void __iomem *base =
293		(void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
294
295	/* set some sane defaults.  Note: we don't fiddle with DWC_CTRL4
296	 * here at all: Port 2 routing (EHCI or UDC) must be set either
297	 * by boot firmware or platform init code; I can't autodetect
298	 * a sane setting.
299	 */
300	__raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
301	wmb();
302	__raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
303	wmb();
304	__raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
305	wmb();
306	__raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
307	wmb();
308	/* set coherent access bit */
309	__raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
310	wmb();
311}
312
313static inline void __au1200_ohci_control(void __iomem *base, int enable)
314{
315	unsigned long r = __raw_readl(base + AU1200_USBCFG);
316	if (enable) {
317		__raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
318		wmb();
319		udelay(2000);
320	} else {
321		__raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
322		wmb();
323		udelay(1000);
324	}
325}
326
327static inline void __au1200_ehci_control(void __iomem *base, int enable)
328{
329	unsigned long r = __raw_readl(base + AU1200_USBCFG);
330	if (enable) {
331		__raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
332		wmb();
333		udelay(1000);
334	} else {
335		if (!(r & USBCFG_UCE))		/* UDC also off? */
336			r &= ~USBCFG_PPE;	/* yes: disable HS PHY PLL */
337		__raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
338		wmb();
339		udelay(1000);
340	}
341}
342
343static inline void __au1200_udc_control(void __iomem *base, int enable)
344{
345	unsigned long r = __raw_readl(base + AU1200_USBCFG);
346	if (enable) {
347		__raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
348		wmb();
349	} else {
350		if (!(r & USBCFG_ECE))		/* EHCI also off? */
351			r &= ~USBCFG_PPE;	/* yes: disable HS PHY PLL */
352		__raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
353		wmb();
354	}
355}
356
357static inline int au1200_coherency_bug(void)
358{
359#if defined(CONFIG_DMA_COHERENT)
360	/* Au1200 AB USB does not support coherent memory */
361	if (!(read_c0_prid() & 0xff)) {
362		printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
363		printk(KERN_INFO "Au1200 USB: update your board or re-configure"
364				 " the kernel\n");
365		return -ENODEV;
366	}
367#endif
368	return 0;
369}
370
371static inline int au1200_usb_control(int block, int enable)
372{
373	void __iomem *base =
374			(void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
375	int ret = 0;
376
377	switch (block) {
378	case ALCHEMY_USB_OHCI0:
379		ret = au1200_coherency_bug();
380		if (ret && enable)
381			goto out;
382		__au1200_ohci_control(base, enable);
383		break;
384	case ALCHEMY_USB_UDC0:
385		__au1200_udc_control(base, enable);
386		break;
387	case ALCHEMY_USB_EHCI0:
388		ret = au1200_coherency_bug();
389		if (ret && enable)
390			goto out;
391		__au1200_ehci_control(base, enable);
392		break;
393	default:
394		ret = -ENODEV;
395	}
396out:
397	return ret;
398}
399
400
401/* initialize USB block(s) to a known working state */
402static inline void au1200_usb_init(void)
403{
404	void __iomem *base =
405			(void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
406	__raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
407	wmb();
408	udelay(1000);
409}
410
411static inline void au1000_usb_init(unsigned long rb, int reg)
412{
413	void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
414	unsigned long r = __raw_readl(base);
415
416#if defined(__BIG_ENDIAN)
417	r |= USBHEN_BE;
418#endif
419	r |= USBHEN_C;
420
421	__raw_writel(r, base);
422	wmb();
423	udelay(1000);
424}
425
426
427static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
428{
429	void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
430	unsigned long r = __raw_readl(base + creg);
431
432	if (enable) {
433		__raw_writel(r | USBHEN_CE, base + creg);
434		wmb();
435		udelay(1000);
436		__raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
437		wmb();
438		udelay(1000);
439
440		/* wait for reset complete (read reg twice: au1500 erratum) */
441		while (__raw_readl(base + creg),
442			!(__raw_readl(base + creg) & USBHEN_RD))
443			udelay(1000);
444	} else {
445		__raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
446		wmb();
447	}
448}
449
450static inline int au1000_usb_control(int block, int enable, unsigned long rb,
451				     int creg)
452{
453	int ret = 0;
454
455	switch (block) {
456	case ALCHEMY_USB_OHCI0:
457		__au1xx0_ohci_control(enable, rb, creg);
458		break;
459	default:
460		ret = -ENODEV;
461	}
462	return ret;
463}
464
465/*
466 * alchemy_usb_control - control Alchemy on-chip USB blocks
467 * @block:	USB block to target
468 * @enable:	set 1 to enable a block, 0 to disable
469 */
470int alchemy_usb_control(int block, int enable)
471{
472	unsigned long flags;
473	int ret;
474
475	spin_lock_irqsave(&alchemy_usb_lock, flags);
476	switch (alchemy_get_cputype()) {
477	case ALCHEMY_CPU_AU1000:
478	case ALCHEMY_CPU_AU1500:
479	case ALCHEMY_CPU_AU1100:
480		ret = au1000_usb_control(block, enable,
481				AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
482		break;
483	case ALCHEMY_CPU_AU1550:
484		ret = au1000_usb_control(block, enable,
485				AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
486		break;
487	case ALCHEMY_CPU_AU1200:
488		ret = au1200_usb_control(block, enable);
489		break;
490	case ALCHEMY_CPU_AU1300:
491		ret = au1300_usb_control(block, enable);
492		break;
493	default:
494		ret = -ENODEV;
495	}
496	spin_unlock_irqrestore(&alchemy_usb_lock, flags);
497	return ret;
498}
499EXPORT_SYMBOL_GPL(alchemy_usb_control);
500
501
502static unsigned long alchemy_usb_pmdata[2];
503
504static void au1000_usb_pm(unsigned long br, int creg, int susp)
505{
506	void __iomem *base = (void __iomem *)KSEG1ADDR(br);
507
508	if (susp) {
509		alchemy_usb_pmdata[0] = __raw_readl(base + creg);
510		/* There appears to be some undocumented reset register.... */
511		__raw_writel(0, base + 0x04);
512		wmb();
513		__raw_writel(0, base + creg);
514		wmb();
515	} else {
516		__raw_writel(alchemy_usb_pmdata[0], base + creg);
517		wmb();
518	}
519}
520
521static void au1200_usb_pm(int susp)
522{
523	void __iomem *base =
524			(void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
525	if (susp) {
526		/* save OTG_CAP/MUX registers which indicate port routing */
527		/* FIXME: write an OTG driver to do that */
528		alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
529		alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
530	} else {
531		/* restore access to all MMIO areas */
532		au1200_usb_init();
533
534		/* restore OTG_CAP/MUX registers */
535		__raw_writel(alchemy_usb_pmdata[0], base + 0x00);
536		__raw_writel(alchemy_usb_pmdata[1], base + 0x04);
537		wmb();
538	}
539}
540
541static void au1300_usb_pm(int susp)
542{
543	void __iomem *base =
544			(void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
545	/* remember Port2 routing */
546	if (susp) {
547		alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
548	} else {
549		au1300_usb_init();
550		__raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
551		wmb();
552	}
553}
554
555static void alchemy_usb_pm(int susp)
556{
557	switch (alchemy_get_cputype()) {
558	case ALCHEMY_CPU_AU1000:
559	case ALCHEMY_CPU_AU1500:
560	case ALCHEMY_CPU_AU1100:
561		au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
562		break;
563	case ALCHEMY_CPU_AU1550:
564		au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
565		break;
566	case ALCHEMY_CPU_AU1200:
567		au1200_usb_pm(susp);
568		break;
569	case ALCHEMY_CPU_AU1300:
570		au1300_usb_pm(susp);
571		break;
572	}
573}
574
575static int alchemy_usb_suspend(void)
576{
577	alchemy_usb_pm(1);
578	return 0;
579}
580
581static void alchemy_usb_resume(void)
582{
583	alchemy_usb_pm(0);
584}
585
586static struct syscore_ops alchemy_usb_pm_ops = {
587	.suspend	= alchemy_usb_suspend,
588	.resume		= alchemy_usb_resume,
589};
590
591static int __init alchemy_usb_init(void)
592{
593	switch (alchemy_get_cputype()) {
594	case ALCHEMY_CPU_AU1000:
595	case ALCHEMY_CPU_AU1500:
596	case ALCHEMY_CPU_AU1100:
597		au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
598		break;
599	case ALCHEMY_CPU_AU1550:
600		au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
601		break;
602	case ALCHEMY_CPU_AU1200:
603		au1200_usb_init();
604		break;
605	case ALCHEMY_CPU_AU1300:
606		au1300_usb_init();
607		break;
608	}
609
610	register_syscore_ops(&alchemy_usb_pm_ops);
611
612	return 0;
613}
614arch_initcall(alchemy_usb_init);