Skip to content

drivers: sdhc: split caps into standard and extra #91701

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 1 commit into
base: main
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 doc/releases/migration-guide-4.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,12 @@ Flash
* Separate the ``compatible`` from ``renesas,ra-nv-flash`` to :dtcompatible:`renesas,ra-nv-code-flash.yaml`
and :dtcompatible:`renesas,ra-nv-data-flash.yaml`.

SD Host Controller
==================

* Moved extra fields from :c:struct:`sdhc_host_caps` to :c:struct:`sdhc_host_props` as per the
`SD Host Controller Specification <https://www.sdcard.org/downloads/pls/pdf/?p=PartA2_SD%20Host_Controller_Simplified_Specification_Ver4.20.jpg>`_.


Stepper
=======
Expand Down
2 changes: 1 addition & 1 deletion drivers/sdhc/ifx_cat1_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ static int ifx_cat1_sdio_get_host_props(const struct device *dev, struct sdhc_ho
memset(props, 0, sizeof(*props));
props->f_max = IFX_CAT1_SDIO_F_MAX;
props->f_min = IFX_CAT1_SDIO_F_MIN;
props->host_caps.bus_4_bit_support = true;
props->bus_4_bit_support = true;
props->host_caps.high_spd_support = true;
props->host_caps.sdr50_support = true;
props->host_caps.sdio_async_interrupt_support = true;
Expand Down
6 changes: 3 additions & 3 deletions drivers/sdhc/imx_usdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ static void imx_usdhc_init_host_props(const struct device *dev)
props->host_caps.sdr104_support = (bool)(caps.flags & kUSDHC_SupportSDR104Flag);
props->host_caps.sdr50_support = (bool)(caps.flags & kUSDHC_SupportSDR50Flag);
props->host_caps.bus_8_bit_support = (bool)(caps.flags & kUSDHC_Support8BitFlag);
props->host_caps.bus_4_bit_support = (bool)(caps.flags & kUSDHC_Support4BitFlag);
props->host_caps.hs200_support = (bool)(cfg->mmc_hs200_1_8v);
props->host_caps.hs400_support = (bool)(cfg->mmc_hs400_1_8v);
props->bus_4_bit_support = (bool)(caps.flags & kUSDHC_Support4BitFlag);
props->hs200_support = (bool)(cfg->mmc_hs200_1_8v);
props->hs400_support = (bool)(cfg->mmc_hs400_1_8v);
}

/*
Expand Down
6 changes: 3 additions & 3 deletions drivers/sdhc/intel_emmc_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,9 +1168,9 @@ static int emmc_get_host_props(const struct device *dev, struct sdhc_host_props
props->host_caps.sdr104_support = (bool)(cap & BIT(33u));
props->host_caps.sdr50_support = (bool)(cap & BIT(32u));
props->host_caps.bus_8_bit_support = true;
props->host_caps.bus_4_bit_support = true;
props->host_caps.hs200_support = (bool)config->hs200_mode;
props->host_caps.hs400_support = (bool)config->hs400_mode;
props->bus_4_bit_support = true;
props->hs200_support = (bool)config->hs200_mode;
props->hs400_support = (bool)config->hs400_mode;

emmc->props = *props;

Expand Down
12 changes: 6 additions & 6 deletions drivers/sdhc/rcar_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ static int rcar_mmc_set_bus_width(const struct device *dev, struct sdhc_io *ios)
reg_width = RCAR_MMC_OPTION_WIDTH_1;
break;
case SDHC_BUS_WIDTH4BIT:
if (data->props.host_caps.bus_4_bit_support) {
if (data->props.bus_4_bit_support) {
reg_width = RCAR_MMC_OPTION_WIDTH_4;
} else {
LOG_ERR("SDHC I/O: 4-bits bus width isn't supported");
Expand Down Expand Up @@ -1331,7 +1331,7 @@ static int rcar_mmc_set_timings(const struct device *dev, struct sdhc_io *ios)
}
break;
case SDHC_TIMING_HS400:
if (!data->props.host_caps.hs400_support) {
if (!data->props.hs400_support) {
LOG_ERR("SDHC I/O: HS400 timing isn't supported");
return -ENOTSUP;
}
Expand All @@ -1347,7 +1347,7 @@ static int rcar_mmc_set_timings(const struct device *dev, struct sdhc_io *ios)
data->ddr_mode = 1;
break;
case SDHC_TIMING_HS200:
if (!data->props.host_caps.hs200_support) {
if (!data->props.hs200_support) {
LOG_ERR("SDHC I/O: HS200 timing isn't supported");
return -ENOTSUP;
}
Expand Down Expand Up @@ -1947,7 +1947,7 @@ static void rcar_mmc_init_host_props(const struct device *dev)
case SDHC_BUS_WIDTH8BIT:
host_caps->bus_8_bit_support = 1;
case SDHC_BUS_WIDTH4BIT:
host_caps->bus_4_bit_support = 1;
props->bus_4_bit_support = 1;
default:
break;
}
Expand All @@ -1958,9 +1958,9 @@ static void rcar_mmc_init_host_props(const struct device *dev)
host_caps->sdr50_support = cfg->uhs_support;
/* neither Linux nor U-boot support DDR50 mode, that's why we don't support it too */
host_caps->ddr50_support = 0;
host_caps->hs200_support = cfg->mmc_hs200_1_8v;
props->hs200_support = cfg->mmc_hs200_1_8v;
/* TODO: add support */
host_caps->hs400_support = 0;
props->hs400_support = 0;
#endif

host_caps->vol_330_support =
Expand Down
4 changes: 2 additions & 2 deletions drivers/sdhc/sdhc_ambiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ static int ambiq_sdio_get_host_props(const struct device *dev, struct sdhc_host_
props->host_caps.adma_2_support = true;
props->host_caps.sdio_async_interrupt_support = true;
props->host_caps.vol_180_support = true;
props->host_caps.bus_4_bit_support = true;
props->host_caps.bus_8_bit_support = true;
props->host_caps.high_spd_support = true;
props->host_caps.sdr50_support = true;
props->host_caps.sdr104_support = true;
props->host_caps.ddr50_support = true;
props->host_caps.hs200_support = true;
props->bus_4_bit_support = true;
props->hs200_support = true;
props->max_current_330 = 1020;
props->max_current_300 = 1020;
props->max_current_180 = 1020;
Expand Down
9 changes: 4 additions & 5 deletions drivers/sdhc/sdhc_esp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,11 +1444,10 @@ static DEVICE_API(sdhc, sdhc_api) = {
.ddr50_support = false, \
.sdr104_support = false, \
.sdr50_support = false, \
.bus_8_bit_support = false, \
.bus_4_bit_support = \
(DT_INST_PROP(n, bus_width) == 4) ? true : false, \
.hs200_support = false, \
.hs400_support = false}}}; \
.bus_8_bit_support = false}, \
.bus_4_bit_support = (DT_INST_PROP(n, bus_width) == 4) ? true : false, \
.hs200_support = false, \
.hs400_support = false}}; \
\
static struct sdhc_esp32_data sdhc_esp32_##n##_data = { \
.bus_width = SDMMC_SLOT_WIDTH_DEFAULT, \
Expand Down
6 changes: 3 additions & 3 deletions drivers/sdhc/sdhc_max32.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void sdhc_max32_init_props(const struct device *dev)
sdhc_data->props.host_caps.sd_base_clk = 0x00;
sdhc_data->props.host_caps.max_blk_len = 0b10;
sdhc_data->props.host_caps.bus_8_bit_support = false;
sdhc_data->props.host_caps.bus_4_bit_support = false;
sdhc_data->props.bus_4_bit_support = false;
sdhc_data->props.host_caps.adma_2_support = true;
sdhc_data->props.host_caps.high_spd_support = true;
sdhc_data->props.host_caps.sdma_support = true;
Expand All @@ -119,8 +119,8 @@ static void sdhc_max32_init_props(const struct device *dev)
sdhc_data->props.host_caps.clk_multiplier = 0;
sdhc_data->props.host_caps.adma3_support = false;
sdhc_data->props.host_caps.vdd2_180_support = false;
sdhc_data->props.host_caps.hs200_support = false;
sdhc_data->props.host_caps.hs400_support = false;
sdhc_data->props.hs200_support = false;
sdhc_data->props.hs400_support = false;
sdhc_data->props.power_delay = sdhc_config->power_delay_ms;
}

Expand Down
11 changes: 5 additions & 6 deletions drivers/sdhc/sdhc_renesas_ra.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,12 +713,11 @@ static DEVICE_API(sdhc, sdhc_api) = {
.ddr50_support = false, \
.sdr104_support = false, \
.sdr50_support = false, \
.bus_8_bit_support = false, \
.bus_4_bit_support = (DT_INST_PROP(index, bus_width) == 4) \
? true \
: false, \
.hs200_support = false, \
.hs400_support = false}}, \
.bus_8_bit_support = false}, \
.bus_4_bit_support = \
(DT_INST_PROP(index, bus_width) == 4) ? true : false, \
.hs200_support = false, \
.hs400_support = false}, \
RA_SDHI_EN(index), \
RA_SDMMC_DTC_STRUCT_INIT(index)}; \
\
Expand Down
6 changes: 3 additions & 3 deletions drivers/sdhc/xlnx_sdhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,14 +587,14 @@ static int xlnx_sdhc_host_props(const struct device *dev, struct sdhc_host_props
XLNX_SDHC_SLOT_TYPE_GET);
props->host_caps.bus_8_bit_support = XLNX_SDHC_GET_HOST_PROP_BIT(cap,
XLNX_SDHC_8BIT_SUPPORT);
props->host_caps.bus_4_bit_support = XLNX_SDHC_GET_HOST_PROP_BIT(cap,
props->bus_4_bit_support = XLNX_SDHC_GET_HOST_PROP_BIT(cap,
XLNX_SDHC_4BIT_SUPPORT);

if ((cap & CHECK_BITS(XLNX_SDHC_SDR400_SUPPORT)) != 0U) {
props->host_caps.hs400_support = (uint8_t)config->hs400_mode;
props->hs400_support = (uint8_t)config->hs400_mode;
dev_data->has_phy = true;
}
props->host_caps.hs200_support = (uint8_t)config->hs200_mode;
props->hs200_support = (uint8_t)config->hs200_mode;

dev_data->props = *props;

Expand Down
12 changes: 7 additions & 5 deletions include/zephyr/drivers/sdhc.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,16 @@ enum sd_voltage {
* @brief SD host controller capabilities
*
* SD host controller capability flags. These flags should be set by the SDHC
* driver, using the @ref sdhc_get_host_props api.
* driver, using the @ref sdhc_get_host_props api. These are packed to fit the capabilities register
* in the standard specification by the SD Association.
*/
struct sdhc_host_caps {
unsigned int timeout_clk_freq: 5; /**< Timeout clock frequency */
unsigned int timeout_clk_freq: 6; /**< Timeout clock frequency */
unsigned int _rsvd_6: 1; /**< Reserved */
unsigned int timeout_clk_unit: 1; /**< Timeout clock unit */
unsigned int sd_base_clk: 8; /**< SD base clock frequency */
unsigned int max_blk_len: 2; /**< Max block length */
unsigned int bus_8_bit_support: 1; /**< 8-bit Support for embedded device */
unsigned int bus_4_bit_support: 1; /**< 4 bit bus support */
unsigned int adma_2_support: 1; /**< ADMA2 support */
unsigned int _rsvd_20: 1; /**< Reserved */
unsigned int high_spd_support: 1; /**< High speed support */
Expand All @@ -189,15 +189,14 @@ struct sdhc_host_caps {
unsigned int drv_type_d_support: 1; /**< Driver type D support */
unsigned int _rsvd_39: 1; /**< Reserved */
unsigned int retune_timer_count: 4; /**< Timer count for re-tuning */
unsigned int _rsvd_44: 1; /**< Reserved */
unsigned int sdr50_needs_tuning: 1; /**< Use tuning for SDR50 */
unsigned int retuning_mode: 2; /**< Re-tuning mode */
unsigned int clk_multiplier: 8; /**< Clock multiplier */
unsigned int _rsvd_56: 3; /**< Reserved */
unsigned int adma3_support: 1; /**< ADMA3 support */
unsigned int vdd2_180_support: 1; /**< 1.8V VDD2 support */
unsigned int _rsvd_61: 3; /**< Reserved */
unsigned int hs200_support: 1; /**< HS200 support */
unsigned int hs400_support: 1; /**< HS400 support */
};

/**
Expand Down Expand Up @@ -230,6 +229,9 @@ struct sdhc_host_props {
uint32_t max_current_330; /*!< Max current (in mA) at 3.3V */
uint32_t max_current_300; /*!< Max current (in mA) at 3.0V */
uint32_t max_current_180; /*!< Max current (in mA) at 1.8V */
bool bus_4_bit_support; /**< 4 bit bus support */
bool hs200_support; /**< HS200 support */
bool hs400_support; /**< HS400 support */
bool is_spi; /*!< Is the host using SPI mode */
};

Expand Down
6 changes: 3 additions & 3 deletions subsys/sd/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ static int mmc_set_bus_width(struct sd_card *card)
if (card->host_props.host_caps.bus_8_bit_support && card->bus_width == 8) {
cmd.arg = MMC_SWITCH_8_BIT_BUS_ARG;
card->bus_io.bus_width = SDHC_BUS_WIDTH8BIT;
} else if (card->host_props.host_caps.bus_4_bit_support && card->bus_width >= 4) {
} else if (card->host_props.bus_4_bit_support && card->bus_width >= 4) {
cmd.arg = MMC_SWITCH_4_BIT_BUS_ARG;
card->bus_io.bus_width = SDHC_BUS_WIDTH4BIT;
} else {
Expand Down Expand Up @@ -454,7 +454,7 @@ static int mmc_set_timing(struct sd_card *card, struct mmc_ext_csd *ext)

/* Timing depends on EXT_CSD register information */
if ((ext->device_type.MMC_HS200_SDR_1200MV || ext->device_type.MMC_HS200_SDR_1800MV) &&
(card->host_props.host_caps.hs200_support) &&
(card->host_props.hs200_support) &&
(card->bus_io.signal_voltage == SD_VOL_1_8_V) &&
(card->bus_io.bus_width >= SDHC_BUS_WIDTH4BIT)) {
ret = mmc_set_hs_timing(card);
Expand Down Expand Up @@ -513,7 +513,7 @@ static int mmc_set_timing(struct sd_card *card, struct mmc_ext_csd *ext)

/* Switch to HS400 if applicable */
if ((ext->device_type.MMC_HS400_DDR_1200MV || ext->device_type.MMC_HS400_DDR_1800MV) &&
(card->host_props.host_caps.hs400_support) &&
(card->host_props.hs400_support) &&
(card->bus_io.bus_width == SDHC_BUS_WIDTH8BIT)) {
/* Switch back to regular HS timing */
ret = mmc_set_hs_timing(card);
Expand Down