Skip to content

add SDHC support on imx93 #524

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions mcux/mcux-sdk/devices/MIMX9352/drivers/fsl_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,12 @@ typedef enum _clock_lpcg
kCLOCK_Pdm \
}

/*! @brief Clock ip name array for USDHC. */
#define USDHC_CLOCKS \
{ \
kCLOCK_IpInvalid, kCLOCK_Usdhc1, kCLOCK_Usdhc2, kCLOCK_Usdhc3 \
}

/*! @brief Clock ip name array for ENET QOS. */
#define ENETQOS_CLOCKS \
{ \
Expand Down
46 changes: 25 additions & 21 deletions mcux/mcux-sdk/drivers/usdhc/fsl_usdhc.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* Copyright 2016-2021, 2025 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
Expand Down Expand Up @@ -1222,11 +1222,11 @@ status_t USDHC_SetADMA1Descriptor(

uint32_t miniEntries, startEntries = 0UL,
maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma1_descriptor_t);
usdhc_adma1_descriptor_t *adma1EntryAddress = (usdhc_adma1_descriptor_t *)(uint32_t)(admaTable);
usdhc_adma1_descriptor_t *adma1EntryAddress = (usdhc_adma1_descriptor_t *)(uintptr_t)(admaTable);
Copy link
Member

Choose a reason for hiding this comment

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

does this change need to be directed now to mcux-sdk-ng folder?

@ZhaoxiangJin,

uint32_t i, dmaBufferLen = 0UL;
const uint32_t *data = dataBufferAddr;

if (((uint32_t)data % USDHC_ADMA1_ADDRESS_ALIGN) != 0UL)
if (((uintptr_t)data % USDHC_ADMA1_ADDRESS_ALIGN) != 0UL)
{
return kStatus_USDHC_DMADataAddrNotAlign;
}
Expand Down Expand Up @@ -1277,10 +1277,10 @@ status_t USDHC_SetADMA1Descriptor(

adma1EntryAddress[i] = (dmaBufferLen << USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT);
adma1EntryAddress[i] |= (uint32_t)kUSDHC_Adma1DescriptorTypeSetLength;
adma1EntryAddress[i + 1UL] = (uint32_t)(data);
adma1EntryAddress[i + 1UL] = (uintptr_t)(data);
adma1EntryAddress[i + 1UL] |=
(uint32_t)kUSDHC_Adma1DescriptorTypeTransfer | (uint32_t)kUSDHC_Adma1DescriptorInterrupFlag;
data = (uint32_t *)((uint32_t)data + dmaBufferLen);
data = (uint32_t *)((uintptr_t)data + dmaBufferLen);
dataBytes -= dmaBufferLen;
}
/* the end of the descriptor */
Expand Down Expand Up @@ -1309,11 +1309,11 @@ status_t USDHC_SetADMA2Descriptor(

uint32_t miniEntries, startEntries = 0UL,
maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma2_descriptor_t);
usdhc_adma2_descriptor_t *adma2EntryAddress = (usdhc_adma2_descriptor_t *)(uint32_t)(admaTable);
usdhc_adma2_descriptor_t *adma2EntryAddress = (usdhc_adma2_descriptor_t *)(uintptr_t)(admaTable);
uint32_t i, dmaBufferLen = 0UL;
const uint32_t *data = dataBufferAddr;

if (((uint32_t)data % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL)
if (((uintptr_t)data % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL)
{
return kStatus_USDHC_DMADataAddrNotAlign;
}
Expand Down Expand Up @@ -1371,13 +1371,17 @@ status_t USDHC_SetADMA2Descriptor(
}

/* Each descriptor for ADMA2 is 64-bit in length */
#if INTPTR_MAX == INT64_MAX
adma2EntryAddress[i].address = (uintptr_t)((dataBytes == 0UL) ? &s_usdhcBootDummy : data);
#else
adma2EntryAddress[i].address = (dataBytes == 0UL) ? &s_usdhcBootDummy : data;
#endif
adma2EntryAddress[i].attribute = (dmaBufferLen << USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT);
adma2EntryAddress[i].attribute |=
(dataBytes == 0UL) ?
0UL :
((uint32_t)kUSDHC_Adma2DescriptorTypeTransfer | (uint32_t)kUSDHC_Adma2DescriptorInterruptFlag);
data = (uint32_t *)((uint32_t)data + dmaBufferLen);
data = (uint32_t *)((uintptr_t)data + dmaBufferLen);

if (dataBytes != 0UL)
{
Expand Down Expand Up @@ -1420,7 +1424,7 @@ status_t USDHC_SetInternalDmaConfig(USDHC_Type *base,
assert(dmaConfig != NULL);
assert(dataAddr != NULL);
assert((NULL != dmaConfig->admaTable) &&
(((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uint32_t)dmaConfig->admaTable) == 0UL));
(((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uintptr_t)dmaConfig->admaTable) == 0UL));

#if FSL_FEATURE_USDHC_HAS_EXT_DMA
/* disable the external DMA if support */
Expand All @@ -1430,26 +1434,26 @@ status_t USDHC_SetInternalDmaConfig(USDHC_Type *base,
if (dmaConfig->dmaMode == kUSDHC_DmaModeSimple)
{
/* check DMA data buffer address align or not */
if (((uint32_t)dataAddr % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL)
if (((uintptr_t)dataAddr % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL)
{
return kStatus_USDHC_DMADataAddrNotAlign;
}
/* in simple DMA mode if use auto CMD23, address should load to ADMA addr,
and block count should load to DS_ADDR*/
if (enAutoCmd23)
{
base->ADMA_SYS_ADDR = USDHC_ADDR_CPU_2_DMA((uint32_t)dataAddr);
base->ADMA_SYS_ADDR = USDHC_ADDR_CPU_2_DMA((uintptr_t)dataAddr);
}
else
{
base->DS_ADDR = USDHC_ADDR_CPU_2_DMA((uint32_t)dataAddr);
base->DS_ADDR = USDHC_ADDR_CPU_2_DMA((uintptr_t)dataAddr);
}
}
else
{
/* When use ADMA, disable simple DMA */
base->DS_ADDR = 0UL;
base->ADMA_SYS_ADDR = USDHC_ADDR_CPU_2_DMA((uint32_t)(dmaConfig->admaTable));
base->ADMA_SYS_ADDR = USDHC_ADDR_CPU_2_DMA((uintptr_t)(dmaConfig->admaTable));
}

#if (defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
Expand Down Expand Up @@ -1485,14 +1489,14 @@ status_t USDHC_SetAdmaTableConfig(USDHC_Type *base,
{
assert(NULL != dmaConfig);
assert((NULL != dmaConfig->admaTable) &&
(((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uint32_t)dmaConfig->admaTable) == 0UL));
(((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uintptr_t)dmaConfig->admaTable) == 0UL));
assert(NULL != dataConfig);

status_t error = kStatus_Fail;
uint32_t bootDummyOffset =
dataConfig->dataType == (uint32_t)kUSDHC_TransferDataBootcontinous ? sizeof(uint32_t) : 0UL;
const uint32_t *data = (const uint32_t *)USDHC_ADDR_CPU_2_DMA((uint32_t)(
(uint32_t)((dataConfig->rxData == NULL) ? dataConfig->txData : dataConfig->rxData) + bootDummyOffset));
const uint32_t *data = (const uint32_t *)USDHC_ADDR_CPU_2_DMA((uintptr_t)(
(uintptr_t)((dataConfig->rxData == NULL) ? dataConfig->txData : dataConfig->rxData) + bootDummyOffset));
uint32_t blockSize = dataConfig->blockSize * dataConfig->blockCount - bootDummyOffset;

#if FSL_FEATURE_USDHC_HAS_EXT_DMA
Expand Down Expand Up @@ -1605,12 +1609,12 @@ status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig
if (data->txData != NULL)
{
/* clear the DCACHE */
DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount));
DCACHE_CleanByRange((uintptr_t)data->txData, (data->blockSize) * (data->blockCount));
}
else
{
/* clear the DCACHE */
DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount));
DCACHE_CleanInvalidateByRange((uintptr_t)data->rxData, (data->blockSize) * (data->blockCount));
}
}
#endif
Expand Down Expand Up @@ -1926,12 +1930,12 @@ status_t USDHC_TransferNonBlocking(USDHC_Type *base,
if (data->txData != NULL)
{
/* clear the DCACHE */
DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount));
DCACHE_CleanByRange((uintptr_t)data->txData, (data->blockSize) * (data->blockCount));
}
else
{
/* clear the DCACHE */
DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount));
DCACHE_CleanInvalidateByRange((uintptr_t)data->rxData, (data->blockSize) * (data->blockCount));
}
}
#endif
Expand Down Expand Up @@ -2345,7 +2349,7 @@ static void USDHC_TransferHandleData(USDHC_Type *base, usdhc_handle_t *handle, u
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
if (handle->data->rxData != NULL)
{
DCACHE_InvalidateByRange((uint32_t)(handle->data->rxData),
DCACHE_InvalidateByRange((uintptr_t)(handle->data->rxData),
(handle->data->blockSize) * (handle->data->blockCount));
}
#endif
Expand Down
10 changes: 7 additions & 3 deletions mcux/mcux-sdk/drivers/usdhc/fsl_usdhc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* Copyright 2016-2021, 2025 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
Expand All @@ -21,8 +21,8 @@

/*! @name Driver version */
/*@{*/
/*! @brief Driver version 2.8.4. */
#define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 8U, 4U))
/*! @brief Driver version 2.8.5. */
#define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 8U, 5U))
/*@}*/

/*! @brief Maximum block count can be set one time */
Expand Down Expand Up @@ -587,7 +587,11 @@ typedef uint32_t usdhc_adma1_descriptor_t;
typedef struct _usdhc_adma2_descriptor
{
uint32_t attribute; /*!< The control and status field. */
#if INTPTR_MAX == INT64_MAX
uint32_t address; /*!< The address field. */
#else
const uint32_t *address; /*!< The address field. */
#endif
} usdhc_adma2_descriptor_t;

/*!
Expand Down