@@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(crypto_cc23x0, CONFIG_CRYPTO_LOG_LEVEL);
14
14
#include <zephyr/drivers/dma.h>
15
15
#include <zephyr/irq.h>
16
16
#include <zephyr/kernel.h>
17
+ #include <zephyr/pm/device.h>
18
+ #include <zephyr/pm/device_runtime.h>
19
+ #include <zephyr/pm/policy.h>
17
20
#include <zephyr/sys/util.h>
18
21
19
22
#include <string.h>
@@ -80,6 +83,22 @@ struct crypto_cc23x0_data {
80
83
#endif
81
84
};
82
85
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
+
83
102
static void crypto_cc23x0_isr (const struct device * dev )
84
103
{
85
104
struct crypto_cc23x0_data * data = dev -> data ;
@@ -102,17 +121,42 @@ static void crypto_cc23x0_isr(const struct device *dev)
102
121
AESClearInterrupt (status );
103
122
}
104
123
105
- static void crypto_cc23x0_cleanup (const struct device * dev )
124
+ #ifdef CONFIG_CRYPTO_CC23X0_DMA
125
+ static int crypto_cc23x0_dma_enable (const struct device * dev , bool * dma_enabled )
106
126
{
127
+ const struct crypto_cc23x0_config * cfg = dev -> config ;
128
+ int ret ;
129
+
130
+ ret = pm_device_runtime_get (cfg -> dma_dev );
131
+ if (ret ) {
132
+ LOG_ERR ("Failed to resume DMA" );
133
+ * dma_enabled = false;
134
+ } else {
135
+ * dma_enabled = true;
136
+ }
137
+
138
+ return ret ;
139
+ }
140
+ #endif
141
+
107
142
#ifdef CONFIG_CRYPTO_CC23X0_DMA
143
+ static void crypto_cc23x0_cleanup_dma (const struct device * dev , bool dma_enabled )
144
+ {
108
145
const struct crypto_cc23x0_config * cfg = dev -> config ;
109
146
110
147
dma_stop (cfg -> dma_dev , cfg -> dma_channel_b );
111
148
dma_stop (cfg -> dma_dev , cfg -> dma_channel_a );
149
+
112
150
AESDisableDMA ();
113
- #else
114
- ARG_UNUSED (dev );
151
+
152
+ if (dma_enabled ) {
153
+ pm_device_runtime_put (cfg -> dma_dev );
154
+ }
155
+ }
115
156
#endif
157
+
158
+ static void crypto_cc23x0_cleanup_aes (void )
159
+ {
116
160
AESClearAUTOCFGTrigger ();
117
161
AESClearAUTOCFGBusHalt ();
118
162
AESClearTXTAndBUF ();
@@ -127,6 +171,7 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
127
171
#ifdef CONFIG_CRYPTO_CC23X0_DMA
128
172
uint32_t int_flags = AES_IMASK_CHBDONE ;
129
173
const struct crypto_cc23x0_config * cfg = dev -> config ;
174
+ bool dma_enabled = false;
130
175
131
176
struct dma_block_config block_cfg_cha = {
132
177
.source_address = (uint32_t )(pkt -> in_buf ),
@@ -186,6 +231,8 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
186
231
187
232
k_mutex_lock (& data -> device_mutex , K_FOREVER );
188
233
234
+ crypto_cc23x0_pm_policy_state_lock_get ();
235
+
189
236
/* Enable interrupts */
190
237
AESSetIMASK (int_flags );
191
238
@@ -198,6 +245,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
198
245
AES_AUTOCFG_TRGAES_WRBUF3S );
199
246
200
247
#ifdef CONFIG_CRYPTO_CC23X0_DMA
248
+ ret = crypto_cc23x0_dma_enable (dev , & dma_enabled );
249
+ if (ret ) {
250
+ goto cleanup ;
251
+ }
252
+
201
253
/* Setup the DMA for the AES engine */
202
254
AESSetupDMA (AES_DMA_ADRCHA_BUF0 |
203
255
AES_DMA_TRGCHA_AESSTART |
@@ -209,11 +261,13 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
209
261
210
262
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_a , & dma_cfg_cha );
211
263
if (ret ) {
264
+ LOG_ERR ("Failed to configure DMA CHA" );
212
265
goto cleanup ;
213
266
}
214
267
215
268
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_b , & dma_cfg_chb );
216
269
if (ret ) {
270
+ LOG_ERR ("Failed to configure DMA CHB" );
217
271
goto cleanup ;
218
272
}
219
273
@@ -265,7 +319,11 @@ static int crypto_cc23x0_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *
265
319
#endif
266
320
267
321
cleanup :
268
- crypto_cc23x0_cleanup (dev );
322
+ #ifdef CONFIG_CRYPTO_CC23X0_DMA
323
+ crypto_cc23x0_cleanup_dma (dev , dma_enabled );
324
+ #endif
325
+ crypto_cc23x0_cleanup_aes ();
326
+ crypto_cc23x0_pm_policy_state_lock_put ();
269
327
k_mutex_unlock (& data -> device_mutex );
270
328
pkt -> out_len = out_bytes_processed ;
271
329
@@ -284,6 +342,7 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
284
342
#ifdef CONFIG_CRYPTO_CC23X0_DMA
285
343
uint32_t int_flags = AES_IMASK_CHBDONE ;
286
344
const struct crypto_cc23x0_config * cfg = dev -> config ;
345
+ bool dma_enabled = false;
287
346
288
347
struct dma_block_config block_cfg_cha = {
289
348
.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
345
404
346
405
k_mutex_lock (& data -> device_mutex , K_FOREVER );
347
406
407
+ crypto_cc23x0_pm_policy_state_lock_get ();
408
+
348
409
/* Enable interrupts */
349
410
AESSetIMASK (int_flags );
350
411
@@ -359,6 +420,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
359
420
AES_AUTOCFG_CTRSIZE_CTR128 );
360
421
361
422
#ifdef CONFIG_CRYPTO_CC23X0_DMA
423
+ ret = crypto_cc23x0_dma_enable (dev , & dma_enabled );
424
+ if (ret ) {
425
+ goto cleanup ;
426
+ }
427
+
362
428
/* Setup the DMA for the AES engine */
363
429
AESSetupDMA (AES_DMA_ADRCHA_TXTX0 |
364
430
AES_DMA_TRGCHA_AESDONE |
@@ -367,11 +433,13 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
367
433
368
434
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_a , & dma_cfg_cha );
369
435
if (ret ) {
436
+ LOG_ERR ("Failed to configure DMA CHA" );
370
437
goto cleanup ;
371
438
}
372
439
373
440
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_b , & dma_cfg_chb );
374
441
if (ret ) {
442
+ LOG_ERR ("Failed to configure DMA CHB" );
375
443
goto cleanup ;
376
444
}
377
445
@@ -433,7 +501,11 @@ static int crypto_cc23x0_ctr(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uin
433
501
#endif
434
502
435
503
cleanup :
436
- crypto_cc23x0_cleanup (dev );
504
+ #ifdef CONFIG_CRYPTO_CC23X0_DMA
505
+ crypto_cc23x0_cleanup_dma (dev , dma_enabled );
506
+ #endif
507
+ crypto_cc23x0_cleanup_aes ();
508
+ crypto_cc23x0_pm_policy_state_lock_put ();
437
509
k_mutex_unlock (& data -> device_mutex );
438
510
pkt -> out_len = bytes_processed ;
439
511
@@ -451,6 +523,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
451
523
#ifdef CONFIG_CRYPTO_CC23X0_DMA
452
524
uint32_t int_flags = AES_IMASK_CHADONE ;
453
525
const struct crypto_cc23x0_config * cfg = dev -> config ;
526
+ bool dma_enabled = false;
454
527
455
528
struct dma_block_config block_cfg_cha = {
456
529
.source_address = (uint32_t )b0 ,
@@ -492,6 +565,8 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
492
565
493
566
k_mutex_lock (& data -> device_mutex , K_FOREVER );
494
567
568
+ crypto_cc23x0_pm_policy_state_lock_get ();
569
+
495
570
/* Enable interrupts */
496
571
AESSetIMASK (int_flags );
497
572
@@ -506,6 +581,13 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
506
581
/* Write zero'd IV */
507
582
AESWriteIV32 (iv );
508
583
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
+
509
591
if (b0 ) {
510
592
#ifdef CONFIG_CRYPTO_CC23X0_DMA
511
593
/* Setup the DMA for the AES engine */
@@ -514,6 +596,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
514
596
515
597
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_a , & dma_cfg_cha );
516
598
if (ret ) {
599
+ LOG_ERR ("Failed to configure DMA CHA" );
517
600
goto out ;
518
601
}
519
602
@@ -546,6 +629,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
546
629
547
630
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_a , & dma_cfg_cha );
548
631
if (ret ) {
632
+ LOG_ERR ("Failed to configure DMA CHA" );
549
633
goto out ;
550
634
}
551
635
@@ -578,6 +662,7 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
578
662
579
663
ret = dma_config (cfg -> dma_dev , cfg -> dma_channel_a , & dma_cfg_cha );
580
664
if (ret ) {
665
+ LOG_ERR ("Failed to configure DMA CHA" );
581
666
goto out ;
582
667
}
583
668
@@ -624,7 +709,11 @@ static int crypto_cc23x0_cmac(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
624
709
AESReadTag (pkt -> out_buf );
625
710
626
711
out :
627
- crypto_cc23x0_cleanup (dev );
712
+ #ifdef CONFIG_CRYPTO_CC23X0_DMA
713
+ crypto_cc23x0_cleanup_dma (dev , dma_enabled );
714
+ #endif
715
+ crypto_cc23x0_cleanup_aes ();
716
+ crypto_cc23x0_pm_policy_state_lock_put ();
628
717
k_mutex_unlock (& data -> device_mutex );
629
718
pkt -> out_len = bytes_processed ;
630
719
@@ -979,6 +1068,7 @@ static int crypto_cc23x0_init(const struct device *dev)
979
1068
{
980
1069
#ifdef CONFIG_CRYPTO_CC23X0_DMA
981
1070
const struct crypto_cc23x0_config * cfg = dev -> config ;
1071
+ int ret ;
982
1072
#endif
983
1073
struct crypto_cc23x0_data * data = dev -> data ;
984
1074
@@ -1000,6 +1090,12 @@ static int crypto_cc23x0_init(const struct device *dev)
1000
1090
if (!device_is_ready (cfg -> dma_dev )) {
1001
1091
return - ENODEV ;
1002
1092
}
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
+ }
1003
1099
#else
1004
1100
k_sem_init (& data -> aes_done , 0 , 1 );
1005
1101
#endif
@@ -1015,6 +1111,30 @@ static DEVICE_API(crypto, crypto_enc_funcs) = {
1015
1111
1016
1112
static struct crypto_cc23x0_data crypto_cc23x0_dev_data ;
1017
1113
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
+ default :
1128
+ ret = - ENOTSUP ;
1129
+ }
1130
+
1131
+ return ret ;
1132
+ }
1133
+
1134
+ #endif /* CONFIG_PM_DEVICE */
1135
+
1136
+ PM_DEVICE_DT_INST_DEFINE (0 , crypto_cc23x0_pm_action );
1137
+
1018
1138
#ifdef CONFIG_CRYPTO_CC23X0_DMA
1019
1139
static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = {
1020
1140
.dma_dev = DEVICE_DT_GET (TI_CC23X0_DT_INST_DMA_CTLR (0 , cha )),
@@ -1026,7 +1146,7 @@ static const struct crypto_cc23x0_config crypto_cc23x0_dev_config = {
1026
1146
1027
1147
DEVICE_DT_INST_DEFINE (0 ,
1028
1148
crypto_cc23x0_init ,
1029
- NULL ,
1149
+ PM_DEVICE_DT_INST_GET ( 0 ) ,
1030
1150
& crypto_cc23x0_dev_data ,
1031
1151
& crypto_cc23x0_dev_config ,
1032
1152
POST_KERNEL ,
@@ -1035,7 +1155,7 @@ DEVICE_DT_INST_DEFINE(0,
1035
1155
#else
1036
1156
DEVICE_DT_INST_DEFINE (0 ,
1037
1157
crypto_cc23x0_init ,
1038
- NULL ,
1158
+ PM_DEVICE_DT_INST_GET ( 0 ) ,
1039
1159
& crypto_cc23x0_dev_data ,
1040
1160
NULL ,
1041
1161
POST_KERNEL ,
0 commit comments