aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/Makefile5
-rw-r--r--arch/arm/mach-omap2/cm.c70
-rw-r--r--arch/arm/mach-omap2/cm.h4
-rw-r--r--arch/arm/mach-omap2/cm4xxx.c68
4 files changed, 147 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 8850a247bec9..59d730fa77e5 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -35,6 +35,11 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
35obj-$(CONFIG_PM_DEBUG) += pm-debug.o 35obj-$(CONFIG_PM_DEBUG) += pm-debug.o
36endif 36endif
37 37
38# PRCM
39obj-$(CONFIG_ARCH_OMAP2) += cm.o
40obj-$(CONFIG_ARCH_OMAP3) += cm.o
41obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o
42
38# Clock framework 43# Clock framework
39obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o 44obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o
40obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o 45obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
new file mode 100644
index 000000000000..8eb2dab8c7db
--- /dev/null
+++ b/arch/arm/mach-omap2/cm.c
@@ -0,0 +1,70 @@
1/*
2 * OMAP2/3 CM module functions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/delay.h>
16#include <linux/spinlock.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/io.h>
21
22#include <asm/atomic.h>
23
24#include "cm.h"
25#include "cm-regbits-24xx.h"
26#include "cm-regbits-34xx.h"
27
28/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
29#define MAX_MODULE_READY_TIME 20000
30
31static const u8 cm_idlest_offs[] = {
32 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
33};
34
35/**
36 * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
37 * @prcm_mod: PRCM module offset
38 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
39 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
40 *
41 * XXX document
42 */
43int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
44{
45 int ena = 0, i = 0;
46 u8 cm_idlest_reg;
47 u32 mask;
48
49 if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
50 return -EINVAL;
51
52 cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
53
54 if (cpu_is_omap24xx())
55 ena = idlest_shift;
56 else if (cpu_is_omap34xx())
57 ena = 0;
58 else
59 BUG();
60
61 mask = 1 << idlest_shift;
62
63 /* XXX should be OMAP2 CM */
64 while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) &&
65 (i++ < MAX_MODULE_READY_TIME))
66 udelay(1);
67
68 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
69}
70
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 18d9a121aa7a..cfd0b726ba44 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -98,6 +98,10 @@ extern u32 cm_read_mod_reg(s16 module, u16 idx);
98extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); 98extern void cm_write_mod_reg(u32 val, s16 module, u16 idx);
99extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); 99extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
100 100
101extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
102 u8 idlest_shift);
103extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs);
104
101static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) 105static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
102{ 106{
103 return cm_rmw_mod_reg_bits(bits, bits, module, idx); 107 return cm_rmw_mod_reg_bits(bits, bits, module, idx);
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
new file mode 100644
index 000000000000..e4ebd6d53135
--- /dev/null
+++ b/arch/arm/mach-omap2/cm4xxx.c
@@ -0,0 +1,68 @@
1/*
2 * OMAP4 CM module functions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/delay.h>
16#include <linux/spinlock.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/io.h>
21
22#include <asm/atomic.h>
23
24#include "cm.h"
25#include "cm-regbits-4xxx.h"
26
27/* XXX move this to cm.h */
28/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
29#define MAX_MODULE_READY_TIME 20000
30
31/*
32 * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the
33 * CM_CLKCTRL register.
34 */
35#define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK (0x2 << 16)
36
37/*
38 * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and
39 * the PRCM module offset address (from the CM module base) in bits 15-0.
40 */
41#define OMAP4_PRCM_MOD_CM_ID_SHIFT 16
42#define OMAP4_PRCM_MOD_OFFS_MASK 0xffff
43
44/**
45 * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby
46 * @prcm_mod: PRCM module offset (XXX example)
47 * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example)
48 *
49 * XXX document
50 */
51int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs)
52{
53 int i = 0;
54 u8 cm_id;
55 u16 prcm_mod_offs;
56 u32 mask = OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK;
57
58 cm_id = prcm_mod >> OMAP4_PRCM_MOD_CM_ID_SHIFT;
59 prcm_mod_offs = prcm_mod & OMAP4_PRCM_MOD_OFFS_MASK;
60
61 while (((omap4_cm_read_mod_reg(cm_id, prcm_mod_offs, prcm_dev_offs,
62 OMAP4_CM_CLKCTRL_DREG) & mask) != 0) &&
63 (i++ < MAX_MODULE_READY_TIME))
64 udelay(1);
65
66 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
67}
68