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
arm
mach-omap2
msdi.c
Go to the documentation of this file.
1
/*
2
* MSDI IP block reset
3
*
4
* Copyright (C) 2012 Texas Instruments, Inc.
5
* Paul Walmsley
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* version 2 as published by the Free Software Foundation.
10
*
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
* 02110-1301 USA
20
*
21
* XXX What about pad muxing?
22
*/
23
24
#include <linux/kernel.h>
25
#include <
linux/err.h
>
26
#include <
linux/platform_data/gpio-omap.h
>
27
28
#include <
plat/omap_hwmod.h
>
29
#include <
plat/omap_device.h
>
30
#include <
plat/mmc.h
>
31
32
#include "
common.h
"
33
#include "
control.h
"
34
#include "
mux.h
"
35
36
/*
37
* MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register
38
* from the IP block's base address
39
*/
40
#define MSDI_CON_OFFSET 0x0c
41
42
/* Register bitfields in the CON register */
43
#define MSDI_CON_POW_MASK BIT(11)
44
#define MSDI_CON_CLKD_MASK (0x3f << 0)
45
#define MSDI_CON_CLKD_SHIFT 0
46
47
/* Maximum microseconds to wait for OMAP module to softreset */
48
#define MAX_MODULE_SOFTRESET_WAIT 10000
49
50
/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */
51
#define MSDI_TARGET_RESET_CLKD 0x3ff
52
63
int
omap_msdi_reset
(
struct
omap_hwmod
*oh)
64
{
65
u16
v
= 0;
66
int
c
= 0;
67
68
/* Write to the SOFTRESET bit */
69
omap_hwmod_softreset
(oh);
70
71
/* Enable the MSDI core and internal clock */
72
v |=
MSDI_CON_POW_MASK
;
73
v |=
MSDI_TARGET_RESET_CLKD
<<
MSDI_CON_CLKD_SHIFT
;
74
omap_hwmod_write
(v, oh,
MSDI_CON_OFFSET
);
75
76
/* Poll on RESETDONE bit */
77
omap_test_timeout((
omap_hwmod_read
(oh, oh->
class
->sysc->syss_offs)
78
&
SYSS_RESETDONE_MASK
),
79
MAX_MODULE_SOFTRESET_WAIT
, c);
80
81
if
(c ==
MAX_MODULE_SOFTRESET_WAIT
)
82
pr_warning
(
"%s: %s: softreset failed (waited %d usec)\n"
,
83
__func__, oh->
name
,
MAX_MODULE_SOFTRESET_WAIT
);
84
else
85
pr_debug
(
"%s: %s: softreset in %d usec\n"
, __func__,
86
oh->
name
, c);
87
88
/* Disable the MSDI internal clock */
89
v &= ~
MSDI_CON_CLKD_MASK
;
90
omap_hwmod_write
(v, oh,
MSDI_CON_OFFSET
);
91
92
return
0;
93
}
94
95
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
96
97
static
inline
void
omap242x_mmc_mux(
struct
omap_mmc_platform_data
98
*mmc_controller)
99
{
100
if
((mmc_controller->
slots
[0].switch_pin > 0) && \
101
(mmc_controller->
slots
[0].switch_pin <
OMAP_MAX_GPIO_LINES
))
102
omap_mux_init_gpio(mmc_controller->
slots
[0].switch_pin,
103
OMAP_PIN_INPUT_PULLUP
);
104
if
((mmc_controller->
slots
[0].gpio_wp > 0) && \
105
(mmc_controller->
slots
[0].gpio_wp <
OMAP_MAX_GPIO_LINES
))
106
omap_mux_init_gpio(mmc_controller->
slots
[0].gpio_wp,
107
OMAP_PIN_INPUT_PULLUP
);
108
109
omap_mux_init_signal(
"sdmmc_cmd"
, 0);
110
omap_mux_init_signal(
"sdmmc_clki"
, 0);
111
omap_mux_init_signal(
"sdmmc_clko"
, 0);
112
omap_mux_init_signal(
"sdmmc_dat0"
, 0);
113
omap_mux_init_signal(
"sdmmc_dat_dir0"
, 0);
114
omap_mux_init_signal(
"sdmmc_cmd_dir"
, 0);
115
if
(mmc_controller->
slots
[0].caps &
MMC_CAP_4_BIT_DATA
) {
116
omap_mux_init_signal(
"sdmmc_dat1"
, 0);
117
omap_mux_init_signal(
"sdmmc_dat2"
, 0);
118
omap_mux_init_signal(
"sdmmc_dat3"
, 0);
119
omap_mux_init_signal(
"sdmmc_dat_dir1"
, 0);
120
omap_mux_init_signal(
"sdmmc_dat_dir2"
, 0);
121
omap_mux_init_signal(
"sdmmc_dat_dir3"
, 0);
122
}
123
124
/*
125
* Use internal loop-back in MMC/SDIO Module Input Clock
126
* selection
127
*/
128
if
(mmc_controller->
slots
[0].internal_clock) {
129
u32
v
=
omap_ctrl_readl
(
OMAP2_CONTROL_DEVCONF0
);
130
v |= (1 << 24);
131
omap_ctrl_writel
(v,
OMAP2_CONTROL_DEVCONF0
);
132
}
133
}
134
135
void
__init
omap242x_init_mmc(
struct
omap_mmc_platform_data
**
mmc_data
)
136
{
137
struct
platform_device
*
pdev
;
138
struct
omap_hwmod
*oh;
139
int
id
= 0;
140
char
*oh_name =
"msdi1"
;
141
char
*dev_name =
"mmci-omap"
;
142
143
if
(!mmc_data[0]) {
144
pr_err
(
"%s fails: Incomplete platform data\n"
, __func__);
145
return
;
146
}
147
148
omap242x_mmc_mux(mmc_data[0]);
149
150
oh =
omap_hwmod_lookup
(oh_name);
151
if
(!oh) {
152
pr_err
(
"Could not look up %s\n"
, oh_name);
153
return
;
154
}
155
pdev =
omap_device_build
(dev_name,
id
, oh, mmc_data[0],
156
sizeof
(
struct
omap_mmc_platform_data
),
NULL
, 0, 0);
157
if
(IS_ERR(pdev))
158
WARN
(1,
"Can'd build omap_device for %s:%s.\n"
,
159
dev_name, oh->
name
);
160
}
161
162
#endif
Generated on Thu Jan 10 2013 13:00:46 for Linux Kernel by
1.8.2