Linux Audio

Check our new training course

Loading...
v3.5.6
  1/*
  2 * OMAP2 and OMAP3 powerdomain control
  3 *
  4 * Copyright (C) 2009-2011 Texas Instruments, Inc.
  5 * Copyright (C) 2007-2009 Nokia Corporation
  6 *
  7 * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
  8 * Rajendra Nayak <rnayak@ti.com>
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License version 2 as
 12 * published by the Free Software Foundation.
 13 */
 14
 15#include <linux/io.h>
 16#include <linux/errno.h>
 17#include <linux/delay.h>
 18#include <linux/bug.h>
 19
 20#include <plat/prcm.h>
 21
 22#include "powerdomain.h"
 23#include "prm.h"
 24#include "prm-regbits-24xx.h"
 25#include "prm-regbits-34xx.h"
 26
 27
 28/* Common functions across OMAP2 and OMAP3 */
 29static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 30{
 31	omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
 32				(pwrst << OMAP_POWERSTATE_SHIFT),
 33				pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
 34	return 0;
 35}
 36
 37static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 38{
 39	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 40					     OMAP2_PM_PWSTCTRL,
 41					     OMAP_POWERSTATE_MASK);
 42}
 43
 44static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
 45{
 46	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 47					     OMAP2_PM_PWSTST,
 48					     OMAP_POWERSTATEST_MASK);
 49}
 50
 51static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
 52								u8 pwrst)
 53{
 54	u32 m;
 55
 56	m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
 57
 58	omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
 59				   OMAP2_PM_PWSTCTRL);
 60
 61	return 0;
 62}
 63
 64static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
 65								u8 pwrst)
 66{
 67	u32 m;
 68
 69	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 70
 71	omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
 72				   OMAP2_PM_PWSTCTRL);
 73
 74	return 0;
 75}
 76
 77static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 78{
 79	u32 m;
 80
 81	m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
 82
 83	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
 84					     m);
 85}
 86
 87static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 88{
 89	u32 m;
 90
 91	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 92
 93	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 94					     OMAP2_PM_PWSTCTRL, m);
 95}
 96
 97static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 98{
 99	u32 v;
100
101	v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
102	omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
103				   pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
104
105	return 0;
106}
107
108static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
109{
110	u32 c = 0;
111
112	/*
113	 * REVISIT: pwrdm_wait_transition() may be better implemented
114	 * via a callback and a periodic timer check -- how long do we expect
115	 * powerdomain transitions to take?
116	 */
117
118	/* XXX Is this udelay() value meaningful? */
119	while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
120		OMAP_INTRANSITION_MASK) &&
121		(c++ < PWRDM_TRANSITION_BAILOUT))
122			udelay(1);
123
124	if (c > PWRDM_TRANSITION_BAILOUT) {
125		printk(KERN_ERR "powerdomain: waited too long for "
126			"powerdomain %s to complete transition\n", pwrdm->name);
127		return -EAGAIN;
128	}
129
130	pr_debug("powerdomain: completed transition in %d loops\n", c);
131
132	return 0;
133}
134
135/* Applicable only for OMAP3. Not supported on OMAP2 */
136static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
137{
138	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
139					     OMAP3430_PM_PREPWSTST,
140					     OMAP3430_LASTPOWERSTATEENTERED_MASK);
141}
142
143static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
144{
145	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
146					     OMAP2_PM_PWSTST,
147					     OMAP3430_LOGICSTATEST_MASK);
148}
149
150static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
151{
152	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
153					     OMAP2_PM_PWSTCTRL,
154					     OMAP3430_LOGICSTATEST_MASK);
155}
156
157static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
158{
159	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
160					     OMAP3430_PM_PREPWSTST,
161					     OMAP3430_LASTLOGICSTATEENTERED_MASK);
162}
163
164static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
165{
166	switch (bank) {
167	case 0:
168		return OMAP3430_LASTMEM1STATEENTERED_MASK;
169	case 1:
170		return OMAP3430_LASTMEM2STATEENTERED_MASK;
171	case 2:
172		return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
173	case 3:
174		return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
175	default:
176		WARN_ON(1); /* should never happen */
177		return -EEXIST;
178	}
179	return 0;
180}
181
182static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
183{
184	u32 m;
185
186	m = omap3_get_mem_bank_lastmemst_mask(bank);
187
188	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
189				OMAP3430_PM_PREPWSTST, m);
190}
191
192static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
193{
194	omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
195	return 0;
196}
197
198static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
199{
200	return omap2_prm_rmw_mod_reg_bits(0,
201					  1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
202					  pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
203}
204
205static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
206{
207	return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
208					  0, pwrdm->prcm_offs,
209					  OMAP2_PM_PWSTCTRL);
210}
211
212struct pwrdm_ops omap2_pwrdm_operations = {
213	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
214	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
215	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
216	.pwrdm_set_logic_retst	= omap2_pwrdm_set_logic_retst,
217	.pwrdm_set_mem_onst	= omap2_pwrdm_set_mem_onst,
218	.pwrdm_set_mem_retst	= omap2_pwrdm_set_mem_retst,
219	.pwrdm_read_mem_pwrst	= omap2_pwrdm_read_mem_pwrst,
220	.pwrdm_read_mem_retst	= omap2_pwrdm_read_mem_retst,
221	.pwrdm_wait_transition	= omap2_pwrdm_wait_transition,
222};
223
224struct pwrdm_ops omap3_pwrdm_operations = {
225	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
226	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
227	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
228	.pwrdm_read_prev_pwrst	= omap3_pwrdm_read_prev_pwrst,
229	.pwrdm_set_logic_retst	= omap2_pwrdm_set_logic_retst,
230	.pwrdm_read_logic_pwrst	= omap3_pwrdm_read_logic_pwrst,
231	.pwrdm_read_logic_retst	= omap3_pwrdm_read_logic_retst,
232	.pwrdm_read_prev_logic_pwrst	= omap3_pwrdm_read_prev_logic_pwrst,
233	.pwrdm_set_mem_onst	= omap2_pwrdm_set_mem_onst,
234	.pwrdm_set_mem_retst	= omap2_pwrdm_set_mem_retst,
235	.pwrdm_read_mem_pwrst	= omap2_pwrdm_read_mem_pwrst,
236	.pwrdm_read_mem_retst	= omap2_pwrdm_read_mem_retst,
237	.pwrdm_read_prev_mem_pwrst	= omap3_pwrdm_read_prev_mem_pwrst,
238	.pwrdm_clear_all_prev_pwrst	= omap3_pwrdm_clear_all_prev_pwrst,
239	.pwrdm_enable_hdwr_sar	= omap3_pwrdm_enable_hdwr_sar,
240	.pwrdm_disable_hdwr_sar	= omap3_pwrdm_disable_hdwr_sar,
241	.pwrdm_wait_transition	= omap2_pwrdm_wait_transition,
242};
v3.1
  1/*
  2 * OMAP2 and OMAP3 powerdomain control
  3 *
  4 * Copyright (C) 2009-2010 Texas Instruments, Inc.
  5 * Copyright (C) 2007-2009 Nokia Corporation
  6 *
  7 * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
  8 * Rajendra Nayak <rnayak@ti.com>
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License version 2 as
 12 * published by the Free Software Foundation.
 13 */
 14
 15#include <linux/io.h>
 16#include <linux/errno.h>
 17#include <linux/delay.h>
 
 18
 19#include <plat/prcm.h>
 20
 21#include "powerdomain.h"
 22#include "prm.h"
 23#include "prm-regbits-24xx.h"
 24#include "prm-regbits-34xx.h"
 25
 26
 27/* Common functions across OMAP2 and OMAP3 */
 28static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 29{
 30	omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
 31				(pwrst << OMAP_POWERSTATE_SHIFT),
 32				pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
 33	return 0;
 34}
 35
 36static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 37{
 38	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 39					     OMAP2_PM_PWSTCTRL,
 40					     OMAP_POWERSTATE_MASK);
 41}
 42
 43static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
 44{
 45	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 46					     OMAP2_PM_PWSTST,
 47					     OMAP_POWERSTATEST_MASK);
 48}
 49
 50static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
 51								u8 pwrst)
 52{
 53	u32 m;
 54
 55	m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
 56
 57	omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
 58				   OMAP2_PM_PWSTCTRL);
 59
 60	return 0;
 61}
 62
 63static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
 64								u8 pwrst)
 65{
 66	u32 m;
 67
 68	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 69
 70	omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
 71				   OMAP2_PM_PWSTCTRL);
 72
 73	return 0;
 74}
 75
 76static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 77{
 78	u32 m;
 79
 80	m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
 81
 82	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
 83					     m);
 84}
 85
 86static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 87{
 88	u32 m;
 89
 90	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 91
 92	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
 93					     OMAP2_PM_PWSTCTRL, m);
 94}
 95
 96static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 97{
 98	u32 v;
 99
100	v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
101	omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
102				   pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
103
104	return 0;
105}
106
107static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
108{
109	u32 c = 0;
110
111	/*
112	 * REVISIT: pwrdm_wait_transition() may be better implemented
113	 * via a callback and a periodic timer check -- how long do we expect
114	 * powerdomain transitions to take?
115	 */
116
117	/* XXX Is this udelay() value meaningful? */
118	while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
119		OMAP_INTRANSITION_MASK) &&
120		(c++ < PWRDM_TRANSITION_BAILOUT))
121			udelay(1);
122
123	if (c > PWRDM_TRANSITION_BAILOUT) {
124		printk(KERN_ERR "powerdomain: waited too long for "
125			"powerdomain %s to complete transition\n", pwrdm->name);
126		return -EAGAIN;
127	}
128
129	pr_debug("powerdomain: completed transition in %d loops\n", c);
130
131	return 0;
132}
133
134/* Applicable only for OMAP3. Not supported on OMAP2 */
135static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
136{
137	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
138					     OMAP3430_PM_PREPWSTST,
139					     OMAP3430_LASTPOWERSTATEENTERED_MASK);
140}
141
142static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
143{
144	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
145					     OMAP2_PM_PWSTST,
146					     OMAP3430_LOGICSTATEST_MASK);
147}
148
149static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
150{
151	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
152					     OMAP2_PM_PWSTCTRL,
153					     OMAP3430_LOGICSTATEST_MASK);
154}
155
156static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
157{
158	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
159					     OMAP3430_PM_PREPWSTST,
160					     OMAP3430_LASTLOGICSTATEENTERED_MASK);
161}
162
163static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
164{
165	switch (bank) {
166	case 0:
167		return OMAP3430_LASTMEM1STATEENTERED_MASK;
168	case 1:
169		return OMAP3430_LASTMEM2STATEENTERED_MASK;
170	case 2:
171		return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
172	case 3:
173		return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
174	default:
175		WARN_ON(1); /* should never happen */
176		return -EEXIST;
177	}
178	return 0;
179}
180
181static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
182{
183	u32 m;
184
185	m = omap3_get_mem_bank_lastmemst_mask(bank);
186
187	return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
188				OMAP3430_PM_PREPWSTST, m);
189}
190
191static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
192{
193	omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
194	return 0;
195}
196
197static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
198{
199	return omap2_prm_rmw_mod_reg_bits(0,
200					  1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
201					  pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
202}
203
204static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
205{
206	return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
207					  0, pwrdm->prcm_offs,
208					  OMAP2_PM_PWSTCTRL);
209}
210
211struct pwrdm_ops omap2_pwrdm_operations = {
212	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
213	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
214	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
215	.pwrdm_set_logic_retst	= omap2_pwrdm_set_logic_retst,
216	.pwrdm_set_mem_onst	= omap2_pwrdm_set_mem_onst,
217	.pwrdm_set_mem_retst	= omap2_pwrdm_set_mem_retst,
218	.pwrdm_read_mem_pwrst	= omap2_pwrdm_read_mem_pwrst,
219	.pwrdm_read_mem_retst	= omap2_pwrdm_read_mem_retst,
220	.pwrdm_wait_transition	= omap2_pwrdm_wait_transition,
221};
222
223struct pwrdm_ops omap3_pwrdm_operations = {
224	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,
225	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst,
226	.pwrdm_read_pwrst	= omap2_pwrdm_read_pwrst,
227	.pwrdm_read_prev_pwrst	= omap3_pwrdm_read_prev_pwrst,
228	.pwrdm_set_logic_retst	= omap2_pwrdm_set_logic_retst,
229	.pwrdm_read_logic_pwrst	= omap3_pwrdm_read_logic_pwrst,
230	.pwrdm_read_logic_retst	= omap3_pwrdm_read_logic_retst,
231	.pwrdm_read_prev_logic_pwrst	= omap3_pwrdm_read_prev_logic_pwrst,
232	.pwrdm_set_mem_onst	= omap2_pwrdm_set_mem_onst,
233	.pwrdm_set_mem_retst	= omap2_pwrdm_set_mem_retst,
234	.pwrdm_read_mem_pwrst	= omap2_pwrdm_read_mem_pwrst,
235	.pwrdm_read_mem_retst	= omap2_pwrdm_read_mem_retst,
236	.pwrdm_read_prev_mem_pwrst	= omap3_pwrdm_read_prev_mem_pwrst,
237	.pwrdm_clear_all_prev_pwrst	= omap3_pwrdm_clear_all_prev_pwrst,
238	.pwrdm_enable_hdwr_sar	= omap3_pwrdm_enable_hdwr_sar,
239	.pwrdm_disable_hdwr_sar	= omap3_pwrdm_disable_hdwr_sar,
240	.pwrdm_wait_transition	= omap2_pwrdm_wait_transition,
241};