Skip to content

Commit 771b3d2

Browse files
committed
ace: pm_runtime: force L1 exit if requested
IMPORTANT: PM part should be moved to zephyr! This will add possibility to force host L1 exit Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
1 parent 93cb105 commit 771b3d2

2 files changed

Lines changed: 96 additions & 4 deletions

File tree

src/audio/host-zephyr.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <sof/lib/mailbox.h>
2020
#include <sof/lib/memory.h>
2121
#include <sof/lib/notifier.h>
22+
#include <sof/lib/pm_runtime.h>
2223
#include <sof/lib/uuid.h>
2324
#include <sof/list.h>
2425
#include <sof/math/numbers.h>
@@ -531,6 +532,9 @@ static int host_copy_normal(struct comp_dev *dev)
531532
if (!copy_bytes)
532533
return 0;
533534

535+
/* Register Host DMA usage */
536+
pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0);
537+
534538
struct dma_cb_data next = {
535539
.channel = hd->chan,
536540
.elem = { .size = copy_bytes },
@@ -584,6 +588,12 @@ static int create_local_elems(struct comp_dev *dev, uint32_t buffer_count,
584588
return 0;
585589
}
586590

591+
static void hda_dma_l1_exit_notify(void *arg, enum notify_id type, void *data)
592+
{
593+
/* Force Host DMA to exit L1 if needed */
594+
pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0);
595+
}
596+
587597
/**
588598
* \brief Command handler.
589599
* \param[in,out] dev Device
@@ -625,6 +635,10 @@ static int host_trigger(struct comp_dev *dev, int cmd)
625635
if (ret < 0)
626636
comp_err(dev, "host_trigger(): dma_start() failed, ret = %u",
627637
ret);
638+
/* Register common L1 exit for all channels */
639+
ret = notifier_register(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER),
640+
NOTIFIER_ID_LL_POST_RUN, hda_dma_l1_exit_notify,
641+
NOTIFIER_FLAG_AGGREGATE);
628642
break;
629643
case COMP_TRIGGER_STOP:
630644
case COMP_TRIGGER_XRUN:
@@ -633,6 +647,9 @@ static int host_trigger(struct comp_dev *dev, int cmd)
633647
if (ret < 0)
634648
comp_err(dev, "host_trigger(): dma stop failed: %d",
635649
ret);
650+
/* Unregister L1 exit */
651+
notifier_unregister(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER),
652+
NOTIFIER_ID_LL_POST_RUN);
636653
}
637654

638655
break;
@@ -1052,8 +1069,12 @@ static int host_reset(struct comp_dev *dev)
10521069
comp_dbg(dev, "host_reset()");
10531070

10541071
if (hd->chan) {
1055-
if (dev->state == COMP_STATE_ACTIVE)
1072+
if (dev->state == COMP_STATE_ACTIVE) {
10561073
dma_stop(hd->chan->dma->z_dev, hd->chan->index);
1074+
/* Unregister L1 exit */
1075+
notifier_unregister(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER),
1076+
NOTIFIER_ID_LL_POST_RUN);
1077+
}
10571078

10581079
/* remove callback */
10591080
notifier_unregister(dev, hd->chan, NOTIFIER_ID_DMA_COPY);

src/platform/intel/ace/lib/pm_runtime.c

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
#include <user/trace.h>
1010
#include <sof_versions.h>
1111
#include <stdint.h>
12+
#include <rtos/alloc.h>
13+
#include <rtos/wait.h>
14+
#include <ipc/topology.h>
1215

1316
#include <adsp_boot.h>
17+
#include <adsp_shim.h>
1418
#include <zephyr/pm/policy.h>
1519

1620
LOG_MODULE_REGISTER(power, CONFIG_SOF_LOG_LEVEL);
@@ -21,6 +25,11 @@ DECLARE_SOF_UUID("power", power_uuid, 0x76cc9773, 0x440c, 0x4df9,
2125

2226
DECLARE_TR_CTX(power_tr, SOF_UUID(power_uuid), LOG_LEVEL_INFO);
2327

28+
/** \brief ACE specific runtime power management data. */
29+
struct ace_pm_runtime_data {
30+
int host_dma_l1_sref; /**< ref counter for Host DMA accesses */
31+
};
32+
2433
#if defined(CONFIG_PM_POLICY_CUSTOM)
2534
const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
2635
{
@@ -98,16 +107,78 @@ void platform_pm_runtime_disable(uint32_t context, uint32_t index)
98107
}
99108
}
100109

110+
/**
111+
* \brief Registers Host DMA usage that should not trigger
112+
* transition to L0 via forced L1 exit.
113+
*/
114+
static void ace_pm_runtime_host_dma_l1_get(void)
115+
{
116+
struct pm_runtime_data *prd = pm_runtime_data_get();
117+
struct ace_pm_runtime_data *pprd = prd->platform_data;
118+
k_spinlock_key_t key;
119+
120+
key = k_spin_lock(&prd->lock);
121+
122+
pprd->host_dma_l1_sref++;
123+
124+
k_spin_unlock(&prd->lock, key);
125+
}
126+
127+
/**
128+
* \brief Releases Host DMA usage preventing L1 exit. If this
129+
* the last user, forced L1 exit is performed.
130+
*/
131+
static inline void ace_pm_runtime_host_dma_l1_put(void)
132+
{
133+
struct pm_runtime_data *prd = pm_runtime_data_get();
134+
struct ace_pm_runtime_data *pprd = prd->platform_data;
135+
k_spinlock_key_t key;
136+
137+
key = k_spin_lock(&prd->lock);
138+
139+
if (pprd->host_dma_l1_sref) {
140+
ACE_DfPMCCH.svcfg |= ADSP_FORCE_DECOUPLED_HDMA_L1_EXIT_BIT;
141+
wait_delay(ADSP_FORCE_L1_EXIT_TIME);
142+
ACE_DfPMCCH.svcfg &= ~(ADSP_FORCE_DECOUPLED_HDMA_L1_EXIT_BIT);
143+
}
144+
pprd->host_dma_l1_sref = 0;
145+
146+
k_spin_unlock(&prd->lock, key);
147+
}
148+
101149
void platform_pm_runtime_init(struct pm_runtime_data *prd)
102-
{ }
150+
{
151+
struct ace_pm_runtime_data *pprd;
152+
153+
pprd = rzalloc(SOF_MEM_ZONE_SYS_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*pprd));
154+
prd->platform_data = pprd;
155+
}
103156

104157
void platform_pm_runtime_get(enum pm_runtime_context context, uint32_t index,
105158
uint32_t flags)
106-
{ }
159+
{
160+
/* Action based on context */
161+
switch (context) {
162+
case PM_RUNTIME_HOST_DMA_L1:
163+
ace_pm_runtime_host_dma_l1_get();
164+
break;
165+
default:
166+
break;
167+
}
168+
}
107169

108170
void platform_pm_runtime_put(enum pm_runtime_context context, uint32_t index,
109171
uint32_t flags)
110-
{ }
172+
{
173+
/* Action based on context */
174+
switch (context) {
175+
case PM_RUNTIME_HOST_DMA_L1:
176+
ace_pm_runtime_host_dma_l1_put();
177+
break;
178+
default:
179+
break;
180+
}
181+
}
111182

112183
void platform_pm_runtime_prepare_d0ix_en(uint32_t index)
113184
{ }

0 commit comments

Comments
 (0)