2929
3030LOG_MODULE_REGISTER (dma_mcux_lpc , CONFIG_DMA_LOG_LEVEL );
3131
32+ #if CONFIG_PM_DEVICE
33+ /*
34+ * Data structures to backup DMA registers when the
35+ * register content lost in low power modes.
36+ */
37+ struct dma_backup_reg {
38+ /*
39+ * Backup the control registers.
40+ * Don't need to backup CTRL and SRAMBASE, they
41+ * are configured in function DMA_Init.
42+ */
43+ uint32_t enableset ; /* Register ENABLESET */
44+ uint32_t intenset ; /* Register INTENSET */
45+ };
46+
47+ struct dma_ch_backup_reg {
48+ /* Don't need to backup status register CTLSTAT. */
49+ uint32_t cfg ; /* Register CFG */
50+ uint32_t xfercfg ; /* Register XFERCFG */
51+ };
52+ #endif /* CONFIG_PM_DEVICE */
53+
3254struct dma_mcux_lpc_config {
3355 DMA_Type * base ;
3456 uint32_t otrig_base_address ;
@@ -54,6 +76,9 @@ struct channel_data {
5476 uint8_t num_of_descriptors ;
5577 bool descriptors_queued ;
5678 bool busy ;
79+ #if CONFIG_PM_DEVICE
80+ struct dma_ch_backup_reg backup_reg ;
81+ #endif /* CONFIG_PM_DEVICE */
5782};
5883
5984struct dma_otrig {
@@ -68,6 +93,9 @@ struct dma_mcux_lpc_dma_data {
6893 struct dma_otrig * otrig_array ;
6994 int8_t * channel_index ;
7095 uint8_t num_channels_used ;
96+ #if CONFIG_PM_DEVICE
97+ struct dma_backup_reg backup_reg ;
98+ #endif /* CONFIG_PM_DEVICE */
7199};
72100
73101struct k_spinlock configuring_otrigs ;
@@ -948,6 +976,69 @@ static int dma_mcux_lpc_get_attribute(const struct device *dev, uint32_t type, u
948976 return 0 ;
949977}
950978
979+ #if CONFIG_PM_DEVICE
980+ static void dma_mcux_lpc_backup_reg (const struct device * dev )
981+ {
982+ struct dma_mcux_lpc_dma_data * dma_data = dev -> data ;
983+ const struct dma_mcux_lpc_config * config = dev -> config ;
984+ struct channel_data * p_channel_data ;
985+ uint32_t virtual_channel ;
986+ DMA_Type * dma_base = DEV_BASE (dev );
987+
988+ dma_data -> backup_reg .enableset = dma_base -> COMMON [0 ].ENABLESET ;
989+ dma_data -> backup_reg .intenset = dma_base -> COMMON [0 ].INTENSET ;
990+
991+ /* Only backup the used channels */
992+ virtual_channel = 0 ;
993+ for (uint32_t channel = 0 ; channel < config -> num_of_channels ; channel ++ ) {
994+ if (dma_data -> channel_index [channel ] != -1 ) {
995+ p_channel_data = & dma_data -> channel_data [virtual_channel ];
996+
997+ p_channel_data -> backup_reg .xfercfg = dma_base -> CHANNEL [channel ].XFERCFG ;
998+ p_channel_data -> backup_reg .cfg = dma_base -> CHANNEL [channel ].CFG ;
999+ virtual_channel ++ ;
1000+ }
1001+ }
1002+ }
1003+
1004+ static void dma_mcux_lpc_restore_reg (const struct device * dev )
1005+ {
1006+ struct dma_mcux_lpc_dma_data * dma_data = dev -> data ;
1007+ const struct dma_mcux_lpc_config * config = dev -> config ;
1008+ struct channel_data * p_channel_data ;
1009+ uint32_t virtual_channel ;
1010+ DMA_Type * dma_base = DEV_BASE (dev );
1011+
1012+ dma_base -> COMMON [0 ].ENABLESET = dma_data -> backup_reg .enableset ;
1013+ dma_base -> COMMON [0 ].INTENSET = dma_data -> backup_reg .intenset ;
1014+
1015+ /* Only backup the used channels */
1016+ virtual_channel = 0 ;
1017+ for (uint32_t channel = 0 ; channel < config -> num_of_channels ; channel ++ ) {
1018+ if (dma_data -> channel_index [channel ] != -1 ) {
1019+ p_channel_data = & dma_data -> channel_data [virtual_channel ];
1020+
1021+ dma_base -> CHANNEL [channel ].XFERCFG = p_channel_data -> backup_reg .xfercfg ;
1022+ dma_base -> CHANNEL [channel ].CFG = p_channel_data -> backup_reg .cfg ;
1023+ virtual_channel ++ ;
1024+ }
1025+ }
1026+ }
1027+
1028+ #else /* !CONFIG_PM_DEVICE */
1029+
1030+ static inline static void dma_mcux_lpc_backup_reg (const struct device * dev )
1031+ {
1032+ ARG_UNUSED (dev );
1033+ }
1034+
1035+ static inline static void dma_mcux_lpc_restore_reg (const struct device * dev )
1036+ {
1037+ ARG_UNUSED (dev );
1038+ }
1039+
1040+ #endif /* CONFIG_PM_DEVICE */
1041+
9511042static int dma_mcux_lpc_pm_action (const struct device * dev , enum pm_device_action action )
9521043{
9531044 switch (action ) {
@@ -956,9 +1047,11 @@ static int dma_mcux_lpc_pm_action(const struct device *dev, enum pm_device_actio
9561047 case PM_DEVICE_ACTION_SUSPEND :
9571048 break ;
9581049 case PM_DEVICE_ACTION_TURN_OFF :
1050+ dma_mcux_lpc_backup_reg (dev );
9591051 break ;
9601052 case PM_DEVICE_ACTION_TURN_ON :
9611053 DMA_Init (DEV_BASE (dev ));
1054+ dma_mcux_lpc_restore_reg (dev );
9621055 break ;
9631056 default :
9641057 return - ENOTSUP ;
0 commit comments