PM: Add domain to all PM interfaces. Internal PM data structures now handle multiple PM domains.
This commit is contained in:
parent
dea4fe5d90
commit
54dbec248e
@ -11588,5 +11588,9 @@
|
|||||||
|
|
||||||
7.16 2016-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
7.16 2016-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
|
||||||
* PM: Add activity domain to all PM driver callbacks (2016-03-27).
|
* PM: Add activity domain to all PM interfaces and driver callbacks. If
|
||||||
|
CONFIG_PM_NDOMAINS == 1, then the legacy behavior is preserved. If
|
||||||
|
CONFIG_PM_NDOMAINS > 1, then multiple PM domains are supported. This
|
||||||
|
will allow separate control for certain power management groups. For
|
||||||
|
example, a network can be shut down without affect an ongoing UI (and
|
||||||
|
vice versa) (2016-03-27).
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit a15cb168507bf218b37a3325902df18085ede4a6
|
Subproject commit 6e43c1ef42c8204d18610771482e460f24034c69
|
2
arch
2
arch
@ -1 +1 @@
|
|||||||
Subproject commit f4b99ebe1fd5ab77e9a6adda04611787b4a26205
|
Subproject commit d5fbee30366a95c69d6c2fab19b2c52f48b73137
|
2
configs
2
configs
@ -1 +1 @@
|
|||||||
Subproject commit 07937231ef92ab88e2043dc9a17d2d677e26903c
|
Subproject commit 11a38b291293ba4fc18e91343b4a0ca94edf670d
|
@ -217,7 +217,7 @@ config PM_SLEEPEXIT_THRESH
|
|||||||
|
|
||||||
config PM_SLEEPENTER_COUNT
|
config PM_SLEEPENTER_COUNT
|
||||||
int "PM SLEEP enter count"
|
int "PM SLEEP enter count"
|
||||||
default 50
|
default 70
|
||||||
---help---
|
---help---
|
||||||
State changes then occur when the weight activity account crosses
|
State changes then occur when the weight activity account crosses
|
||||||
threshold values for certain periods of time (time slice count).
|
threshold values for certain periods of time (time slice count).
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/power/pm
|
* drivers/power/pm
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -96,12 +96,12 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/* This structure encapsulates all of the global data used by the PM module */
|
/* This describes the activity and state for one domain */
|
||||||
|
|
||||||
struct pm_global_s
|
struct pm_domain_s
|
||||||
{
|
{
|
||||||
/* state - The current state (as determined by an explicit call to
|
/* state - The current state for this PM domain (as determined by an
|
||||||
* pm_changestate()
|
* explicit call to pm_changestate())
|
||||||
* recommended - The recommended state based on the PM algorithm in
|
* recommended - The recommended state based on the PM algorithm in
|
||||||
* function pm_update().
|
* function pm_update().
|
||||||
* mndex - The index to the next slot in the memory[] array to use.
|
* mndex - The index to the next slot in the memory[] array to use.
|
||||||
@ -138,6 +138,15 @@ struct pm_global_s
|
|||||||
/* stime - The time (in ticks) at the start of the current time slice */
|
/* stime - The time (in ticks) at the start of the current time slice */
|
||||||
|
|
||||||
systime_t stime;
|
systime_t stime;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This structure encapsulates all of the global data used by the PM module */
|
||||||
|
|
||||||
|
struct pm_global_s
|
||||||
|
{
|
||||||
|
/* The activity/state information for each PM domain */
|
||||||
|
|
||||||
|
struct pm_domain_s domain[CONFIG_PM_NDOMAINS];
|
||||||
|
|
||||||
/* This semaphore manages mutually exclusive access to the power management
|
/* This semaphore manages mutually exclusive access to the power management
|
||||||
* registry. It must be initialized to the value 1.
|
* registry. It must be initialized to the value 1.
|
||||||
@ -186,6 +195,7 @@ EXTERN struct pm_global_s g_pmglobals;
|
|||||||
* update driver activity metrics and recommended states.
|
* update driver activity metrics and recommended states.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* domain - The domain associated with the accumulator.
|
||||||
* accum - The value of the activity accumulator at the end of the time
|
* accum - The value of the activity accumulator at the end of the time
|
||||||
* slice.
|
* slice.
|
||||||
*
|
*
|
||||||
@ -200,7 +210,7 @@ EXTERN struct pm_global_s g_pmglobals;
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
EXTERN void pm_update(int16_t accum);
|
EXTERN void pm_update(int domain, int16_t accum);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/power/pm_activity.c
|
* drivers/power/pm_activity.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -47,30 +47,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -85,6 +61,7 @@
|
|||||||
* power states.
|
* power states.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* domain - The domain of the PM activity
|
||||||
* priority - Activity priority, range 0-9. Larger values correspond to
|
* priority - Activity priority, range 0-9. Larger values correspond to
|
||||||
* higher priorities. Higher priority activity can prevent the system
|
* higher priorities. Higher priority activity can prevent the system
|
||||||
* from entering reduced power states for a longer period of time.
|
* from entering reduced power states for a longer period of time.
|
||||||
@ -101,12 +78,18 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void pm_activity(int priority)
|
void pm_activity(int domain, int priority)
|
||||||
{
|
{
|
||||||
|
FAR struct pm_domain_s *pdom;
|
||||||
systime_t now;
|
systime_t now;
|
||||||
uint32_t accum;
|
uint32_t accum;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
pdom = &g_pmglobals.domain[domain];
|
||||||
|
|
||||||
/* Just increment the activity count in the current time slice. The priority
|
/* Just increment the activity count in the current time slice. The priority
|
||||||
* is simply the number of counts that are added.
|
* is simply the number of counts that are added.
|
||||||
*/
|
*/
|
||||||
@ -116,7 +99,7 @@ void pm_activity(int priority)
|
|||||||
/* Add the priority to the accumulated counts in a critical section. */
|
/* Add the priority to the accumulated counts in a critical section. */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
accum = (uint32_t)g_pmglobals.accum + priority;
|
accum = (uint32_t)pdom->accum + priority;
|
||||||
|
|
||||||
/* Make sure that we do not overflow the underlying uint16_t representation */
|
/* Make sure that we do not overflow the underlying uint16_t representation */
|
||||||
|
|
||||||
@ -127,7 +110,7 @@ void pm_activity(int priority)
|
|||||||
|
|
||||||
/* Save the updated count */
|
/* Save the updated count */
|
||||||
|
|
||||||
g_pmglobals.accum = (int16_t)accum;
|
pdom->accum = (int16_t)accum;
|
||||||
|
|
||||||
/* Check the elapsed time. In periods of low activity, time slicing is
|
/* Check the elapsed time. In periods of low activity, time slicing is
|
||||||
* controlled by IDLE loop polling; in periods of higher activity, time
|
* controlled by IDLE loop polling; in periods of higher activity, time
|
||||||
@ -138,7 +121,7 @@ void pm_activity(int priority)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
now = clock_systimer();
|
now = clock_systimer();
|
||||||
if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
|
if (now - pdom->stime >= TIME_SLICE_TICKS)
|
||||||
{
|
{
|
||||||
int16_t tmp;
|
int16_t tmp;
|
||||||
|
|
||||||
@ -147,16 +130,16 @@ void pm_activity(int priority)
|
|||||||
* still disabled.
|
* still disabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = g_pmglobals.accum;
|
tmp = pdom->accum;
|
||||||
g_pmglobals.stime = now;
|
pdom->stime = now;
|
||||||
g_pmglobals.accum = 0;
|
pdom->accum = 0;
|
||||||
|
|
||||||
/* Reassessing the PM state may require some computation. However,
|
/* Reassessing the PM state may require some computation. However,
|
||||||
* the work will actually be performed on a worker thread at a user-
|
* the work will actually be performed on a worker thread at a user-
|
||||||
* controlled priority.
|
* controlled priority.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pm_update(tmp);
|
(void)pm_update(domain, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
@ -164,4 +147,3 @@ void pm_activity(int priority)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
|
@ -46,26 +46,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -213,7 +193,7 @@ int pm_changestate(int domain, enum pm_state_e newstate)
|
|||||||
* the preceding state.
|
* the preceding state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
newstate = g_pmglobals.state;
|
newstate = g_pmglobals.domain[domain].state;
|
||||||
(void)pm_prepall(domain, newstate);
|
(void)pm_prepall(domain, newstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +202,7 @@ int pm_changestate(int domain, enum pm_state_e newstate)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pm_changeall(domain, newstate);
|
pm_changeall(domain, newstate);
|
||||||
g_pmglobals.state = newstate;
|
g_pmglobals.domain[domain].state = newstate;
|
||||||
|
|
||||||
/* Restore the interrupt state */
|
/* Restore the interrupt state */
|
||||||
|
|
||||||
|
@ -47,30 +47,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -99,18 +75,24 @@
|
|||||||
* is completed.
|
* is completed.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* None
|
* domain - the PM domain to check
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* The recommended power management state.
|
* The recommended power management state.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
enum pm_state_e pm_checkstate(void)
|
enum pm_state_e pm_checkstate(int domain)
|
||||||
{
|
{
|
||||||
|
FAR struct pm_domain_s *pdom;
|
||||||
systime_t now;
|
systime_t now;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
pdom = &g_pmglobals.domain[domain];
|
||||||
|
|
||||||
/* Check for the end of the current time slice. This must be performed
|
/* Check for the end of the current time slice. This must be performed
|
||||||
* with interrupts disabled so that it does not conflict with the similar
|
* with interrupts disabled so that it does not conflict with the similar
|
||||||
* logic in pm_activity().
|
* logic in pm_activity().
|
||||||
@ -127,7 +109,7 @@ enum pm_state_e pm_checkstate(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
now = clock_systimer();
|
now = clock_systimer();
|
||||||
if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
|
if (now - pdom->stime >= TIME_SLICE_TICKS)
|
||||||
{
|
{
|
||||||
int16_t accum;
|
int16_t accum;
|
||||||
|
|
||||||
@ -136,16 +118,16 @@ enum pm_state_e pm_checkstate(void)
|
|||||||
* still disabled.
|
* still disabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
accum = g_pmglobals.accum;
|
accum = pdom->accum;
|
||||||
g_pmglobals.stime = now;
|
pdom->stime = now;
|
||||||
g_pmglobals.accum = 0;
|
pdom->accum = 0;
|
||||||
|
|
||||||
/* Reassessing the PM state may require some computation. However,
|
/* Reassessing the PM state may require some computation. However,
|
||||||
* the work will actually be performed on a worker thread at a user-
|
* the work will actually be performed on a worker thread at a user-
|
||||||
* controlled priority.
|
* controlled priority.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pm_update(accum);
|
(void)pm_update(domain, accum);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
@ -156,7 +138,7 @@ enum pm_state_e pm_checkstate(void)
|
|||||||
* state should be current:
|
* state should be current:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return g_pmglobals.recommended;
|
return pdom->recommended;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
@ -47,22 +47,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -71,10 +55,6 @@
|
|||||||
|
|
||||||
struct pm_global_s g_pmglobals;
|
struct pm_global_s g_pmglobals;
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -48,30 +48,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/power/pm_update.c
|
* drivers/power/pm_update.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <nuttx/power/pm.h>
|
#include <nuttx/power/pm.h>
|
||||||
@ -48,14 +49,22 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct pm_worker_param_s
|
||||||
|
{
|
||||||
|
uint8_t domndx;
|
||||||
|
int16_t accum;
|
||||||
|
};
|
||||||
|
|
||||||
|
union pm_worker_param_u
|
||||||
|
{
|
||||||
|
struct pm_worker_param_s s;
|
||||||
|
uintptr_t i;
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -134,7 +143,7 @@ static const uint16_t g_pmcount[3] =
|
|||||||
* Name: pm_worker
|
* Name: pm_worker
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This worker function is queue at the end of a time slice in order to
|
* This worker function is queued at the end of a time slice in order to
|
||||||
* update driver activity metrics and recommended states.
|
* update driver activity metrics and recommended states.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
@ -151,22 +160,42 @@ static const uint16_t g_pmcount[3] =
|
|||||||
|
|
||||||
void pm_worker(FAR void *arg)
|
void pm_worker(FAR void *arg)
|
||||||
{
|
{
|
||||||
int16_t accum = (int16_t)((intptr_t)arg);
|
union pm_worker_param_u parameter;
|
||||||
|
FAR struct pm_domain_s *pdom;
|
||||||
int32_t Y;
|
int32_t Y;
|
||||||
|
int16_t accum;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
#if CONFIG_PM_MEMORY > 1
|
#if CONFIG_PM_MEMORY > 1
|
||||||
int32_t denom;
|
int32_t denom;
|
||||||
int i, j;
|
int i;
|
||||||
|
int j;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Decode the domain and accumulator as a scaler value.
|
||||||
|
*
|
||||||
|
* REVISIT: domain will fit in a uint8_t and accum is int16_t. Assuming
|
||||||
|
* that sizeof(FAR void *) >=3, the following will work. It will not work
|
||||||
|
* for 16-bit addresses!
|
||||||
|
*/
|
||||||
|
|
||||||
|
parameter.i = (uintptr_t)arg;
|
||||||
|
index = parameter.s.domndx;
|
||||||
|
accum = parameter.s.accum;
|
||||||
|
|
||||||
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
pdom = &g_pmglobals.domain[index];
|
||||||
|
|
||||||
|
#if CONFIG_PM_MEMORY > 1
|
||||||
/* We won't bother to do anything until we have accumulated
|
/* We won't bother to do anything until we have accumulated
|
||||||
* CONFIG_PM_MEMORY-1 samples.
|
* CONFIG_PM_MEMORY-1 samples.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (g_pmglobals.mcnt < CONFIG_PM_MEMORY-1)
|
if (pdom->mcnt < CONFIG_PM_MEMORY-1)
|
||||||
{
|
{
|
||||||
g_pmglobals.memory[g_pmglobals.mcnt] = accum;
|
index = pdom->mcnt++;
|
||||||
g_pmglobals.mcnt++;
|
pdom->memory[index] = accum;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,29 +213,32 @@ void pm_worker(FAR void *arg)
|
|||||||
denom = CONFIG_PM_COEFN;
|
denom = CONFIG_PM_COEFN;
|
||||||
|
|
||||||
/* Then calculate Y += SUM(Ai*Yi), i = 1..n-1. The oldest sample will
|
/* Then calculate Y += SUM(Ai*Yi), i = 1..n-1. The oldest sample will
|
||||||
* reside at g_pmglobals.mndx (and this is the value that we will overwrite
|
* reside at the domain's mndx (and this is the value that we will overwrite
|
||||||
* with the new value).
|
* with the new value).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0, j = g_pmglobals.mndx; i < CONFIG_PM_MEMORY-1; i++, j++)
|
for (i = 0, j = pdom->mndx;
|
||||||
|
i < CONFIG_PM_MEMORY-1;
|
||||||
|
i++, j++)
|
||||||
{
|
{
|
||||||
if (j >= CONFIG_PM_MEMORY-1)
|
if (j >= CONFIG_PM_MEMORY-1)
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Y += g_pmcoeffs[i] * g_pmglobals.memory[j];
|
Y += g_pmcoeffs[i] * pdom->memory[j];
|
||||||
denom += g_pmcoeffs[i];
|
denom += g_pmcoeffs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute and save the new activity value */
|
/* Compute and save the new activity value */
|
||||||
|
|
||||||
Y /= denom;
|
Y /= denom;
|
||||||
g_pmglobals.memory[g_pmglobals.mndx] = Y;
|
|
||||||
g_pmglobals.mndx++;
|
index = pdom->mndx++;
|
||||||
if (g_pmglobals.mndx >= CONFIG_PM_MEMORY-1)
|
pdom->memory[index] = Y;
|
||||||
|
if (pdom->mndx >= CONFIG_PM_MEMORY-1)
|
||||||
{
|
{
|
||||||
g_pmglobals.mndx = 0;
|
pdom->mndx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -223,13 +255,13 @@ void pm_worker(FAR void *arg)
|
|||||||
* probably does apply for the IDLE state.
|
* probably does apply for the IDLE state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (g_pmglobals.state > PM_NORMAL)
|
if (pdom->state > PM_NORMAL)
|
||||||
{
|
{
|
||||||
/* Get the table index for the current state (which will be the
|
/* Get the table index for the current state (which will be the
|
||||||
* current state minus one)
|
* current state minus one)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
index = g_pmglobals.state - 1;
|
index = pdom->state - 1;
|
||||||
|
|
||||||
/* Has the threshold to return to normal power consumption state been
|
/* Has the threshold to return to normal power consumption state been
|
||||||
* exceeded?
|
* exceeded?
|
||||||
@ -239,8 +271,8 @@ void pm_worker(FAR void *arg)
|
|||||||
{
|
{
|
||||||
/* Yes... reset the count and recommend the normal state. */
|
/* Yes... reset the count and recommend the normal state. */
|
||||||
|
|
||||||
g_pmglobals.thrcnt = 0;
|
pdom->thrcnt = 0;
|
||||||
g_pmglobals.recommended = PM_NORMAL;
|
pdom->recommended = PM_NORMAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,7 +283,7 @@ void pm_worker(FAR void *arg)
|
|||||||
* surprised to be executing!).
|
* surprised to be executing!).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (g_pmglobals.state < PM_SLEEP)
|
if (pdom->state < PM_SLEEP)
|
||||||
{
|
{
|
||||||
unsigned int nextstate;
|
unsigned int nextstate;
|
||||||
|
|
||||||
@ -259,8 +291,8 @@ void pm_worker(FAR void *arg)
|
|||||||
* be the current state)
|
* be the current state)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
index = g_pmglobals.state;
|
index = pdom->state;
|
||||||
nextstate = g_pmglobals.state + 1;
|
nextstate = pdom->state + 1;
|
||||||
|
|
||||||
/* Has the threshold to enter the next lower power consumption state
|
/* Has the threshold to enter the next lower power consumption state
|
||||||
* been exceeded?
|
* been exceeded?
|
||||||
@ -270,26 +302,26 @@ void pm_worker(FAR void *arg)
|
|||||||
{
|
{
|
||||||
/* No... reset the count and recommend the current state */
|
/* No... reset the count and recommend the current state */
|
||||||
|
|
||||||
g_pmglobals.thrcnt = 0;
|
pdom->thrcnt = 0;
|
||||||
g_pmglobals.recommended = g_pmglobals.state;
|
pdom->recommended = pdom->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Yes.. have we already recommended this state? If so, do nothing */
|
/* Yes.. have we already recommended this state? If so, do nothing */
|
||||||
|
|
||||||
else if (g_pmglobals.recommended < nextstate)
|
else if (pdom->recommended < nextstate)
|
||||||
{
|
{
|
||||||
/* No.. increment the count. Has it passed the count required
|
/* No.. increment the count. Has it passed the count required
|
||||||
* for a state transition?
|
* for a state transition?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (++g_pmglobals.thrcnt >= g_pmcount[index])
|
if (++pdom->thrcnt >= g_pmcount[index])
|
||||||
{
|
{
|
||||||
/* Yes, recommend the new state and set up for the next
|
/* Yes, recommend the new state and set up for the next
|
||||||
* transition.
|
* transition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g_pmglobals.thrcnt = 0;
|
pdom->thrcnt = 0;
|
||||||
g_pmglobals.recommended = nextstate;
|
pdom->recommended = nextstate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,6 +339,7 @@ void pm_worker(FAR void *arg)
|
|||||||
* update driver activity metrics and recommended states.
|
* update driver activity metrics and recommended states.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* domain - The PM domain associated with the accumulator
|
||||||
* accum - The value of the activity accumulator at the end of the time
|
* accum - The value of the activity accumulator at the end of the time
|
||||||
* slice.
|
* slice.
|
||||||
*
|
*
|
||||||
@ -323,13 +356,26 @@ void pm_worker(FAR void *arg)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void pm_update(int16_t accum)
|
void pm_update(int domain, int16_t accum)
|
||||||
{
|
{
|
||||||
|
union pm_worker_param_u parameter;
|
||||||
|
|
||||||
|
/* Encode the domain and accumulator as a scaler value.
|
||||||
|
*
|
||||||
|
* REVISIT: domain will fit in a uint8_t and accum is int16_t. Assuming
|
||||||
|
* that sizeof(FAR void *) >=3, the following will work. It will not work
|
||||||
|
* for 16-bit addresses!
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
parameter.s.domndx = (uint8_t)domain;
|
||||||
|
parameter.s.accum = accum;
|
||||||
|
|
||||||
/* The work will be performed on the worker thread */
|
/* The work will be performed on the worker thread */
|
||||||
|
|
||||||
DEBUGASSERT(g_pmglobals.work.worker == NULL);
|
DEBUGASSERT(g_pmglobals.work.worker == NULL);
|
||||||
(void)work_queue(HPWORK, &g_pmglobals.work, pm_worker,
|
(void)work_queue(HPWORK, &g_pmglobals.work, pm_worker,
|
||||||
(FAR void *)((intptr_t)accum), 0);
|
(FAR void *)parameter.i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
@ -402,6 +402,7 @@ int pm_register(FAR struct pm_callback_s *callbacks);
|
|||||||
* power states.
|
* power states.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* domain - The domain of the PM activity
|
||||||
* priority - Activity priority, range 0-9. Larger values correspond to
|
* priority - Activity priority, range 0-9. Larger values correspond to
|
||||||
* higher priorities. Higher priority activity can prevent the system
|
* higher priorities. Higher priority activity can prevent the system
|
||||||
* from entering reduced power states for a longer period of time.
|
* from entering reduced power states for a longer period of time.
|
||||||
@ -418,7 +419,7 @@ int pm_register(FAR struct pm_callback_s *callbacks);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void pm_activity(int priority);
|
void pm_activity(int domain, int priority);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_checkstate
|
* Name: pm_checkstate
|
||||||
@ -444,14 +445,14 @@ void pm_activity(int priority);
|
|||||||
* is completed.
|
* is completed.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* None
|
* domain - The PM domain to check
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* The recommended power management state.
|
* The recommended power management state.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
enum pm_state_e pm_checkstate(void);
|
enum pm_state_e pm_checkstate(int domain);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_changestate
|
* Name: pm_changestate
|
||||||
@ -501,10 +502,10 @@ int pm_changestate(int domain, enum pm_state_e newstate);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
# define pm_initialize()
|
# define pm_initialize()
|
||||||
# define pm_register(cb) (0)
|
# define pm_register(cb) (0)
|
||||||
# define pm_activity(prio)
|
# define pm_activity(domain,prio)
|
||||||
# define pm_checkstate() (0)
|
# define pm_checkstate(domain) (0)
|
||||||
# define pm_changestate(state)
|
# define pm_changestate(domain,state)
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
#endif /* __INCLUDE_NUTTX_POWER_PM_H */
|
#endif /* __INCLUDE_NUTTX_POWER_PM_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user