Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
powerpc
platforms
83xx
usb.c
Go to the documentation of this file.
1
/*
2
* Freescale 83xx USB SOC setup code
3
*
4
* Copyright (C) 2007 Freescale Semiconductor, Inc.
5
* Author: Li Yang
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation; either version 2 of the License, or (at your
10
* option) any later version.
11
*/
12
13
14
#include <linux/stddef.h>
15
#include <linux/kernel.h>
16
#include <linux/errno.h>
17
#include <
linux/of.h
>
18
19
#include <asm/io.h>
20
#include <asm/prom.h>
21
#include <
sysdev/fsl_soc.h
>
22
23
#include "
mpc83xx.h
"
24
25
26
#ifdef CONFIG_PPC_MPC834x
27
int
mpc834x_usb_cfg
(
void
)
28
{
29
unsigned
long
sccr, sicrl, sicrh;
30
void
__iomem
*immap;
31
struct
device_node
*np =
NULL
;
32
int
port0_is_dr = 0, port1_is_dr = 0;
33
const
void
*prop, *dr_mode;
34
35
immap =
ioremap
(
get_immrbase
(), 0x1000);
36
if
(!immap)
37
return
-
ENOMEM
;
38
39
/* Read registers */
40
/* Note: DR and MPH must use the same clock setting in SCCR */
41
sccr =
in_be32
(immap +
MPC83XX_SCCR_OFFS
) & ~
MPC83XX_SCCR_USB_MASK
;
42
sicrl =
in_be32
(immap +
MPC83XX_SICRL_OFFS
) & ~
MPC834X_SICRL_USB_MASK
;
43
sicrh =
in_be32
(immap +
MPC83XX_SICRH_OFFS
) & ~
MPC834X_SICRH_USB_UTMI
;
44
45
np =
of_find_compatible_node
(
NULL
,
NULL
,
"fsl-usb2-dr"
);
46
if
(np) {
47
sccr |=
MPC83XX_SCCR_USB_DRCM_11
;
/* 1:3 */
48
49
prop =
of_get_property
(np,
"phy_type"
,
NULL
);
50
port1_is_dr = 1;
51
if
(prop && (!
strcmp
(prop,
"utmi"
) ||
52
!
strcmp
(prop,
"utmi_wide"
))) {
53
sicrl |=
MPC834X_SICRL_USB0
|
MPC834X_SICRL_USB1
;
54
sicrh |=
MPC834X_SICRH_USB_UTMI
;
55
port0_is_dr = 1;
56
}
else
if
(prop && !
strcmp
(prop,
"serial"
)) {
57
dr_mode =
of_get_property
(np,
"dr_mode"
,
NULL
);
58
if
(dr_mode && !
strcmp
(dr_mode,
"otg"
)) {
59
sicrl |=
MPC834X_SICRL_USB0
|
MPC834X_SICRL_USB1
;
60
port0_is_dr = 1;
61
}
else
{
62
sicrl |=
MPC834X_SICRL_USB1
;
63
}
64
}
else
if
(prop && !
strcmp
(prop,
"ulpi"
)) {
65
sicrl |=
MPC834X_SICRL_USB1
;
66
}
else
{
67
printk
(
KERN_WARNING
"834x USB PHY type not supported\n"
);
68
}
69
of_node_put(np);
70
}
71
np =
of_find_compatible_node
(
NULL
,
NULL
,
"fsl-usb2-mph"
);
72
if
(np) {
73
sccr |=
MPC83XX_SCCR_USB_MPHCM_11
;
/* 1:3 */
74
75
prop =
of_get_property
(np,
"port0"
,
NULL
);
76
if
(prop) {
77
if
(port0_is_dr)
78
printk
(
KERN_WARNING
79
"834x USB port0 can't be used by both DR and MPH!\n"
);
80
sicrl &= ~
MPC834X_SICRL_USB0
;
81
}
82
prop =
of_get_property
(np,
"port1"
,
NULL
);
83
if
(prop) {
84
if
(port1_is_dr)
85
printk
(
KERN_WARNING
86
"834x USB port1 can't be used by both DR and MPH!\n"
);
87
sicrl &= ~
MPC834X_SICRL_USB1
;
88
}
89
of_node_put(np);
90
}
91
92
/* Write back */
93
out_be32
(immap +
MPC83XX_SCCR_OFFS
, sccr);
94
out_be32
(immap +
MPC83XX_SICRL_OFFS
, sicrl);
95
out_be32
(immap +
MPC83XX_SICRH_OFFS
, sicrh);
96
97
iounmap
(immap);
98
return
0;
99
}
100
#endif
/* CONFIG_PPC_MPC834x */
101
102
#ifdef CONFIG_PPC_MPC831x
103
int
mpc831x_usb_cfg
(
void
)
104
{
105
u32
temp
;
106
void
__iomem
*immap, *usb_regs;
107
struct
device_node
*np =
NULL
;
108
struct
device_node
*immr_node =
NULL
;
109
const
void
*prop;
110
struct
resource
res
;
111
int
ret
= 0;
112
#ifdef CONFIG_USB_OTG
113
const
void
*dr_mode;
114
#endif
115
116
np =
of_find_compatible_node
(
NULL
,
NULL
,
"fsl-usb2-dr"
);
117
if
(!np)
118
return
-
ENODEV
;
119
prop =
of_get_property
(np,
"phy_type"
,
NULL
);
120
121
/* Map IMMR space for pin and clock settings */
122
immap =
ioremap
(
get_immrbase
(), 0x1000);
123
if
(!immap) {
124
of_node_put(np);
125
return
-
ENOMEM
;
126
}
127
128
/* Configure clock */
129
immr_node =
of_get_parent
(np);
130
if
(immr_node && (
of_device_is_compatible
(immr_node,
"fsl,mpc8315-immr"
) ||
131
of_device_is_compatible
(immr_node,
"fsl,mpc8308-immr"
)))
132
clrsetbits_be32(immap +
MPC83XX_SCCR_OFFS
,
133
MPC8315_SCCR_USB_MASK
,
134
MPC8315_SCCR_USB_DRCM_01
);
135
else
136
clrsetbits_be32(immap +
MPC83XX_SCCR_OFFS
,
137
MPC83XX_SCCR_USB_MASK
,
138
MPC83XX_SCCR_USB_DRCM_11
);
139
140
/* Configure pin mux for ULPI. There is no pin mux for UTMI */
141
if
(prop && !
strcmp
(prop,
"ulpi"
)) {
142
if
(
of_device_is_compatible
(immr_node,
"fsl,mpc8308-immr"
)) {
143
clrsetbits_be32(immap +
MPC83XX_SICRH_OFFS
,
144
MPC8308_SICRH_USB_MASK
,
145
MPC8308_SICRH_USB_ULPI
);
146
}
else
if
(
of_device_is_compatible
(immr_node,
"fsl,mpc8315-immr"
)) {
147
clrsetbits_be32(immap +
MPC83XX_SICRL_OFFS
,
148
MPC8315_SICRL_USB_MASK
,
149
MPC8315_SICRL_USB_ULPI
);
150
clrsetbits_be32(immap +
MPC83XX_SICRH_OFFS
,
151
MPC8315_SICRH_USB_MASK
,
152
MPC8315_SICRH_USB_ULPI
);
153
}
else
{
154
clrsetbits_be32(immap +
MPC83XX_SICRL_OFFS
,
155
MPC831X_SICRL_USB_MASK
,
156
MPC831X_SICRL_USB_ULPI
);
157
clrsetbits_be32(immap +
MPC83XX_SICRH_OFFS
,
158
MPC831X_SICRH_USB_MASK
,
159
MPC831X_SICRH_USB_ULPI
);
160
}
161
}
162
163
iounmap
(immap);
164
165
if
(immr_node)
166
of_node_put(immr_node);
167
168
/* Map USB SOC space */
169
ret =
of_address_to_resource
(np, 0, &
res
);
170
if
(ret) {
171
of_node_put(np);
172
return
ret
;
173
}
174
usb_regs =
ioremap
(
res
.start, resource_size(&
res
));
175
176
/* Using on-chip PHY */
177
if
(prop && (!
strcmp
(prop,
"utmi_wide"
) ||
178
!
strcmp
(prop,
"utmi"
))) {
179
u32
refsel;
180
181
if
(
of_device_is_compatible
(immr_node,
"fsl,mpc8308-immr"
))
182
goto
out
;
183
184
if
(
of_device_is_compatible
(immr_node,
"fsl,mpc8315-immr"
))
185
refsel =
CONTROL_REFSEL_24MHZ
;
186
else
187
refsel =
CONTROL_REFSEL_48MHZ
;
188
/* Set UTMI_PHY_EN and REFSEL */
189
out_be32
(usb_regs +
FSL_USB2_CONTROL_OFFS
,
190
CONTROL_UTMI_PHY_EN
| refsel);
191
/* Using external UPLI PHY */
192
}
else
if
(prop && !
strcmp
(prop,
"ulpi"
)) {
193
/* Set PHY_CLK_SEL to ULPI */
194
temp =
CONTROL_PHY_CLK_SEL_ULPI
;
195
#ifdef CONFIG_USB_OTG
196
/* Set OTG_PORT */
197
if
(!
of_device_is_compatible
(immr_node,
"fsl,mpc8308-immr"
)) {
198
dr_mode =
of_get_property
(np,
"dr_mode"
,
NULL
);
199
if
(dr_mode && !
strcmp
(dr_mode,
"otg"
))
200
temp |=
CONTROL_OTG_PORT
;
201
}
202
#endif
/* CONFIG_USB_OTG */
203
out_be32
(usb_regs +
FSL_USB2_CONTROL_OFFS
, temp);
204
}
else
{
205
printk
(
KERN_WARNING
"831x USB PHY type not supported\n"
);
206
ret = -
EINVAL
;
207
}
208
209
out
:
210
iounmap
(usb_regs);
211
of_node_put(np);
212
return
ret
;
213
}
214
#endif
/* CONFIG_PPC_MPC831x */
215
216
#ifdef CONFIG_PPC_MPC837x
217
int
mpc837x_usb_cfg
(
void
)
218
{
219
void
__iomem
*immap;
220
struct
device_node
*np =
NULL
;
221
const
void
*prop;
222
int
ret = 0;
223
224
np =
of_find_compatible_node
(
NULL
,
NULL
,
"fsl-usb2-dr"
);
225
if
(!np || !
of_device_is_available
(np))
226
return
-
ENODEV
;
227
prop =
of_get_property
(np,
"phy_type"
,
NULL
);
228
229
if
(!prop || (
strcmp
(prop,
"ulpi"
) &&
strcmp
(prop,
"serial"
))) {
230
printk
(
KERN_WARNING
"837x USB PHY type not supported\n"
);
231
of_node_put(np);
232
return
-
EINVAL
;
233
}
234
235
/* Map IMMR space for pin and clock settings */
236
immap =
ioremap
(
get_immrbase
(), 0x1000);
237
if
(!immap) {
238
of_node_put(np);
239
return
-
ENOMEM
;
240
}
241
242
/* Configure clock */
243
clrsetbits_be32(immap +
MPC83XX_SCCR_OFFS
,
MPC837X_SCCR_USB_DRCM_11
,
244
MPC837X_SCCR_USB_DRCM_11
);
245
246
/* Configure pin mux for ULPI/serial */
247
clrsetbits_be32(immap +
MPC83XX_SICRL_OFFS
,
MPC837X_SICRL_USB_MASK
,
248
MPC837X_SICRL_USB_ULPI
);
249
250
iounmap
(immap);
251
of_node_put(np);
252
return
ret
;
253
}
254
#endif
/* CONFIG_PPC_MPC837x */
Generated on Thu Jan 10 2013 12:58:40 for Linux Kernel by
1.8.2