Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 313168
b: refs/heads/master
c: 3f0ea76
h: refs/heads/master
v: v3
  • Loading branch information
Vaibhav Hiremath authored and Paul Walmsley committed Jun 18, 2012
1 parent 618b0f7 commit 2631c01
Show file tree
Hide file tree
Showing 6 changed files with 439 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f969a6dcec75fe997a156b904d4fbbb5b313e54f
refs/heads/master: 3f0ea7645ae6d7111ebc3e83f47fbc0f2c8a8964
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-omap2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o
obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o
obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o

# PRCM clockdomain control
clockdomain-common += clockdomain.o
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/mach-omap2/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ void __init am33xx_init_early(void)
ti81xx_check_features();
omap_common_init_early();
am33xx_voltagedomains_init();
am33xx_powerdomains_init();
}
#endif

Expand Down
23 changes: 21 additions & 2 deletions trunk/arch/arm/mach-omap2/powerdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@

/*
* Maximum number of clockdomains that can be associated with a powerdomain.
* CORE powerdomain on OMAP4 is the worst case
* PER powerdomain on AM33XX is the worst case
*/
#define PWRDM_MAX_CLKDMS 9
#define PWRDM_MAX_CLKDMS 11

/* XXX A completely arbitrary number. What is reasonable here? */
#define PWRDM_TRANSITION_BAILOUT 100000
Expand All @@ -92,6 +92,15 @@ struct powerdomain;
* @pwrdm_clkdms: Clockdomains in this powerdomain
* @node: list_head linking all powerdomains
* @voltdm_node: list_head linking all powerdomains in a voltagedomain
* @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs
* @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs
* @logicretstate_mask: (AM33XX only) mask for logic retention bitfield
* in @pwrstctrl_offs
* @mem_on_mask: (AM33XX only) mask for mem on bitfield in @pwrstctrl_offs
* @mem_ret_mask: (AM33XX only) mask for mem ret bitfield in @pwrstctrl_offs
* @mem_pwrst_mask: (AM33XX only) mask for mem state bitfield in @pwrstst_offs
* @mem_retst_mask: (AM33XX only) mask for mem retention state bitfield
* in @pwrstctrl_offs
* @state:
* @state_counter:
* @timer:
Expand Down Expand Up @@ -121,6 +130,14 @@ struct powerdomain {
unsigned ret_logic_off_counter;
unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];

const u8 pwrstctrl_offs;
const u8 pwrstst_offs;
const u32 logicretstate_mask;
const u32 mem_on_mask[PWRDM_MAX_MEM_BANKS];
const u32 mem_ret_mask[PWRDM_MAX_MEM_BANKS];
const u32 mem_pwrst_mask[PWRDM_MAX_MEM_BANKS];
const u32 mem_retst_mask[PWRDM_MAX_MEM_BANKS];

#ifdef CONFIG_PM_DEBUG
s64 timer;
s64 state_timer[PWRDM_MAX_PWRSTS];
Expand Down Expand Up @@ -222,10 +239,12 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
extern void omap242x_powerdomains_init(void);
extern void omap243x_powerdomains_init(void);
extern void omap3xxx_powerdomains_init(void);
extern void am33xx_powerdomains_init(void);
extern void omap44xx_powerdomains_init(void);

extern struct pwrdm_ops omap2_pwrdm_operations;
extern struct pwrdm_ops omap3_pwrdm_operations;
extern struct pwrdm_ops am33xx_pwrdm_operations;
extern struct pwrdm_ops omap4_pwrdm_operations;

/* Common Internal functions used across OMAP rev's */
Expand Down
229 changes: 229 additions & 0 deletions trunk/arch/arm/mach-omap2/powerdomain33xx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*
* AM33XX Powerdomain control
*
* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
*
* Derived from mach-omap2/powerdomain44xx.c written by Rajendra Nayak
* <rnayak@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/io.h>
#include <linux/errno.h>
#include <linux/delay.h>

#include <plat/prcm.h>

#include "powerdomain.h"
#include "prm33xx.h"
#include "prm-regbits-33xx.h"


static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
{
am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK,
(pwrst << OMAP_POWERSTATE_SHIFT),
pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
return 0;
}

static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
{
u32 v;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
v &= OMAP_POWERSTATE_MASK;
v >>= OMAP_POWERSTATE_SHIFT;

return v;
}

static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
{
u32 v;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
v &= OMAP_POWERSTATEST_MASK;
v >>= OMAP_POWERSTATEST_SHIFT;

return v;
}

static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
{
u32 v;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;

return v;
}

static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
{
am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
(1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT),
pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
return 0;
}

static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
{
am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK,
AM33XX_LASTPOWERSTATEENTERED_MASK,
pwrdm->prcm_offs, pwrdm->pwrstst_offs);
return 0;
}

static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
{
u32 m;

m = pwrdm->logicretstate_mask;
if (!m)
return -EINVAL;

am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);

return 0;
}

static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
{
u32 v;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
v &= AM33XX_LOGICSTATEST_MASK;
v >>= AM33XX_LOGICSTATEST_SHIFT;

return v;
}

static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
{
u32 v, m;

m = pwrdm->logicretstate_mask;
if (!m)
return -EINVAL;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
v &= m;
v >>= __ffs(m);

return v;
}

static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
u8 pwrst)
{
u32 m;

m = pwrdm->mem_on_mask[bank];
if (!m)
return -EINVAL;

am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);

return 0;
}

static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
u8 pwrst)
{
u32 m;

m = pwrdm->mem_ret_mask[bank];
if (!m)
return -EINVAL;

am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)),
pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);

return 0;
}

static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
{
u32 m, v;

m = pwrdm->mem_pwrst_mask[bank];
if (!m)
return -EINVAL;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
v &= m;
v >>= __ffs(m);

return v;
}

static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
{
u32 m, v;

m = pwrdm->mem_retst_mask[bank];
if (!m)
return -EINVAL;

v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs);
v &= m;
v >>= __ffs(m);

return v;
}

static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
{
u32 c = 0;

/*
* REVISIT: pwrdm_wait_transition() may be better implemented
* via a callback and a periodic timer check -- how long do we expect
* powerdomain transitions to take?
*/

/* XXX Is this udelay() value meaningful? */
while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs)
& OMAP_INTRANSITION_MASK) &&
(c++ < PWRDM_TRANSITION_BAILOUT))
udelay(1);

if (c > PWRDM_TRANSITION_BAILOUT) {
pr_err("powerdomain: %s: waited too long to complete transition\n",
pwrdm->name);
return -EAGAIN;
}

pr_debug("powerdomain: completed transition in %d loops\n", c);

return 0;
}

struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
.pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
.pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
.pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
.pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
.pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,
.pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst,
.pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange,
.pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst,
.pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst,
.pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst,
.pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
.pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
};
Loading

0 comments on commit 2631c01

Please sign in to comment.