[U-Boot] [PATCH v2 1/1] mmc: Add MMC support for stm32h7 Socs
Patrice CHOTARD
patrice.chotard at st.com
Thu Jul 20 07:08:19 UTC 2017
Hi Jaehoon
On 07/20/2017 06:22 AM, Jaehoon Chung wrote:
> Hi Patrice
>
> On 07/19/2017 09:20 PM, Patrice CHOTARD wrote:
>> Hi Jaehoon
>>
>> On 07/19/2017 12:11 PM, Jaehoon Chung wrote:
>>> Hi,
>>>
>>> On 07/19/2017 04:27 PM, patrice.chotard at st.com wrote:
>>>> From: Patrice Chotard <patrice.chotard at st.com>
>>>>
>>>> This patch adds SD/MMC support for STM32H7 SoCs.
>>>>
>>>> Here is an extraction of SDMMC main features, embedded in
>>>> STM32H7 SoCs.
>>>> The SD/MMC block include the following:
>>>> _ Full compliance with MultiMediaCard System Specification
>>>> Version 4.51. Card support for three different databus modes:
>>>> 1-bit (default), 4-bit and 8-bit.
>>>> _ Full compatibility with previous versions of MultiMediaCards
>>>> (backward compatibility).
>>>> _ Full compliance with SD memory card specifications version 4.1.
>>>> (SDR104 SDMMC_CK speed limited to maximum allowed IO speed,
>>>> SPI mode and UHS-II mode not supported).
>>>> _ Full compliance with SDIO card specification version 4.0.
>>>> Card support for two different databus modes: 1-bit (default)
>>>> and 4-bit. (SDR104 SDMMC_CK speed limited to maximum allowed IO
>>>> speed, SPI mode and UHS-II mode not supported).
>>>> _ Data transfer up to 208 Mbyte/s for the 8 bit mode.
>>>> (depending maximum allowed IO speed).
>>>> _ Data and command output enable signals to control external
>>>> bidirectional drivers.
>>>>
>>>> The current version of the SDMMC supports only one SD/SDIO/MMC card
>>>> at any one time and a stack of MMC Version 4.51 or previous.
>>>>
>>>> Signed-off-by: Christophe Kerello <christophe.kerello at st.com>
>>>> Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
>>>> ---
>>>>
>>>> v2: _ add .get_cd() callback support
>>>>
>>>> drivers/mmc/Kconfig | 8 +
>>>> drivers/mmc/Makefile | 1 +
>>>> drivers/mmc/stm32_sdmmc2.c | 619 +++++++++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 628 insertions(+)
>>>> create mode 100644 drivers/mmc/stm32_sdmmc2.c
>>>>
>>>> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
>>>> index 82b8d75..f2e4c26 100644
>>>> --- a/drivers/mmc/Kconfig
>>>> +++ b/drivers/mmc/Kconfig
>>>> @@ -377,6 +377,14 @@ config GENERIC_ATMEL_MCI
>>>> the SD Memory Card Specification V2.0, the SDIO V2.0 specification
>>>> and CE-ATA V1.1.
>>>>
>>>> +config STM32_SDMMC2
>>>
>>> Why add the SDMMC2? not SDMMC?
>>> Is there a special reason?
>>
>> It's simply the IP name
>>
>>>
>>>> + bool "STMicroelectronics STM32H7 SD/MMC Host Controller support"
>>>> + depends on DM_MMC && OF_CONTROL && DM_MMC_OPS
>>>> + help
>>>> + This selects support for the SD/MMC controller on STM32H7 SoCs.
>>>> + If you have a board based on such a SoC and with a SD/MMC slot,
>>>> + say Y or M here.
>>>> +
>>>> endif
>>>>
>>>> config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
>>>> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
>>>> index 2d781c3..2584663 100644
>>>> --- a/drivers/mmc/Makefile
>>>> +++ b/drivers/mmc/Makefile
>>>> @@ -43,6 +43,7 @@ obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
>>>> obj-$(CONFIG_MMC_SANDBOX) += sandbox_mmc.o
>>>> obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
>>>> obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
>>>> +obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
>>>>
>>>> # SDHCI
>>>> obj-$(CONFIG_MMC_SDHCI) += sdhci.o
>>>> diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
>>>> new file mode 100644
>>>> index 0000000..84f96e5
>>>> --- /dev/null
>>>> +++ b/drivers/mmc/stm32_sdmmc2.c
>>>> @@ -0,0 +1,619 @@
>>>> +/*
>>>> + * Copyright (c) 2017 STMicrelectronics
>>>> + *
>>>> + * SPDX-License-Identifier: GPL-2.0
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <clk.h>
>>>> +#include <dm.h>
>>>> +#include <fdtdec.h>
>>>> +#include <libfdt.h>
>>>> +#include <mmc.h>
>>>> +#include <reset.h>
>>>> +#include <asm/io.h>
>>>> +#include <asm/gpio.h>
>>>> +
>>>> +struct stm32_sdmmc2 {
>>>> + u32 power; /* SDMMC power control [0x00] */
>>>> + u32 clkcr; /* SDMMC clock control [0x04] */
>>>> + u32 arg; /* SDMMC argument [0x08] */
>>>> + u32 cmd; /* SDMMC command [0x0C] */
>>>> + u32 respcmd; /* SDMMC command response [0x10] */
>>>> + u32 resp1; /* SDMMC response 1 [0x14] */
>>>> + u32 resp2; /* SDMMC response 2 [0x18] */
>>>> + u32 resp3; /* SDMMC response 3 [0x1C] */
>>>> + u32 resp4; /* SDMMC response 4 [0x20] */
>>>> + u32 dtimer; /* SDMMC data timer [0x24] */
>>>> + u32 dlen; /* SDMMC data length [0x28] */
>>>> + u32 dctrl; /* SDMMC data control [0x2C] */
>>>> + u32 dcount; /* SDMMC data counter [0x30] */
>>>> + u32 sta; /* SDMMC status [0x34] */
>>>> + u32 icr; /* SDMMC interrupt clear [0x38] */
>>>> + u32 mask; /* SDMMC mask [0x3C] */
>>>> + u32 acktime; /* SDMMC Acknowledgment timer [0x40] */
>>>> + u32 reserved0[3]; /* Reserved, 0x44 - 0x4C - 0x4C */
>>>> + u32 idmactrl; /* SDMMC DMA control [0x50] */
>>>> + u32 idmabsize; /* SDMMC DMA buffer size [0x54] */
>>>> + u32 idmabase0; /* SDMMC DMA buffer 0 base address [0x58] */
>>>> + u32 idmabase1; /* SDMMC DMA buffer 1 base address [0x5C] */
>>>> + u32 reserved1[8]; /* Reserved, 0x4C-0x7C */
>>>> + u32 fifo; /* SDMMC data FIFO [0x80] */
>>>> +};
>>>
>>> This is for register offset, right?
>>
>> yes
>>
>>>
>>> I want to use the defined value..likes "#define SDMMC_POWER_CONTROL 0x00"
>>> (It's my preference.)
>>> I'm not sure but i have remembered that was difficult to debug.
>>
>> But on http://www.denx.de/wiki/U-Boot/CodingStyle, it's recommended to
>> use structures for I/O access, see "Use structures for I/O access " chapter.
>
> It's recommended, not mandatory.
> Already used the "define" style in mmc subsystem on u-boot.
> e.g) sdhci/dwmmc controller etc...
>
> I think it's no problem to use "define" style..
> In my opinion, it's more complex than define..
>
> For example, some controllers can be changed the register offset according to IP version.
> Then we needs to make new structure for it.
>
> And if someone calculated wrong offset, then it's possible that all register should be accessed to wrong offset.
> That's why it's my preference.
Ok i will convert this driver with registers offset.
>
>>
>>
>>>
>>>> +
>>>> +struct stm32_sdmmc2_host {
>>>> + struct stm32_sdmmc2 *base;
>>>> + struct mmc_config cfg;
>>>> + struct clk clk;
>>>> + struct reset_ctl reset_ctl;
>>>> + struct gpio_desc cd_gpio;
>>>> + u32 clk_reg_add;
>>>> + u32 pwr_reg_add;
>>>> +};
>>>> +
>
> [..snip..]
>
>>>> + cfg->host_caps |= MMC_MODE_4BIT;
>>>> + break;
>>>> + case 1:
>>>> + break;
>>>> + default:
>>>> + printf("%s: invalid \"bus-width\" property\n", __func__);
>>>> + ret = -ENOENT;
>>>> + goto reset_free;
>>>
>>> Maybe default value can be 1..
>>
>> Default value is already set to 1 in case the property "bus-width" is
>> not present in DT.
>>
>> The "default" case is just a protection in case of "bus-width" property
>> is set with other values than 1, 4 or 8.
>
> Then i think it can be just displayed wrong dt property value, not returned error
> and host controller and card can be worked with 1bit buswidth..
> how about? :)
Agree, i will fix it
Thanks
Patrice
>
> Best Regards,
> Jaehoon Chung
>
>>
>>>
>>>> + }
>>>> +
>>>> + mmc = mmc_create(cfg, host);
>>>> + if (!mmc) {
>>>> + ret = -ENOMEM;
>>>> + goto reset_free;
>>>> + }
>>>> +
>>>> + mmc->block_dev.removable = !dev_read_bool(dev, "non-removable");
>>>> + mmc->dev = dev;
>>>> + upriv->mmc = mmc;
>>>> +
>>>> + return 0;
>>>> +
>>>> +reset_free:
>>>> + reset_free(&host->reset_ctl);
>>>> +clk_disable:
>>>> + clk_disable(&host->clk);
>>>> +clk_free:
>>>> + clk_free(&host->clk);
>>>> +
>>>> + return ret;
>>>> +}
>>>> +
>>>> +static const struct udevice_id stm32_sdmmc2_ids[] = {
>>>> + { .compatible = "st,stm32-sdmmc2" },
>>>> + { }
>>>> +};
>>>> +
>>>> +U_BOOT_DRIVER(stm32_sdmmc2) = {
>>>> + .name = "stm32_sdmmc2",
>>>> + .id = UCLASS_MMC,
>>>> + .of_match = stm32_sdmmc2_ids,
>>>> + .ops = &stm32_sdmmc2_ops,
>>>> + .probe = stm32_sdmmc2_probe,
>>>> + .priv_auto_alloc_size = sizeof(struct stm32_sdmmc2_host),
>>>> +};
>>>>
>>>
>>
>>
>
More information about the U-Boot
mailing list