Skip to contentSkip to conversation

mmc: Tinification of the mmc code

PATCH New Marek Vasut 2 participants 10 messages May 26, 2016 – Oct 28, 2016 MMC, SD and SDIO

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mmc: Tinification of the mmc code

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
 common/spl/spl_mmc.c |  4 ++++
 drivers/mmc/Makefile |  2 ++
 drivers/mmc/mmc.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h        |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)
common/spl/spl_mmc.c +4 -0
index ae42221..51f0f24 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
 			if (part == 7)
 				part = 0;
 
+#ifdef CONFIG_MMC_TINY
+			err = mmc_switch_part(mmc, part);
+#else
 			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+#endif
 			if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 				puts("spl: mmc partition switch failed\n");
drivers/mmc/Makefile +2 -0
index 3da4817..4d986cb 100644
@@ -10,8 +10,10 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifndef CONFIG_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +58 -1

92 lines not on this page · raw message

include/mmc.h +1 -0
index a5c6573..08a59c2 100644
@@ -444,6 +444,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
 		      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
Signature · 1 line
2.7.0
#1 lore raw

PATCH 1/1 mmc: Tinification of the mmc code

Hi Marek,

Quoted 8 lines · Marek Vasut

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

Quoted 6 lines
---
 common/spl/spl_mmc.c |  4 ++++
 drivers/mmc/Makefile |  2 ++
 drivers/mmc/mmc.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h        |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)

Can CONFIG_MMC_TINY be a Kconfig? Also I suggest CONFIG_SPL_MMC_TINY.

common/spl/spl_mmc.c int spl_mmc_load_image(u32 boot_device) · line 303

Quoted 10 lines
common/spl/spl_mmc.c +1 -0
index ae42221..51f0f24 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
+#ifdef CONFIG_MMC_TINY

if (CONFIG_IS_ENABLED(MMC_TINY))

to avoid #ifdef

Quoted 136 lines
common/spl/spl_mmc.c +3 -0
+                       err = mmc_switch_part(mmc, part);
+#else
                        err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+#endif
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
drivers/mmc/Makefile +2 -0
index 3da4817..4d986cb 100644
@@ -10,8 +10,10 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifndef CONFIG_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +58 -1
index d687345..1f240ed 100644
@@ -21,6 +21,29 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#if defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static;
+struct mmc *find_mmc_device(int dev_num)
+{
+       return &mmc_static;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m = &mmc_static;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+       mmc_set_preinit(m, 1);
+#endif
+       if (m->preinit)
+               mmc_start_init(m);
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+#endif
+
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -238,7 +261,11 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
+#ifdef CONFIG_MMC_TINY
+       err = mmc_switch_part(mmc, block_dev->hwpart);
+#else
        err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+#endif
        if (err < 0)
                return 0;
 
@@ -568,7 +595,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
@@ -1585,6 +1612,34 @@ int mmc_unbind(struct udevice *dev)
        return 0;
 }
 
+#elif defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static = {
+       .dsr_imp                = 0,
+       .dsr                    = 0xffffffff,
+       .block_dev = {
+               .if_type        = IF_TYPE_MMC,
+               .removable      = 1,
+               .devnum         = 0,
+               .block_read     = mmc_bread,
+               .block_write    = mmc_bwrite,
+               .block_erase    = mmc_berase,
+               .part_type      = 0,
+       },
+};
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+       struct mmc *mmc = &mmc_static;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+}
 #else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
@@ -1834,8 +1889,10 @@ int mmc_initialize(bd_t *bis)
        initialized = 1;
 
 #ifndef CONFIG_BLK
+#ifndef CONFIG_MMC_TINY
        mmc_list_init();
 #endif
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
include/mmc.h +1 -1
index a5c6573..08a59c2 100644
@@ -444,6 +444,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
--
Quoted 2 lines

2.7.0

This is partially undoing the legacy block device work. How much does this patch save?

Regards,
Simon

#2 lore raw

PATCH 1/1 mmc: Tinification of the mmc code

Quoted 1 line · Simon Glass

Hi Marek,

Hi!

Quoted 16 lines · Marek Vasut
Quoted 8 lines

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

Quoted 6 lines
---
 common/spl/spl_mmc.c |  4 ++++
 drivers/mmc/Makefile |  2 ++
 drivers/mmc/mmc.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h        |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)
Quoted 1 line

Can CONFIG_MMC_TINY be a Kconfig? Also I suggest CONFIG_SPL_MMC_TINY.

It can, but how do I assure it's enabled only for SPL build ?

Quoted 8 lines
Quoted 8 lines
common/spl/spl_mmc.c +0 -0
index ae42221..51f0f24 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
Quoted 5 lines

common/spl/spl_mmc.c int spl_mmc_load_image(u32 boot_device) · line 303

Quoted 1 line
common/spl/spl_mmc.c +1 -0
+#ifdef CONFIG_MMC_TINY

if (CONFIG_IS_ENABLED(MMC_TINY))

to avoid #ifdef

The compiler complains about missing symbols blk_dselect_hwpart() and such, so I will opt for the ifdef .

Quoted 133 lines
Quoted 133 lines
common/spl/spl_mmc.c +3 -0
+                       err = mmc_switch_part(mmc, part);
+#else
                        err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+#endif
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
drivers/mmc/Makefile +2 -0
index 3da4817..4d986cb 100644
@@ -10,8 +10,10 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifndef CONFIG_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +58 -1
index d687345..1f240ed 100644
@@ -21,6 +21,29 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#if defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static;
+struct mmc *find_mmc_device(int dev_num)
+{
+       return &mmc_static;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m = &mmc_static;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+       mmc_set_preinit(m, 1);
+#endif
+       if (m->preinit)
+               mmc_start_init(m);
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+#endif
+
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -238,7 +261,11 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
+#ifdef CONFIG_MMC_TINY
+       err = mmc_switch_part(mmc, block_dev->hwpart);
+#else
        err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+#endif
        if (err < 0)
                return 0;
 
@@ -568,7 +595,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
@@ -1585,6 +1612,34 @@ int mmc_unbind(struct udevice *dev)
        return 0;
 }
 
+#elif defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static = {
+       .dsr_imp                = 0,
+       .dsr                    = 0xffffffff,
+       .block_dev = {
+               .if_type        = IF_TYPE_MMC,
+               .removable      = 1,
+               .devnum         = 0,
+               .block_read     = mmc_bread,
+               .block_write    = mmc_bwrite,
+               .block_erase    = mmc_berase,
+               .part_type      = 0,
+       },
+};
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+       struct mmc *mmc = &mmc_static;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+}
 #else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
@@ -1834,8 +1889,10 @@ int mmc_initialize(bd_t *bis)
        initialized = 1;
 
 #ifndef CONFIG_BLK
+#ifndef CONFIG_MMC_TINY
        mmc_list_init();
 #endif
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
include/mmc.h +1 -0
index a5c6573..08a59c2 100644
@@ -444,6 +444,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
Quoted 8 lines
Quoted 5 lines
include/mmc.h +0 -1
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
--

2.7.0

This is partially undoing the legacy block device work. How much does this patch save?

It does save enough to make my SPL fit on my device, which is a few kiB. I didn't measure it precisely because the block stuff starts requiring malloc support (which my SPL does not have) and pulls in more and more code which blows the SPL size.

Signature · 2 lines
Best regards,
Marek Vasut
#3 lore raw

PATCH 1/1 mmc: Tinification of the mmc code

Hi Marek,

Quoted 21 lines · Marek Vasut
Quoted 1 line · Simon Glass

Hi Marek,

Hi!

Quoted 16 lines · Marek Vasut
Quoted 14 lines

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
 common/spl/spl_mmc.c |  4 ++++
 drivers/mmc/Makefile |  2 ++
 drivers/mmc/mmc.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h        |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)
Quoted 3 lines
Quoted 1 line

Can CONFIG_MMC_TINY be a Kconfig? Also I suggest CONFIG_SPL_MMC_TINY.

It can, but how do I assure it's enabled only for SPL build ?

depends on SPL

and in the code:

#if CONFIG_IS_ENABLED(MMC_TINY)

will do it.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
common/spl/spl_mmc.c +0 -0
index ae42221..51f0f24 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
Quoted 8 lines
Quoted 5 lines

common/spl/spl_mmc.c int spl_mmc_load_image(u32 boot_device) · line 303

Quoted 1 line
common/spl/spl_mmc.c +1 -0
+#ifdef CONFIG_MMC_TINY

if (CONFIG_IS_ENABLED(MMC_TINY))

to avoid #ifdef

The compiler complains about missing symbols blk_dselect_hwpart() and such, so I will opt for the ifdef .

That's odd. It should not care about things which are not compiled in.

Quoted 143 lines
Quoted 134 lines
Quoted 134 lines
common/spl/spl_mmc.c +3 -0
+                       err = mmc_switch_part(mmc, part);
+#else
                        err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+#endif
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
drivers/mmc/Makefile +2 -0
index 3da4817..4d986cb 100644
@@ -10,8 +10,10 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifndef CONFIG_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +58 -1
index d687345..1f240ed 100644
@@ -21,6 +21,29 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#if defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static;
+struct mmc *find_mmc_device(int dev_num)
+{
+       return &mmc_static;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m = &mmc_static;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+       mmc_set_preinit(m, 1);
+#endif
+       if (m->preinit)
+               mmc_start_init(m);
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+#endif
+
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -238,7 +261,11 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
+#ifdef CONFIG_MMC_TINY
+       err = mmc_switch_part(mmc, block_dev->hwpart);
+#else
        err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+#endif
        if (err < 0)
                return 0;
 
@@ -568,7 +595,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
@@ -1585,6 +1612,34 @@ int mmc_unbind(struct udevice *dev)
        return 0;
 }
 
+#elif defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static = {
+       .dsr_imp                = 0,
+       .dsr                    = 0xffffffff,
+       .block_dev = {
+               .if_type        = IF_TYPE_MMC,
+               .removable      = 1,
+               .devnum         = 0,
+               .block_read     = mmc_bread,
+               .block_write    = mmc_bwrite,
+               .block_erase    = mmc_berase,
+               .part_type      = 0,
+       },
+};
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+       struct mmc *mmc = &mmc_static;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+}
 #else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
@@ -1834,8 +1889,10 @@ int mmc_initialize(bd_t *bis)
        initialized = 1;
 
 #ifndef CONFIG_BLK
+#ifndef CONFIG_MMC_TINY
        mmc_list_init();
 #endif
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
include/mmc.h +1 -0
index a5c6573..08a59c2 100644
@@ -444,6 +444,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
Quoted 8 lines
Quoted 5 lines
include/mmc.h +0 -1
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
--

2.7.0

This is partially undoing the legacy block device work. How much does this patch save?

Quoted 4 lines

It does save enough to make my SPL fit on my device, which is a few kiB. I didn't measure it precisely because the block stuff starts requiring malloc support (which my SPL does not have) and pulls in more and more code which blows the SPL size.

The legacy block support should not require malloc().

Can you give me instructions on how to try all this (perhaps point me to a tree?). I'd like to dig into it a little.

Regards,
Simon

#4 lore raw

PATCH v2 1/1 mmc: Tinification of the mmc code

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
V2: Switch the MMC_TINY option to Kconfig

---
 common/spl/spl_mmc.c |  6 +++++-
 drivers/mmc/Kconfig  | 16 ++++++++++++++
 drivers/mmc/Makefile |  6 ++++++
 drivers/mmc/mmc.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h        |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)
common/spl/spl_mmc.c +5 -1
index dcfd842..6508b3e 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
 			if (part == 7)
 				part = 0;
 
-			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+			if (CONFIG_IS_ENABLED(MMC_TINY))
+				err = mmc_switch_part(mmc, part);
+			else
+				err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+
 			if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 				puts("spl: mmc partition switch failed\n");
drivers/mmc/Kconfig +16 -0
index c80efc3..365057b 100644
@@ -16,6 +16,22 @@ config DM_MMC
 	  appear as block devices in U-Boot and can support filesystems such
 	  as EXT4 and FAT.
 
+config SPL_MMC_TINY
+	bool "Tiny MMC framework in SPL"
+	default n
+	help
+	  Enable MMC framework tinification support. This option is useful if
+	  if your SPL is extremely size constrained. Heed the warning, enable
+	  this option if and only if you know exactly what you are doing, if
+	  you are reading this help text, you most likely have no idea :-)
+
+	  The MMC framework is reduced to bare minimum to be useful. No malloc
+	  support is needed for the MMC framework operation with this option
+	  enabled. The framework supports exactly one MMC device and exactly
+	  one MMC driver. The MMC driver can be adjusted to avoid any malloc
+	  operations too, which can remove the need for malloc support in SPL
+	  and thus further reduce footprint.
+
 config MSM_SDHCI
 	bool "Qualcomm SDHCI controller"
 	depends on DM_MMC
drivers/mmc/Makefile +6 -0
index 3da4817..89578d2 100644
@@ -10,8 +10,14 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifdef CONFIG_SPL_BUILD
+ifndef CONFIG_SPL_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+else
+obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
+endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +59 -2

93 lines not on this page · raw message

include/mmc.h +1 -0
index 7fdfc32..3f6f9d2 100644
@@ -443,6 +443,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
 		      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
Signature · 1 line
2.7.0
#5 lore raw

PATCH v2 1/1 mmc: Tinification of the mmc code

Hi Marek,

Quoted 10 lines · Marek Vasut

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
V2: Switch the MMC_TINY option to Kconfig

Quoted 7 lines
---
 common/spl/spl_mmc.c |  6 +++++-
 drivers/mmc/Kconfig  | 16 ++++++++++++++
 drivers/mmc/Makefile |  6 ++++++
 drivers/mmc/mmc.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h        |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)

What's the status of these patches? Can they run with DM and CONFIG_BLK?

Regards,
Simon

#6 lore raw

PATCH v2 1/1 mmc: Tinification of the mmc code

Quoted 21 lines · Simon Glass

Hi Marek,

Quoted 10 lines · Marek Vasut

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
V2: Switch the MMC_TINY option to Kconfig

Quoted 7 lines
---
 common/spl/spl_mmc.c |  6 +++++-
 drivers/mmc/Kconfig  | 16 ++++++++++++++
 drivers/mmc/Makefile |  6 ++++++
 drivers/mmc/mmc.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h        |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)
Quoted 1 line

What's the status of these patches? Can they run with DM and CONFIG_BLK?

Probably broken due to the changes in the MMC subsys. I have a rebased version, but I didn't test it on the hardware itself. If you want to test them, I can send you the patch(es).

Signature · 2 lines
Best regards,
Marek Vasut
#7 lore raw

PATCH v2 1/1 mmc: Tinification of the mmc code

H iMarek,

Quoted 22 lines · Marek Vasut
Quoted 21 lines · Simon Glass

Hi Marek,

Quoted 17 lines · Marek Vasut

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
V2: Switch the MMC_TINY option to Kconfig

---
 common/spl/spl_mmc.c |  6 +++++-
 drivers/mmc/Kconfig  | 16 ++++++++++++++
 drivers/mmc/Makefile |  6 ++++++
 drivers/mmc/mmc.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h        |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)
Quoted 5 lines
Quoted 1 line

What's the status of these patches? Can they run with DM and CONFIG_BLK?

Probably broken due to the changes in the MMC subsys. I have a rebased version, but I didn't test it on the hardware itself. If you want to test them, I can send you the patch(es).

Yes I can do that - can you push them to a tree somewhere?

Regards,
Simon

#8 lore raw

PATCH v2 1/1 mmc: Tinification of the mmc code

Quoted 1 line · Simon Glass

H iMarek,

Hi,

Quoted 23 lines · Marek Vasut
Quoted 22 lines · Simon Glass
Quoted 21 lines

Hi Marek,

Quoted 17 lines · Marek Vasut

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
V2: Switch the MMC_TINY option to Kconfig

---
 common/spl/spl_mmc.c |  6 +++++-
 drivers/mmc/Kconfig  | 16 ++++++++++++++
 drivers/mmc/Makefile |  6 ++++++
 drivers/mmc/mmc.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h        |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

What's the status of these patches? Can they run with DM and CONFIG_BLK?

Probably broken due to the changes in the MMC subsys. I have a rebased version, but I didn't test it on the hardware itself. If you want to test them, I can send you the patch(es).

Yes I can do that - can you push them to a tree somewhere?

I forwarded you the tarball.

Signature · 2 lines
Best regards,
Marek Vasut
#9 lore raw

PATCH 1/1 mmc: Tinification of the mmc code

In reply to Simon Glass
Quoted 1 line · Simon Glass

Hi Marek,

Hi,

Quoted 26 lines · Marek Vasut
Quoted 21 lines · Simon Glass
Quoted 1 line

Hi Marek,

Hi!

Quoted 16 lines · Marek Vasut
Quoted 14 lines

Add new configuration option CONFIG_MMC_TINY which strips away all memory allocation within the MMC code and code for handling multiple cards. This allows extremely space-constrained SPL code use the MMC framework.

---
 common/spl/spl_mmc.c |  4 ++++
 drivers/mmc/Makefile |  2 ++
 drivers/mmc/mmc.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h        |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)
Quoted 3 lines
Quoted 1 line

Can CONFIG_MMC_TINY be a Kconfig? Also I suggest CONFIG_SPL_MMC_TINY.

It can, but how do I assure it's enabled only for SPL build ?

Quoted 7 lines

depends on SPL

and in the code:

#if CONFIG_IS_ENABLED(MMC_TINY)

will do it.

Ah right, thanks.

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

common/spl/spl_mmc.c int spl_mmc_load_image(u32 boot_device) · line 303

Quoted 9 lines
common/spl/spl_mmc.c +1 -0
index ae42221..51f0f24 100644
@@ -300,7 +300,11 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
+#ifdef CONFIG_MMC_TINY

if (CONFIG_IS_ENABLED(MMC_TINY))

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

to avoid #ifdef

The compiler complains about missing symbols blk_dselect_hwpart() and such, so I will opt for the ifdef .

That's odd. It should not care about things which are not compiled in.

Must've been some oddity indeed.

Quoted 142 lines
Quoted 142 lines
Quoted 141 lines
Quoted 136 lines
common/spl/spl_mmc.c +3 -0
+                       err = mmc_switch_part(mmc, part);
+#else
                        err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+#endif
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
drivers/mmc/Makefile +2 -0
index 3da4817..4d986cb 100644
@@ -10,8 +10,10 @@ obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
 endif
 
 ifndef CONFIG_BLK
+ifndef CONFIG_MMC_TINY
 obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
 endif
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
drivers/mmc/mmc.c +58 -1
index d687345..1f240ed 100644
@@ -21,6 +21,29 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#if defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static;
+struct mmc *find_mmc_device(int dev_num)
+{
+       return &mmc_static;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m = &mmc_static;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+       mmc_set_preinit(m, 1);
+#endif
+       if (m->preinit)
+               mmc_start_init(m);
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+#endif
+
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -238,7 +261,11 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
+#ifdef CONFIG_MMC_TINY
+       err = mmc_switch_part(mmc, block_dev->hwpart);
+#else
        err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+#endif
        if (err < 0)
                return 0;
 
@@ -568,7 +595,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
@@ -1585,6 +1612,34 @@ int mmc_unbind(struct udevice *dev)
        return 0;
 }
 
+#elif defined(CONFIG_MMC_TINY)
+static struct mmc mmc_static = {
+       .dsr_imp                = 0,
+       .dsr                    = 0xffffffff,
+       .block_dev = {
+               .if_type        = IF_TYPE_MMC,
+               .removable      = 1,
+               .devnum         = 0,
+               .block_read     = mmc_bread,
+               .block_write    = mmc_bwrite,
+               .block_erase    = mmc_berase,
+               .part_type      = 0,
+       },
+};
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+       struct mmc *mmc = &mmc_static;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+}
 #else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
@@ -1834,8 +1889,10 @@ int mmc_initialize(bd_t *bis)
        initialized = 1;
 
 #ifndef CONFIG_BLK
+#ifndef CONFIG_MMC_TINY
        mmc_list_init();
 #endif
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
include/mmc.h +1 -1
index a5c6573..08a59c2 100644
@@ -444,6 +444,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
--
Quoted 2 lines

2.7.0

This is partially undoing the legacy block device work. How much does this patch save?

Quoted 6 lines
Quoted 4 lines

It does save enough to make my SPL fit on my device, which is a few kiB. I didn't measure it precisely because the block stuff starts requiring malloc support (which my SPL does not have) and pulls in more and more code which blows the SPL size.

The legacy block support should not require malloc().

But it does require convoluted list handling, which takes a lot of space.

Quoted 2 lines

Can you give me instructions on how to try all this (perhaps point me to a tree?). I'd like to dig into it a little.

Sent off-list.

Signature · 2 lines
Best regards,
Marek Vasut