Skip to content

mcux-sdk: edma: support memory offset for different master and correct ELINKNO #528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include <stdbool.h>

#include "fsl_edma_rev2.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a short description for this commit explaining what is the issue this is trying to tackle?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, have updated

#if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
#include "fsl_memory.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind making this e separate commit with a more detailed description? I'd be interested in learning more about this.

is this related to the fact that DTCM is mapped at different addresses for M7 and EDMA and thus we require a translation? if so, please mention this in the commit description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, for examples In imx95, DTCM has different memory maps for M33 or M7core, which are defined in modules/hal/nxp/mcux/mcux-sdk/devices/MIMX9596, and other devices.
image

#endif

#define EDMA_READ(base, access)\
((access) == kEDMA_RegAccess16 ?\
Expand Down Expand Up @@ -169,6 +172,39 @@ static uint32_t EDMA_ConvertTransferWidth(uint32_t width)
return 0;
}

status_t EDMA_SetChannelLink(edma_config_t *cfg, int channel, edma_channel_link_type_t type, uint32_t linkedChannel)
{
uint32_t mp_csr;
/* setting global channel linking control */
mp_csr = EDMA_MPRegRead(cfg, EDMA_MP_CS) | EDMA_MP_CS_GCLC_MASK;
EDMA_MPRegWrite(cfg, EDMA_MP_CS, mp_csr);
if (type == kEDMA_MinorLink)
{
uint16_t biter, citer;
biter = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_BITER);
citer = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_CITER);
biter |= EDMA_BITER_ELINKYES_ELINK_MASK | EDMA_BITER_ELINKYES_LINKCH(linkedChannel);
citer |= EDMA_CITER_ELINKYES_ELINK_MASK | EDMA_CITER_ELINKYES_LINKCH(linkedChannel);
EDMA_ChannelRegWrite(cfg, channel, EDMA_TCD_CITER, citer);
EDMA_ChannelRegWrite(cfg, channel, EDMA_TCD_BITER, biter);
}
else if(type == kEDMA_MajorLink)
{
uint16_t csr;
csr = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_CSR);
csr |= EDMA_CSR_MAJORELINK_MASK | EDMA_CSR_MAJORLINKCH(linkedChannel);
EDMA_ChannelRegUpdate(cfg, channel, EDMA_TCD_CSR, EDMA_TCD_CSR_MAJORELINK_MASk, 0);
}
else
{
/* disable global channel linking control if no linked channel */
mp_csr = EDMA_MPRegRead(cfg, EDMA_MP_CS) & (~EDMA_MP_CS_GCLC_MASK);
EDMA_MPRegWrite(cfg, EDMA_MP_CS, mp_csr);
}

return kStatus_Success;
}

status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel,
uint32_t saddr, uint32_t daddr,
uint32_t ssize, uint32_t dsize,
Expand Down Expand Up @@ -237,6 +273,11 @@ status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel,
break;
}

#if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
saddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(saddr), kMEMORY_Local2DMA);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be useful to add a comment here stating that translation will only be performed if saddr/daddr are from DTCM

daddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(daddr), kMEMORY_Local2DMA);
#endif

/* notes:
* 1) SOFF and DOFF are currently set to SSIZE and DSIZE.
* 2) channel linking is not currently supported.
Expand Down
24 changes: 23 additions & 1 deletion mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ extern "C" {
#define EDMA_TCD_ATTR_DSIZE(x) ((x) & EDMA_TCD_ATTR_SSIZE_DSIZE_MASK)
#define EDMA_TCD_ATTR_SSIZE(x) (((x) & EDMA_TCD_ATTR_SSIZE_DSIZE_MASK) << 8)

#define EDMA_TCD_CITER_ELINKNO_MASK 0xf
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thx! mind also doing this change for EDMA_TCD_BITER_ELINKNO_MASK?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, have updated

#define EDMA_TCD_CITER_ELINKNO_MASK 0x7fff
#define EDMA_TCD_CITER_ELINKNO(x) ((x) & EDMA_TCD_CITER_ELINKNO_MASK)

#define EDMA_TCD_BITER_ELINKNO_MASK 0xf
Expand All @@ -83,21 +83,34 @@ extern "C" {
#define EDMA_TCD_NBYTES_MLOFFNO_MASK 0x3fffffff
#define EDMA_TCD_NBYTES_MLOFFNO(x) ((x) & EDMA_TCD_NBYTES_MLOFFNO_MASK)

#define EDMA_TCD_CSR_MAJORELINK_MASk EDMA_BIT(5)
#define EDMA_TCD_CSR_INTHALF_MASK EDMA_BIT(2)
#define EDMA_TCD_CSR_INTMAJOR_MASK EDMA_BIT(1)
#define EDMA_TCD_CSR_START_MASK EDMA_BIT(0)

#define EDMA_TCD_CH_CSR_ACTIVE_MASK EDMA_BIT(31)
#define EDMA_TCD_CH_CSR_DONE_MASK EDMA_BIT(30)
#define EDMA_TCD_CH_CSR_ERQ_MASK EDMA_BIT(0)

#define EDMA_TCD_CH_INT_MASK BIT(1)

#define EDMA_CSR_MAJORELINK_MASK EDMA_BIT(5)
#define EDMA_CITER_ELINKYES_LINKCH_MASK (0x3E00U)
#define EDMA_BITER_ELINKYES_LINKCH_MASK (0x3E00U)
#define EDMA_BITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U))
#define EDMA_CITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U))
#define EDMA_BITER_ELINKYES_ELINK_MASK EDMA_BIT(15)
#define EDMA_CITER_ELINKYES_ELINK_MASK EDMA_BIT(15)
#define EDMA_CSR_MAJORLINKCH_MASK (0x1F00U)
#define EDMA_CSR_MAJORLINKCH(x) (((uint16_t)(((uint16_t)(x)) << (8U))) & (0x1F00U))

/* EDMA registers */
/* common MP-related registers */
#define EDMA_MP_CS EDMA_REGISTER_MAKE(EDMA_MP_CS_INDEX, kEDMA_RegAccess32)
#define EDMA_MP_ES EDMA_REGISTER_MAKE(EDMA_MP_ES_INDEX, kEDMA_RegAccess32)
#define EDMA_MP_INT EDMA_REGISTER_MAKE(EDMA_MP_INT_INDEX, kEDMA_RegAccess32)
#define EDMA_MP_HRS EDMA_REGISTER_MAKE(EDMA_MP_HRS_INDEX, kEDMA_RegAccess32)
#define EDMA_MP_CS_GCLC_MASK EDMA_BIT(6)
/* TODO: access requires validation */
#define EDMA_MP_CH_GRPRI EDMA_REGISTER_MAKE(EDMA_MP_CH_GRPRI_INDEX, kEDMA_RegAccess32)
/* common TCD-related registers */
Expand Down Expand Up @@ -159,6 +172,14 @@ enum _edma_transfer_type {
kEDMA_TransferTypeP2M, /* Peripheral to memory transfer */
};

/*! @brief Channel link type */
typedef enum _edma_channel_link_type
{
kEDMA_LinkNone = 0x0U, /*!< No channel link */
kEDMA_MinorLink, /*!< Channel link after each minor loop */
kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */
}edma_channel_link_type_t;

typedef struct _edma_config {
/* EDMA base address. Should be overwritten by user if working with virtual
* addresses.
Expand Down Expand Up @@ -328,3 +349,4 @@ status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel,
}
#endif
#endif /* _FSL_EDMA_REV2_H_ */