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
prm44xx.c
Go to the documentation of this file.
1
/*
2
* OMAP4 PRM module functions
3
*
4
* Copyright (C) 2011 Texas Instruments, Inc.
5
* Copyright (C) 2010 Nokia Corporation
6
* BenoƮt Cousson
7
* Paul Walmsley
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License version 2 as
11
* published by the Free Software Foundation.
12
*/
13
14
#include <linux/kernel.h>
15
#include <
linux/delay.h
>
16
#include <linux/errno.h>
17
#include <
linux/err.h
>
18
#include <
linux/io.h
>
19
20
#include <
plat/prcm.h
>
21
22
#include "
soc.h
"
23
#include "
iomap.h
"
24
#include "
common.h
"
25
#include "
vp.h
"
26
#include "
prm44xx.h
"
27
#include "
prm-regbits-44xx.h
"
28
#include "
prcm44xx.h
"
29
#include "
prminst44xx.h
"
30
31
static
const
struct
omap_prcm_irq
omap4_prcm_irqs[] = {
32
OMAP_PRCM_IRQ
(
"wkup"
, 0, 0),
33
OMAP_PRCM_IRQ
(
"io"
, 9, 1),
34
};
35
36
static
struct
omap_prcm_irq_setup
omap4_prcm_irq_setup = {
37
.ack =
OMAP4_PRM_IRQSTATUS_MPU_OFFSET
,
38
.mask =
OMAP4_PRM_IRQENABLE_MPU_OFFSET
,
39
.nr_regs = 2,
40
.irqs = omap4_prcm_irqs,
41
.nr_irqs =
ARRAY_SIZE
(omap4_prcm_irqs),
42
.irq = 11 +
OMAP44XX_IRQ_GIC_START
,
43
.read_pending_irqs = &
omap44xx_prm_read_pending_irqs
,
44
.ocp_barrier = &
omap44xx_prm_ocp_barrier
,
45
.save_and_clear_irqen = &
omap44xx_prm_save_and_clear_irqen
,
46
.restore_irqen = &
omap44xx_prm_restore_irqen
,
47
};
48
49
/* PRM low-level functions */
50
51
/* Read a register in a CM/PRM instance in the PRM module */
52
u32
omap4_prm_read_inst_reg
(
s16
inst,
u16
reg
)
53
{
54
return
__raw_readl
(
OMAP44XX_PRM_REGADDR
(inst, reg));
55
}
56
57
/* Write into a register in a CM/PRM instance in the PRM module */
58
void
omap4_prm_write_inst_reg
(
u32
val
,
s16
inst,
u16
reg
)
59
{
60
__raw_writel
(val,
OMAP44XX_PRM_REGADDR
(inst, reg));
61
}
62
63
/* Read-modify-write a register in a PRM module. Caller must lock */
64
u32
omap4_prm_rmw_inst_reg_bits
(
u32
mask
,
u32
bits
,
s16
inst,
s16
reg
)
65
{
66
u32
v
;
67
68
v =
omap4_prm_read_inst_reg
(inst, reg);
69
v &= ~mask;
70
v |=
bits
;
71
omap4_prm_write_inst_reg
(v, inst, reg);
72
73
return
v
;
74
}
75
76
/* PRM VP */
77
78
/*
79
* struct omap4_vp - OMAP4 VP register access description.
80
* @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
81
* @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
82
*/
83
struct
omap4_vp
{
84
u32
irqstatus_mpu
;
85
u32
tranxdone_status
;
86
};
87
88
static
struct
omap4_vp
omap4_vp
[] = {
89
[
OMAP4_VP_VDD_MPU_ID
] = {
90
.
irqstatus_mpu
=
OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET
,
91
.tranxdone_status =
OMAP4430_VP_MPU_TRANXDONE_ST_MASK
,
92
},
93
[
OMAP4_VP_VDD_IVA_ID
] = {
94
.irqstatus_mpu =
OMAP4_PRM_IRQSTATUS_MPU_OFFSET
,
95
.tranxdone_status =
OMAP4430_VP_IVA_TRANXDONE_ST_MASK
,
96
},
97
[
OMAP4_VP_VDD_CORE_ID
] = {
98
.irqstatus_mpu =
OMAP4_PRM_IRQSTATUS_MPU_OFFSET
,
99
.tranxdone_status =
OMAP4430_VP_CORE_TRANXDONE_ST_MASK
,
100
},
101
};
102
103
u32
omap4_prm_vp_check_txdone
(
u8
vp_id)
104
{
105
struct
omap4_vp *vp = &omap4_vp[vp_id];
106
u32
irqstatus;
107
108
irqstatus =
omap4_prminst_read_inst_reg
(
OMAP4430_PRM_PARTITION
,
109
OMAP4430_PRM_OCP_SOCKET_INST
,
110
vp->
irqstatus_mpu
);
111
return
irqstatus & vp->
tranxdone_status
;
112
}
113
114
void
omap4_prm_vp_clear_txdone
(
u8
vp_id)
115
{
116
struct
omap4_vp *vp = &omap4_vp[vp_id];
117
118
omap4_prminst_write_inst_reg
(vp->
tranxdone_status
,
119
OMAP4430_PRM_PARTITION
,
120
OMAP4430_PRM_OCP_SOCKET_INST
,
121
vp->
irqstatus_mpu
);
122
};
123
124
u32
omap4_prm_vcvp_read
(
u8
offset
)
125
{
126
return
omap4_prminst_read_inst_reg
(
OMAP4430_PRM_PARTITION
,
127
OMAP4430_PRM_DEVICE_INST
, offset);
128
}
129
130
void
omap4_prm_vcvp_write
(
u32
val
,
u8
offset
)
131
{
132
omap4_prminst_write_inst_reg
(val,
OMAP4430_PRM_PARTITION
,
133
OMAP4430_PRM_DEVICE_INST
, offset);
134
}
135
136
u32
omap4_prm_vcvp_rmw
(
u32
mask
,
u32
bits
,
u8
offset
)
137
{
138
return
omap4_prminst_rmw_inst_reg_bits
(mask, bits,
139
OMAP4430_PRM_PARTITION
,
140
OMAP4430_PRM_DEVICE_INST
,
141
offset);
142
}
143
144
static
inline
u32
_read_pending_irq_reg(
u16
irqen_offs,
u16
irqst_offs)
145
{
146
u32
mask
,
st
;
147
148
/* XXX read mask from RAM? */
149
mask =
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
,
150
irqen_offs);
151
st =
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
, irqst_offs);
152
153
return
mask &
st
;
154
}
155
164
void
omap44xx_prm_read_pending_irqs
(
unsigned
long
*
events
)
165
{
166
events[0] = _read_pending_irq_reg(
OMAP4_PRM_IRQENABLE_MPU_OFFSET
,
167
OMAP4_PRM_IRQSTATUS_MPU_OFFSET
);
168
169
events[1] = _read_pending_irq_reg(
OMAP4_PRM_IRQENABLE_MPU_2_OFFSET
,
170
OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET
);
171
}
172
181
void
omap44xx_prm_ocp_barrier
(
void
)
182
{
183
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
,
184
OMAP4_REVISION_PRM_OFFSET
);
185
}
186
198
void
omap44xx_prm_save_and_clear_irqen
(
u32
*saved_mask)
199
{
200
saved_mask[0] =
201
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
,
202
OMAP4_PRM_IRQSTATUS_MPU_OFFSET
);
203
saved_mask[1] =
204
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
,
205
OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET
);
206
207
omap4_prm_write_inst_reg
(0,
OMAP4430_PRM_OCP_SOCKET_INST
,
208
OMAP4_PRM_IRQENABLE_MPU_OFFSET
);
209
omap4_prm_write_inst_reg
(0,
OMAP4430_PRM_OCP_SOCKET_INST
,
210
OMAP4_PRM_IRQENABLE_MPU_2_OFFSET
);
211
212
/* OCP barrier */
213
omap4_prm_read_inst_reg
(
OMAP4430_PRM_OCP_SOCKET_INST
,
214
OMAP4_REVISION_PRM_OFFSET
);
215
}
216
227
void
omap44xx_prm_restore_irqen
(
u32
*saved_mask)
228
{
229
omap4_prm_write_inst_reg
(saved_mask[0],
OMAP4430_PRM_OCP_SOCKET_INST
,
230
OMAP4_PRM_IRQENABLE_MPU_OFFSET
);
231
omap4_prm_write_inst_reg
(saved_mask[1],
OMAP4430_PRM_OCP_SOCKET_INST
,
232
OMAP4_PRM_IRQENABLE_MPU_2_OFFSET
);
233
}
234
244
void
omap44xx_prm_reconfigure_io_chain
(
void
)
245
{
246
int
i
= 0;
247
248
/* Trigger WUCLKIN enable */
249
omap4_prm_rmw_inst_reg_bits
(
OMAP4430_WUCLK_CTRL_MASK
,
250
OMAP4430_WUCLK_CTRL_MASK
,
251
OMAP4430_PRM_DEVICE_INST
,
252
OMAP4_PRM_IO_PMCTRL_OFFSET
);
253
omap_test_timeout(
254
(((
omap4_prm_read_inst_reg
(
OMAP4430_PRM_DEVICE_INST
,
255
OMAP4_PRM_IO_PMCTRL_OFFSET
) &
256
OMAP4430_WUCLK_STATUS_MASK
) >>
257
OMAP4430_WUCLK_STATUS_SHIFT
) == 1),
258
MAX_IOPAD_LATCH_TIME
, i);
259
if
(i ==
MAX_IOPAD_LATCH_TIME
)
260
pr_warn
(
"PRM: I/O chain clock line assertion timed out\n"
);
261
262
/* Trigger WUCLKIN disable */
263
omap4_prm_rmw_inst_reg_bits
(
OMAP4430_WUCLK_CTRL_MASK
, 0x0,
264
OMAP4430_PRM_DEVICE_INST
,
265
OMAP4_PRM_IO_PMCTRL_OFFSET
);
266
omap_test_timeout(
267
(((
omap4_prm_read_inst_reg
(
OMAP4430_PRM_DEVICE_INST
,
268
OMAP4_PRM_IO_PMCTRL_OFFSET
) &
269
OMAP4430_WUCLK_STATUS_MASK) >>
270
OMAP4430_WUCLK_STATUS_SHIFT
) == 0),
271
MAX_IOPAD_LATCH_TIME
, i);
272
if
(i ==
MAX_IOPAD_LATCH_TIME
)
273
pr_warn
(
"PRM: I/O chain clock line deassertion timed out\n"
);
274
275
return
;
276
}
277
286
static
void
__init
omap44xx_prm_enable_io_wakeup(
void
)
287
{
288
omap4_prm_rmw_inst_reg_bits
(
OMAP4430_GLOBAL_WUEN_MASK
,
289
OMAP4430_GLOBAL_WUEN_MASK
,
290
OMAP4430_PRM_DEVICE_INST
,
291
OMAP4_PRM_IO_PMCTRL_OFFSET
);
292
}
293
294
static
int
__init
omap4xxx_prcm_init(
void
)
295
{
296
if
(
cpu_is_omap44xx
()) {
297
omap44xx_prm_enable_io_wakeup();
298
return
omap_prcm_register_chain_handler
(&omap4_prcm_irq_setup);
299
}
300
return
0;
301
}
302
subsys_initcall
(omap4xxx_prcm_init);
Generated on Thu Jan 10 2013 13:00:58 for Linux Kernel by
1.8.2