Skip to content

Commit ae226a8

Browse files
committed
drivers: crypto: cc23x0: Add power management
Add PM support to cc23x0 AES module. Signed-off-by: Julien Panis <jpanis@baylibre.com>
1 parent 179045e commit ae226a8

File tree

1 file changed

+133
-10
lines changed

1 file changed

+133
-10
lines changed

drivers/crypto/crypto_cc23x0.c

Lines changed: 133 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(crypto_cc23x0, CONFIG_CRYPTO_LOG_LEVEL);
1414
#include <zephyr/drivers/dma.h>
1515
#include <zephyr/irq.h>
1616
#include <zephyr/kernel.h>
17+
#include <zephyr/pm/device.h>
18+
#include <zephyr/pm/device_runtime.h>
19+
#include <zephyr/pm/policy.h>
1720
#include <zephyr/sys/util.h>
1821

1922
#include <string.h>
@@ -80,6 +83,22 @@ struct crypto_cc23x0_data {
8083
#endif
8184
};
8285

86+
static inline void crypto_cc23x0_pm_policy_state_lock_get(void)
87+
{
88+
#ifdef CONFIG_PM_DEVICE
89+
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
90+
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
91+
#endif
92+
}
93+
94+
static inline void crypto_cc23x0_pm_policy_state_lock_put(void)
95+
{
96+
#ifdef CONFIG_PM_DEVICE
97+
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
98+
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
99+
#endif
100+
}
101+
83102
static void crypto_cc23x0_isr(const struct device *dev)
84103
{
85104
struct crypto_cc23x0_data *data = dev->data;
@@ -102,17 +121,42 @@ static void crypto_cc23x0_isr(const struct device *dev)
102121
AESClearInterrupt(status);
103122
}
104123

105-
static void crypto_cc23x0_cleanup(const struct device *dev)
106-
{
107124
#ifdef CONFIG_CRYPTO_CC23X0_DMA
125+
126+
static int crypto_cc23x0_dma_enable(const struct device *dev, bool *dma_enabled)
127+
{
128+
const struct crypto_cc23x0_config *cfg = dev->config;
129+
int ret;
130+
131+
ret = pm_device_runtime_get(cfg->dma_dev);
132+
if (ret) {
133+
LOG_ERR("Failed to resume DMA");
134+
*dma_enabled = false;
135+
} else {
136+
*dma_enabled = true;
137+
}
138+
139+
return ret;
140+
}
141+
142+
static void crypto_cc23x0_dma_cleanup(const struct device *dev, bool dma_enabled)
143+
{
108144
const struct crypto_cc23x0_config *cfg = dev->config;
109145

110146
dma_stop(cfg->dma_dev, cfg->dma_channel_b);
111147
dma_stop(cfg->dma_dev, cfg->dma_channel_a);
148+
112149
AESDisableDMA();
113-
#else
114-
ARG_UNUSED(dev);
115-
#endif
150+
151+
if (dma_enabled) {
152+
pm_device_runtime_put(cfg->dma_dev);
153+
}
154+
}
155+
156+
#endif /* CONFIG_CRYPTO_CC23X0_DMA */
157+
158+
static void crypto_cc23x0_aes_cleanup(void)
159+
{
116160
AESClearAUTOCFGTrigger();
117161
AESClearAUTOCFGBusHalt();
118162
AESClearTXTAndBUF();
@@ -127,6 +171,7 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
127171
#ifdef CONFIG_CRYPTO_CC23X0_DMA
128172
uint32_t int_flags = AES_IMASK_CHBDONE;
129173
const struct crypto_cc23x0_config *cfg = dev->config;
174+
bool dma_enabled = false;
130175

131176
struct dma_block_config block_cfg_cha = {
132177
.source_address = (uint32_t)(pkt->in_buf),
@@ -186,6 +231,8 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
186231

187232
k_mutex_lock(&data->device_mutex, K_FOREVER);
188233

234+
crypto_cc23x0_pm_policy_state_lock_get();
235+
189236
/* Enable interrupts */
190237
AESSetIMASK(int_flags);
191238

@@ -198,6 +245,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
198245
AES_AUTOCFG_TRGAES_WRBUF3S);
199246

200247
#ifdef CONFIG_CRYPTO_CC23X0_DMA
248+
ret = crypto_cc23x0_dma_enable(dev, &dma_enabled);
249+
if (ret) {
250+
goto cleanup;
251+
}
252+
201253
/* Setup the DMA for the AES engine */
202254
AESSetupDMA(AES_DMA_ADRCHA_BUF0 |
203255
AES_DMA_TRGCHA_AESSTART |
@@ -209,11 +261,13 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
209261

210262
ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha);
211263
if (ret) {
264+
LOG_ERR("Failed to configure DMA CHA");
212265
goto cleanup;
213266
}
214267

215268
ret = dma_config(cfg->dma_dev, cfg->dma_channel_b, &dma_cfg_chb);
216269
if (ret) {
270+
LOG_ERR("Failed to configure DMA CHB");
217271
goto cleanup;
218272
}
219273

@@ -265,7 +319,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
265319
#endif
266320

267321
cleanup:
268-
crypto_cc23x0_cleanup(dev);
322+
#ifdef CONFIG_CRYPTO_CC23X0_DMA
323+
crypto_cc23x0_dma_cleanup(dev, dma_enabled);
324+
#endif
325+
crypto_cc23x0_aes_cleanup();
326+
crypto_cc23x0_pm_policy_state_lock_put();
269327
k_mutex_unlock(&data->device_mutex);
270328
pkt->out_len = out_bytes_processed;
271329

@@ -284,6 +342,7 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
284342
#ifdef CONFIG_CRYPTO_CC23X0_DMA
285343
uint32_t int_flags = AES_IMASK_CHBDONE;
286344
const struct crypto_cc23x0_config *cfg = dev->config;
345+
bool dma_enabled = false;
287346

288347
struct dma_block_config block_cfg_cha = {
289348
.source_address = (uint32_t)(pkt->in_buf),
@@ -345,6 +404,8 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
345404

346405
k_mutex_lock(&data->device_mutex, K_FOREVER);
347406

407+
crypto_cc23x0_pm_policy_state_lock_get();
408+
348409
/* Enable interrupts */
349410
AESSetIMASK(int_flags);
350411

@@ -359,6 +420,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
359420
AES_AUTOCFG_CTRSIZE_CTR128);
360421

361422
#ifdef CONFIG_CRYPTO_CC23X0_DMA
423+
ret = crypto_cc23x0_dma_enable(dev, &dma_enabled);
424+
if (ret) {
425+
goto cleanup;
426+
}
427+
362428
/* Setup the DMA for the AES engine */
363429
AESSetupDMA(AES_DMA_ADRCHA_TXTX0 |
364430
AES_DMA_TRGCHA_AESDONE |
@@ -367,11 +433,13 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
367433

368434
ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha);
369435
if (ret) {
436+
LOG_ERR("Failed to configure DMA CHA");
370437
goto cleanup;
371438
}
372439

373440
ret = dma_config(cfg->dma_dev, cfg->dma_channel_b, &dma_cfg_chb);
374441
if (ret) {
442+
LOG_ERR("Failed to configure DMA CHB");
375443
goto cleanup;
376444
}
377445

@@ -433,7 +501,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
433501
#endif
434502

435503
cleanup:
436-
crypto_cc23x0_cleanup(dev);
504+
#ifdef CONFIG_CRYPTO_CC23X0_DMA
505+
crypto_cc23x0_dma_cleanup(dev, dma_enabled);
506+
#endif
507+
crypto_cc23x0_aes_cleanup();
508+
crypto_cc23x0_pm_policy_state_lock_put();
437509
k_mutex_unlock(&data->device_mutex);
438510
pkt->out_len = bytes_processed;
439511

@@ -451,6 +523,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
451523
#ifdef CONFIG_CRYPTO_CC23X0_DMA
452524
uint32_t int_flags = AES_IMASK_CHADONE;
453525
const struct crypto_cc23x0_config *cfg = dev->config;
526+
bool dma_enabled = false;
454527

455528
struct dma_block_config block_cfg_cha = {
456529
.source_address = (uint32_t)b0,
@@ -492,6 +565,8 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
492565

493566
k_mutex_lock(&data->device_mutex, K_FOREVER);
494567

568+
crypto_cc23x0_pm_policy_state_lock_get();
569+
495570
/* Enable interrupts */
496571
AESSetIMASK(int_flags);
497572

@@ -506,6 +581,13 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
506581
/* Write zero'd IV */
507582
AESWriteIV32(iv);
508583

584+
#ifdef CONFIG_CRYPTO_CC23X0_DMA
585+
ret = crypto_cc23x0_dma_enable(dev, &dma_enabled);
586+
if (ret) {
587+
goto out;
588+
}
589+
#endif
590+
509591
if (b0) {
510592
#ifdef CONFIG_CRYPTO_CC23X0_DMA
511593
/* Setup the DMA for the AES engine */
@@ -514,6 +596,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
514596

515597
ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha);
516598
if (ret) {
599+
LOG_ERR("Failed to configure DMA CHA");
517600
goto out;
518601
}
519602

@@ -546,6 +629,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
546629

547630
ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha);
548631
if (ret) {
632+
LOG_ERR("Failed to configure DMA CHA");
549633
goto out;
550634
}
551635

@@ -578,6 +662,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
578662

579663
ret = dma_config(cfg->dma_dev, cfg->dma_channel_a, &dma_cfg_cha);
580664
if (ret) {
665+
LOG_ERR("Failed to configure DMA CHA");
581666
goto out;
582667
}
583668

@@ -624,7 +709,11 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
624709
AESReadTag(pkt->out_buf);
625710

626711
out:
627-
crypto_cc23x0_cleanup(dev);
712+
#ifdef CONFIG_CRYPTO_CC23X0_DMA
713+
crypto_cc23x0_dma_cleanup(dev, dma_enabled);
714+
#endif
715+
crypto_cc23x0_aes_cleanup();
716+
crypto_cc23x0_pm_policy_state_lock_put();
628717
k_mutex_unlock(&data->device_mutex);
629718
pkt->out_len = bytes_processed;
630719

@@ -979,6 +1068,7 @@ static int crypto_cc23x0_init(const struct device *dev)
9791068
{
9801069
#ifdef CONFIG_CRYPTO_CC23X0_DMA
9811070
const struct crypto_cc23x0_config *cfg = dev->config;
1071+
int ret;
9821072
#endif
9831073
struct crypto_cc23x0_data *data = dev->data;
9841074

@@ -1000,6 +1090,12 @@ static int crypto_cc23x0_init(const struct device *dev)
10001090
if (!device_is_ready(cfg->dma_dev)) {
10011091
return -ENODEV;
10021092
}
1093+
1094+
ret = pm_device_runtime_enable(cfg->dma_dev);
1095+
if (ret) {
1096+
LOG_ERR("Failed to enable DMA runtime PM");
1097+
return ret;
1098+
}
10031099
#else
10041100
k_sem_init(&data->aes_done, 0, 1);
10051101
#endif
@@ -1015,6 +1111,33 @@ static DEVICE_API(crypto, crypto_enc_funcs) = {
10151111

10161112
static struct crypto_cc23x0_data crypto_cc23x0_dev_data;
10171113

1114+
#ifdef CONFIG_PM_DEVICE
1115+
1116+
static int crypto_cc23x0_pm_action(const struct device *dev, enum pm_device_action action)
1117+
{
1118+
int ret = 0;
1119+
1120+
switch (action) {
1121+
case PM_DEVICE_ACTION_SUSPEND:
1122+
CLKCTLDisable(CLKCTL_BASE, CLKCTL_LAES);
1123+
break;
1124+
case PM_DEVICE_ACTION_RESUME:
1125+
CLKCTLEnable(CLKCTL_BASE, CLKCTL_LAES);
1126+
break;
1127+
case PM_DEVICE_ACTION_TURN_ON:
1128+
case PM_DEVICE_ACTION_TURN_OFF:
1129+
break;
1130+
default:
1131+
ret = -ENOTSUP;
1132+
}
1133+
1134+
return ret;
1135+
}
1136+
1137+
#endif /* CONFIG_PM_DEVICE */
1138+
1139+
PM_DEVICE_DT_INST_DEFINE(0, crypto_cc23x0_pm_action);
1140+
10181141
#ifdef CONFIG_CRYPTO_CC23X0_DMA
10191142
static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = {
10201143
.dma_dev = DEVICE_DT_GET(TI_CC23X0_DT_INST_DMA_CTLR(0, cha)),
@@ -1026,7 +1149,7 @@ static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = {
10261149

10271150
DEVICE_DT_INST_DEFINE(0,
10281151
crypto_cc23x0_init,
1029-
NULL,
1152+
PM_DEVICE_DT_INST_GET(0),
10301153
&crypto_cc23x0_dev_data,
10311154
&crypto_cc23x0_dev_config,
10321155
POST_KERNEL,
@@ -1035,7 +1158,7 @@ DEVICE_DT_INST_DEFINE(0,
10351158
#else
10361159
DEVICE_DT_INST_DEFINE(0,
10371160
crypto_cc23x0_init,
1038-
NULL,
1161+
PM_DEVICE_DT_INST_GET(0),
10391162
&crypto_cc23x0_dev_data,
10401163
NULL,
10411164
POST_KERNEL,

0 commit comments

Comments
 (0)