diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index e382db763e5d..d19b0b658559 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -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 `_. + Stepper ======= diff --git a/drivers/sdhc/ifx_cat1_sdio.c b/drivers/sdhc/ifx_cat1_sdio.c index 4449b532f0b2..a69bef546909 100644 --- a/drivers/sdhc/ifx_cat1_sdio.c +++ b/drivers/sdhc/ifx_cat1_sdio.c @@ -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; diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index 0c4dbac14fcc..cd51557c79f9 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -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); } /* diff --git a/drivers/sdhc/intel_emmc_host.c b/drivers/sdhc/intel_emmc_host.c index 2ac32d82898e..ba0581367c2d 100644 --- a/drivers/sdhc/intel_emmc_host.c +++ b/drivers/sdhc/intel_emmc_host.c @@ -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; diff --git a/drivers/sdhc/rcar_mmc.c b/drivers/sdhc/rcar_mmc.c index b5677f23a104..257612871d8b 100644 --- a/drivers/sdhc/rcar_mmc.c +++ b/drivers/sdhc/rcar_mmc.c @@ -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"); @@ -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; } @@ -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; } @@ -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; } @@ -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 = diff --git a/drivers/sdhc/sdhc_ambiq.c b/drivers/sdhc/sdhc_ambiq.c index e32a1958a0e1..e9a1f7518dee 100644 --- a/drivers/sdhc/sdhc_ambiq.c +++ b/drivers/sdhc/sdhc_ambiq.c @@ -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; diff --git a/drivers/sdhc/sdhc_esp32.c b/drivers/sdhc/sdhc_esp32.c index 87c60796a5d0..91e7d6492b68 100644 --- a/drivers/sdhc/sdhc_esp32.c +++ b/drivers/sdhc/sdhc_esp32.c @@ -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, \ diff --git a/drivers/sdhc/sdhc_max32.c b/drivers/sdhc/sdhc_max32.c index 0bc8caa3233c..8609adfeec55 100644 --- a/drivers/sdhc/sdhc_max32.c +++ b/drivers/sdhc/sdhc_max32.c @@ -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; @@ -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; } diff --git a/drivers/sdhc/sdhc_renesas_ra.c b/drivers/sdhc/sdhc_renesas_ra.c index 786584ea3065..cd889be13600 100644 --- a/drivers/sdhc/sdhc_renesas_ra.c +++ b/drivers/sdhc/sdhc_renesas_ra.c @@ -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)}; \ \ diff --git a/drivers/sdhc/xlnx_sdhc.c b/drivers/sdhc/xlnx_sdhc.c index 4cc15cf1cfc6..6bdbb1871600 100644 --- a/drivers/sdhc/xlnx_sdhc.c +++ b/drivers/sdhc/xlnx_sdhc.c @@ -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; diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index 98f651cfeec0..b615f079abd5 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -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 */ @@ -189,6 +189,7 @@ 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 */ @@ -196,8 +197,6 @@ struct sdhc_host_caps { 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 */ }; /** @@ -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 */ }; diff --git a/subsys/sd/mmc.c b/subsys/sd/mmc.c index 02216d3700a5..4a062616dc45 100644 --- a/subsys/sd/mmc.c +++ b/subsys/sd/mmc.c @@ -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 { @@ -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); @@ -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);