Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331318
b: refs/heads/master
c: b71c721
h: refs/heads/master
v: v3
  • Loading branch information
Paul Walmsley committed Sep 23, 2012
1 parent c84954e commit 8464f61
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 26 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: 5c3e4ec48586f6dfb482f1c524748948ba14021e
refs/heads/master: b71c72178e24118214f21567a15adcad61b4238a
17 changes: 17 additions & 0 deletions trunk/arch/arm/mach-omap2/clockdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
return ret;
}

/**
* clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
* @clkdm: struct clockdomain *
*
* Returns true if clockdomain @clkdm has the
* CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
* null. More information is available in the documentation for the
* CLKDM_MISSING_IDLE_REPORTING macro.
*/
bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
{
if (!clkdm)
return false;

return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
}

/* Clockdomain-to-clock/hwmod framework interface code */

static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
Expand Down
20 changes: 17 additions & 3 deletions trunk/arch/arm/mach-omap2/clockdomain.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/*
* arch/arm/plat-omap/include/mach/clockdomain.h
*
* OMAP2/3 clockdomain framework functions
*
* Copyright (C) 2008 Texas Instruments, Inc.
* Copyright (C) 2008, 2012 Texas Instruments, Inc.
* Copyright (C) 2008-2011 Nokia Corporation
*
* Paul Walmsley
Expand Down Expand Up @@ -34,13 +32,28 @@
* CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
* active whenever the MPU is active. True for interconnects and
* the WKUP clockdomains.
* CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
* clocks inside this clockdomain are not taken into account by
* the PRCM when determining whether the clockdomain is idle.
* Without this flag, if the clockdomain is set to
* hardware-supervised idle mode, the PRCM may transition the
* enclosing powerdomain to a low power state, even when devices
* inside the clockdomain and powerdomain are in use. (An example
* of such a clockdomain is the EMU clockdomain on OMAP3/4.) If
* this flag is set, and the clockdomain does not support the
* force-sleep mode, then the HW_AUTO mode will be used to put the
* clockdomain to sleep. Similarly, if the clockdomain supports
* the force-wakeup mode, then it will be used whenever a clock or
* IP block inside the clockdomain is active, rather than the
* HW_AUTO mode.
*/
#define CLKDM_CAN_FORCE_SLEEP (1 << 0)
#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)
#define CLKDM_CAN_ENABLE_AUTO (1 << 2)
#define CLKDM_CAN_DISABLE_AUTO (1 << 3)
#define CLKDM_NO_AUTODEPS (1 << 4)
#define CLKDM_ACTIVE_WITH_MPU (1 << 5)
#define CLKDM_MISSING_IDLE_REPORTING (1 << 6)

#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
Expand Down Expand Up @@ -187,6 +200,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm);
bool clkdm_in_hwsup(struct clockdomain *clkdm);
bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);

int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
Expand Down
49 changes: 35 additions & 14 deletions trunk/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ static void _disable_hwsup(struct clockdomain *clkdm)
clkdm->clktrctrl_mask);
}

static int omap3_clkdm_sleep(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
return 0;
}

static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
return 0;
}

static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
{
Expand All @@ -170,6 +183,17 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
if (!clkdm->clktrctrl_mask)
return 0;

/*
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
* more details on the unpleasant problem this is working
* around
*/
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
_enable_hwsup(clkdm);
return 0;
}

hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);

Expand All @@ -193,6 +217,17 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
if (!clkdm->clktrctrl_mask)
return 0;

/*
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
* more details on the unpleasant problem this is working
* around
*/
if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
omap3_clkdm_wakeup(clkdm);
return 0;
}

hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);

Expand All @@ -209,20 +244,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
return 0;
}

static int omap3_clkdm_sleep(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
return 0;
}

static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
{
omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
return 0;
}

static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
{
if (atomic_read(&clkdm->usecount) > 0)
Expand Down
11 changes: 11 additions & 0 deletions trunk/arch/arm/mach-omap2/clockdomain44xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
if (!clkdm->prcm_partition)
return 0;

/*
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
* more details on the unpleasant problem this is working
* around
*/
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
omap4_clkdm_allow_idle(clkdm);
return 0;
}

hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
clkdm->cm_inst, clkdm->clkdm_offs);

Expand Down
7 changes: 2 additions & 5 deletions trunk/arch/arm/mach-omap2/clockdomains3xxx_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
};

/*
* Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
* switched of even if sdti is in use
*/
static struct clockdomain emu_clkdm = {
.name = "emu_clkdm",
.pwrdm = { .name = "emu_pwrdm" },
.flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
.flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
CLKDM_MISSING_IDLE_REPORTING),
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
};

Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/mach-omap2/clockdomains44xx_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
.prcm_partition = OMAP4430_PRM_PARTITION,
.cm_inst = OMAP4430_PRM_EMU_CM_INST,
.clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
.flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
.flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
CLKDM_MISSING_IDLE_REPORTING),
};

static struct clockdomain l3_dma_44xx_clkdm = {
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -2007,7 +2007,8 @@ static int _enable(struct omap_hwmod *oh)
* completely the module. The clockdomain can be set
* in HW_AUTO only when the module become ready.
*/
hwsup = clkdm_in_hwsup(oh->clkdm);
hwsup = clkdm_in_hwsup(oh->clkdm) &&
!clkdm_missing_idle_reporting(oh->clkdm);
r = clkdm_hwmod_enable(oh->clkdm, oh);
if (r) {
WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/arm/mach-omap2/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ static void __init omap2_init_processor_devices(void)

int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
{
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
!(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
Expand Down

0 comments on commit 8464f61

Please sign in to comment.