xref: /rk3399_rockchip-uboot/drivers/usb/host/ehci-mxc.c (revision 5b591502f9fc340df8fb1e3bec918009ba3bc313)
1*5b591502SStefano Babic /*
2*5b591502SStefano Babic  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
3*5b591502SStefano Babic  *
4*5b591502SStefano Babic  * This program is free software; you can redistribute it and/or modify it
5*5b591502SStefano Babic  * under the terms of the GNU General Public License as published by the
6*5b591502SStefano Babic  * Free Software Foundation; either version 2 of the License, or (at your
7*5b591502SStefano Babic  * option) any later version.
8*5b591502SStefano Babic  *
9*5b591502SStefano Babic  * This program is distributed in the hope that it will be useful, but
10*5b591502SStefano Babic  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11*5b591502SStefano Babic  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12*5b591502SStefano Babic  * for more details.
13*5b591502SStefano Babic  *
14*5b591502SStefano Babic  * You should have received a copy of the GNU General Public License
15*5b591502SStefano Babic  * along with this program; if not, write to the Free Software Foundation,
16*5b591502SStefano Babic  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17*5b591502SStefano Babic  */
18*5b591502SStefano Babic 
19*5b591502SStefano Babic 
20*5b591502SStefano Babic #include <common.h>
21*5b591502SStefano Babic #include <usb.h>
22*5b591502SStefano Babic #include <asm/io.h>
23*5b591502SStefano Babic #include <asm/arch/mx31-regs.h>
24*5b591502SStefano Babic #include <usb/ehci-fsl.h>
25*5b591502SStefano Babic #include <errno.h>
26*5b591502SStefano Babic 
27*5b591502SStefano Babic #include "ehci.h"
28*5b591502SStefano Babic #include "ehci-core.h"
29*5b591502SStefano Babic 
30*5b591502SStefano Babic #define USBCTRL_OTGBASE_OFFSET	0x600
31*5b591502SStefano Babic 
32*5b591502SStefano Babic #define MX31_OTG_SIC_SHIFT	29
33*5b591502SStefano Babic #define MX31_OTG_SIC_MASK	(0x3 << MX31_OTG_SIC_SHIFT)
34*5b591502SStefano Babic #define MX31_OTG_PM_BIT		(1 << 24)
35*5b591502SStefano Babic 
36*5b591502SStefano Babic #define MX31_H2_SIC_SHIFT	21
37*5b591502SStefano Babic #define MX31_H2_SIC_MASK	(0x3 << MX31_H2_SIC_SHIFT)
38*5b591502SStefano Babic #define MX31_H2_PM_BIT		(1 << 16)
39*5b591502SStefano Babic #define MX31_H2_DT_BIT		(1 << 5)
40*5b591502SStefano Babic 
41*5b591502SStefano Babic #define MX31_H1_SIC_SHIFT	13
42*5b591502SStefano Babic #define MX31_H1_SIC_MASK	(0x3 << MX31_H1_SIC_SHIFT)
43*5b591502SStefano Babic #define MX31_H1_PM_BIT		(1 << 8)
44*5b591502SStefano Babic #define MX31_H1_DT_BIT		(1 << 4)
45*5b591502SStefano Babic 
46*5b591502SStefano Babic static int mxc_set_usbcontrol(int port, unsigned int flags)
47*5b591502SStefano Babic {
48*5b591502SStefano Babic 	unsigned int v;
49*5b591502SStefano Babic #ifdef CONFIG_MX31
50*5b591502SStefano Babic 		v = readl(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET);
51*5b591502SStefano Babic 
52*5b591502SStefano Babic 		switch (port) {
53*5b591502SStefano Babic 		case 0:	/* OTG port */
54*5b591502SStefano Babic 			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
55*5b591502SStefano Babic 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
56*5b591502SStefano Babic 					<< MX31_OTG_SIC_SHIFT;
57*5b591502SStefano Babic 			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
58*5b591502SStefano Babic 				v |= MX31_OTG_PM_BIT;
59*5b591502SStefano Babic 
60*5b591502SStefano Babic 			break;
61*5b591502SStefano Babic 		case 1: /* H1 port */
62*5b591502SStefano Babic 			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT |
63*5b591502SStefano Babic 				MX31_H1_DT_BIT);
64*5b591502SStefano Babic 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
65*5b591502SStefano Babic 						<< MX31_H1_SIC_SHIFT;
66*5b591502SStefano Babic 			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
67*5b591502SStefano Babic 				v |= MX31_H1_PM_BIT;
68*5b591502SStefano Babic 
69*5b591502SStefano Babic 			if (!(flags & MXC_EHCI_TTL_ENABLED))
70*5b591502SStefano Babic 				v |= MX31_H1_DT_BIT;
71*5b591502SStefano Babic 
72*5b591502SStefano Babic 			break;
73*5b591502SStefano Babic 		case 2:	/* H2 port */
74*5b591502SStefano Babic 			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT |
75*5b591502SStefano Babic 				MX31_H2_DT_BIT);
76*5b591502SStefano Babic 			v |= (flags & MXC_EHCI_INTERFACE_MASK)
77*5b591502SStefano Babic 						<< MX31_H2_SIC_SHIFT;
78*5b591502SStefano Babic 			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
79*5b591502SStefano Babic 				v |= MX31_H2_PM_BIT;
80*5b591502SStefano Babic 
81*5b591502SStefano Babic 			if (!(flags & MXC_EHCI_TTL_ENABLED))
82*5b591502SStefano Babic 				v |= MX31_H2_DT_BIT;
83*5b591502SStefano Babic 
84*5b591502SStefano Babic 			break;
85*5b591502SStefano Babic 		default:
86*5b591502SStefano Babic 			return -EINVAL;
87*5b591502SStefano Babic 		}
88*5b591502SStefano Babic 
89*5b591502SStefano Babic 		writel(v, MX31_OTG_BASE_ADDR +
90*5b591502SStefano Babic 				     USBCTRL_OTGBASE_OFFSET);
91*5b591502SStefano Babic #endif
92*5b591502SStefano Babic 		return 0;
93*5b591502SStefano Babic }
94*5b591502SStefano Babic 
95*5b591502SStefano Babic int ehci_hcd_init(void)
96*5b591502SStefano Babic {
97*5b591502SStefano Babic 	u32 tmp;
98*5b591502SStefano Babic 	struct usb_ehci *ehci;
99*5b591502SStefano Babic 	struct clock_control_regs *sc_regs =
100*5b591502SStefano Babic 		(struct clock_control_regs *)CCM_BASE;
101*5b591502SStefano Babic 
102*5b591502SStefano Babic 	tmp = __raw_readl(&sc_regs->ccmr);
103*5b591502SStefano Babic 	__raw_writel(__raw_readl(&sc_regs->ccmr) | (1 << 9), &sc_regs->ccmr) ;
104*5b591502SStefano Babic 
105*5b591502SStefano Babic 	udelay(80);
106*5b591502SStefano Babic 
107*5b591502SStefano Babic 	/* Take USB2 */
108*5b591502SStefano Babic 	ehci = (struct usb_ehci *)(MX31_OTG_BASE_ADDR +
109*5b591502SStefano Babic 		(0x200 * CONFIG_MXC_USB_PORT));
110*5b591502SStefano Babic 	hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
111*5b591502SStefano Babic 	hcor = (struct ehci_hcor *)((uint32_t) hccr +
112*5b591502SStefano Babic 			HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
113*5b591502SStefano Babic 	setbits_le32(&ehci->usbmode, CM_HOST);
114*5b591502SStefano Babic 	setbits_le32(&ehci->control, USB_EN);
115*5b591502SStefano Babic 
116*5b591502SStefano Babic 	__raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
117*5b591502SStefano Babic 
118*5b591502SStefano Babic 	mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS);
119*5b591502SStefano Babic 
120*5b591502SStefano Babic 	return 0;
121*5b591502SStefano Babic }
122*5b591502SStefano Babic 
123*5b591502SStefano Babic /*
124*5b591502SStefano Babic  * Destroy the appropriate control structures corresponding
125*5b591502SStefano Babic  * the the EHCI host controller.
126*5b591502SStefano Babic  */
127*5b591502SStefano Babic int ehci_hcd_stop(void)
128*5b591502SStefano Babic {
129*5b591502SStefano Babic 	return 0;
130*5b591502SStefano Babic }
131