Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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};