summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx35/system.c
blob: 19ee470339fca2a5fb43ce48e4ffff7db92cc4bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/proc-fns.h>
#include <asm/system.h>
#include <mach/clock.h>
#include <mach/hardware.h>
#include "crm_regs.h"

/*!
 * @defgroup MSL_MX35 i.MX35 Machine Specific Layer (MSL)
 */

/*!
 * @file mach-mx35/system.c
 * @brief This file contains idle and reset functions.
 *
 * @ingroup MSL_MX35
 */

/*!
* MX35 low-power mode
*/
enum mx35_low_pwr_mode {
	MX35_RUN_MODE,
	MX35_WAIT_MODE,
	MX35_DOZE_MODE,
	MX35_STOP_MODE
};

extern int mxc_jtag_enabled;

/*!
 * This function is used to set cpu low power mode before WFI instruction
 *
 * @param  mode         indicates different kinds of power modes
 */
void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{
	unsigned int lpm;
	unsigned long reg;

	/*read CCMR value */
	reg = __raw_readl(MXC_CCM_CCMR);

	switch (mode) {
	case WAIT_UNCLOCKED_POWER_OFF:
		lpm = MX35_DOZE_MODE;
		break;

	case STOP_POWER_ON:
	case STOP_POWER_OFF:
		lpm = MX35_STOP_MODE;
		/* Enabled Well Bias */
		reg |= MXC_CCM_CCMR_WBEN;
		if (!board_is_rev(BOARD_REV_1))
			reg |= MXC_CCM_CCMR_VSTBY;
		break;

	case WAIT_CLOCKED:
	case WAIT_UNCLOCKED:
	default:
		/* Wait is the default mode used when idle. */
		lpm = MX35_WAIT_MODE;
		break;
	}

	/* program LPM bit */
	reg = (reg & (~MXC_CCM_CCMR_LPM_MASK)) | lpm << MXC_CCM_CCMR_LPM_OFFSET;
	/* program Interrupt holdoff bit */
	reg = reg | MXC_CCM_CCMR_WFI;
	/* TBD: PMIC has put the voltage back to Normal if the voltage ready */
	/* counter finished */
	reg = reg | MXC_CCM_CCMR_STBY_EXIT_SRC;

	__raw_writel(reg, MXC_CCM_CCMR);
}

EXPORT_SYMBOL(mxc_cpu_lp_set);

/*!
 * This function puts the CPU into idle mode. It is called by default_idle()
 * in process.c file.
 */
void arch_idle(void)
{
	/*
	 * This should do all the clock switching
	 * and wait for interrupt tricks.
	 */
	if (!mxc_jtag_enabled) {
#ifdef CONFIG_MX35_DOZE_DURING_IDLE
		/*set as Doze mode */
		mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
#else
		/* set as Wait mode */
		mxc_cpu_lp_set(WAIT_UNCLOCKED);
#endif
		cpu_do_idle();
	}
}

/*
 * This function resets the system. It is called by machine_restart().
 *
 * @param  mode         indicates different kinds of resets
 */
void arch_reset(char mode)
{
	unsigned long reg;

	reg = __raw_readl(MXC_CCM_CGR0);
	reg |=
	    (MXC_CCM_CGR0_ESDHC1_MASK | MXC_CCM_CGR0_ESDHC2_MASK |
	     MXC_CCM_CGR0_ESDHC3_MASK);
	__raw_writel(reg, MXC_CCM_CGR0);

	/* Assert SRS signal */
	mxc_wd_reset();
}