mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
stm32mp: stm32prog: add MTD devices support
Add support of MTD device (DFU_MTD backend) for NOR, NAND or SPI-NAND target. Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
This commit is contained in:
parent
ffc405e63b
commit
eb845d6f8b
5 changed files with 117 additions and 7 deletions
|
@ -114,7 +114,9 @@ config CMD_STM32PROG
|
||||||
select DFU_VIRT
|
select DFU_VIRT
|
||||||
select PARTITION_TYPE_GUID
|
select PARTITION_TYPE_GUID
|
||||||
imply CMD_GPT if MMC
|
imply CMD_GPT if MMC
|
||||||
|
imply CMD_MTD if MTD
|
||||||
imply DFU_MMC if MMC
|
imply DFU_MMC if MMC
|
||||||
|
imply DFU_MTD if MTD
|
||||||
help
|
help
|
||||||
activate a specific command stm32prog for STM32MP soc family
|
activate a specific command stm32prog for STM32MP soc family
|
||||||
witch update the device with the tools STM32CubeProgrammer,
|
witch update the device with the tools STM32CubeProgrammer,
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
#include <dfu.h>
|
#include <dfu.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <mmc.h>
|
#include <mmc.h>
|
||||||
|
#include <part.h>
|
||||||
#include <dm/uclass.h>
|
#include <dm/uclass.h>
|
||||||
|
#include <jffs2/load_kernel.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/list_sort.h>
|
#include <linux/list_sort.h>
|
||||||
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
|
|
||||||
#include "stm32prog.h"
|
#include "stm32prog.h"
|
||||||
|
@ -65,6 +68,11 @@ enum stm32prog_col_t {
|
||||||
COL_NB_STM32
|
COL_NB_STM32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* partition handling routines : CONFIG_CMD_MTDPARTS */
|
||||||
|
int mtdparts_init(void);
|
||||||
|
int find_dev_and_part(const char *id, struct mtd_device **dev,
|
||||||
|
u8 *part_num, struct part_info **part);
|
||||||
|
|
||||||
char *stm32prog_get_error(struct stm32prog_data *data)
|
char *stm32prog_get_error(struct stm32prog_data *data)
|
||||||
{
|
{
|
||||||
static const char error_msg[] = "Unspecified";
|
static const char error_msg[] = "Unspecified";
|
||||||
|
@ -233,6 +241,15 @@ static int parse_ip(struct stm32prog_data *data,
|
||||||
} else if (!strncmp(p, "mmc", 3)) {
|
} else if (!strncmp(p, "mmc", 3)) {
|
||||||
part->target = STM32PROG_MMC;
|
part->target = STM32PROG_MMC;
|
||||||
len = 3;
|
len = 3;
|
||||||
|
} else if (!strncmp(p, "nor", 3)) {
|
||||||
|
part->target = STM32PROG_NOR;
|
||||||
|
len = 3;
|
||||||
|
} else if (!strncmp(p, "nand", 4)) {
|
||||||
|
part->target = STM32PROG_NAND;
|
||||||
|
len = 4;
|
||||||
|
} else if (!strncmp(p, "spi-nand", 8)) {
|
||||||
|
part->target = STM32PROG_SPI_NAND;
|
||||||
|
len = 8;
|
||||||
} else {
|
} else {
|
||||||
result = -EINVAL;
|
result = -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -475,11 +492,37 @@ static int __init part_cmp(void *priv, struct list_head *a, struct list_head *b)
|
||||||
return parta->addr > partb->addr ? 1 : -1;
|
return parta->addr > partb->addr ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_mtd_by_target(char *string, enum stm32prog_target target,
|
||||||
|
int dev_id)
|
||||||
|
{
|
||||||
|
const char *dev_str;
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
case STM32PROG_NOR:
|
||||||
|
dev_str = "nor";
|
||||||
|
break;
|
||||||
|
case STM32PROG_NAND:
|
||||||
|
dev_str = "nand";
|
||||||
|
break;
|
||||||
|
case STM32PROG_SPI_NAND:
|
||||||
|
dev_str = "spi-nand";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_str = "invalid";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprintf(string, "%s%d", dev_str, dev_id);
|
||||||
|
}
|
||||||
|
|
||||||
static int init_device(struct stm32prog_data *data,
|
static int init_device(struct stm32prog_data *data,
|
||||||
struct stm32prog_dev_t *dev)
|
struct stm32prog_dev_t *dev)
|
||||||
{
|
{
|
||||||
struct mmc *mmc = NULL;
|
struct mmc *mmc = NULL;
|
||||||
struct blk_desc *block_dev = NULL;
|
struct blk_desc *block_dev = NULL;
|
||||||
|
#ifdef CONFIG_MTD
|
||||||
|
struct mtd_info *mtd = NULL;
|
||||||
|
char mtd_id[16];
|
||||||
|
#endif
|
||||||
int part_id;
|
int part_id;
|
||||||
int ret;
|
int ret;
|
||||||
u64 first_addr = 0, last_addr = 0;
|
u64 first_addr = 0, last_addr = 0;
|
||||||
|
@ -521,6 +564,29 @@ static int init_device(struct stm32prog_data *data,
|
||||||
first_addr, last_addr);
|
first_addr, last_addr);
|
||||||
pr_debug(" full_update = %d\n", dev->full_update);
|
pr_debug(" full_update = %d\n", dev->full_update);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_MTD
|
||||||
|
case STM32PROG_NOR:
|
||||||
|
case STM32PROG_NAND:
|
||||||
|
case STM32PROG_SPI_NAND:
|
||||||
|
get_mtd_by_target(mtd_id, dev->target, dev->dev_id);
|
||||||
|
pr_debug("%s\n", mtd_id);
|
||||||
|
|
||||||
|
mtdparts_init();
|
||||||
|
mtd = get_mtd_device_nm(mtd_id);
|
||||||
|
if (IS_ERR(mtd)) {
|
||||||
|
stm32prog_err("MTD device %s not found", mtd_id);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
first_addr = 0;
|
||||||
|
last_addr = mtd->size;
|
||||||
|
dev->erase_size = mtd->erasesize;
|
||||||
|
pr_debug("MTD device %s: size=%lld erasesize=%d\n",
|
||||||
|
mtd_id, mtd->size, mtd->erasesize);
|
||||||
|
pr_debug(" available address = 0x%llx..0x%llx\n",
|
||||||
|
first_addr, last_addr);
|
||||||
|
dev->mtd = mtd;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
stm32prog_err("unknown device type = %d", dev->target);
|
stm32prog_err("unknown device type = %d", dev->target);
|
||||||
|
@ -637,6 +703,29 @@ static int init_device(struct stm32prog_data *data,
|
||||||
part_found = true;
|
part_found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD
|
||||||
|
if (mtd) {
|
||||||
|
char mtd_part_id[32];
|
||||||
|
struct part_info *mtd_part;
|
||||||
|
struct mtd_device *mtd_dev;
|
||||||
|
u8 part_num;
|
||||||
|
|
||||||
|
sprintf(mtd_part_id, "%s,%d", mtd_id,
|
||||||
|
part->part_id - 1);
|
||||||
|
ret = find_dev_and_part(mtd_part_id, &mtd_dev,
|
||||||
|
&part_num, &mtd_part);
|
||||||
|
if (ret != 0) {
|
||||||
|
stm32prog_err("%s (0x%x): Invalid MTD partition %s",
|
||||||
|
part->name, part->id,
|
||||||
|
mtd_part_id);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
part_addr = mtd_part->offset;
|
||||||
|
part_size = mtd_part->size;
|
||||||
|
part_name = mtd_part->name;
|
||||||
|
part_found = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!part_found) {
|
if (!part_found) {
|
||||||
stm32prog_err("%s (0x%x): Invalid partition",
|
stm32prog_err("%s (0x%x): Invalid partition",
|
||||||
part->name, part->id);
|
part->name, part->id);
|
||||||
|
@ -840,6 +929,9 @@ static int create_partitions(struct stm32prog_data *data)
|
||||||
}
|
}
|
||||||
puts("done\n");
|
puts("done\n");
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
run_command("mtd list", 0);
|
||||||
|
#endif
|
||||||
free(buf);
|
free(buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -898,9 +990,17 @@ static int stm32prog_alt_add(struct stm32prog_data *data,
|
||||||
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
||||||
" mmcpart %d;", -(part->part_id));
|
" mmcpart %d;", -(part->part_id));
|
||||||
} else {
|
} else {
|
||||||
offset += snprintf(buf + offset,
|
if (part->part_type == PART_SYSTEM &&
|
||||||
ALT_BUF_LEN - offset,
|
(part->target == STM32PROG_NAND ||
|
||||||
"part");
|
part->target == STM32PROG_NOR ||
|
||||||
|
part->target == STM32PROG_SPI_NAND))
|
||||||
|
offset += snprintf(buf + offset,
|
||||||
|
ALT_BUF_LEN - offset,
|
||||||
|
"partubi");
|
||||||
|
else
|
||||||
|
offset += snprintf(buf + offset,
|
||||||
|
ALT_BUF_LEN - offset,
|
||||||
|
"part");
|
||||||
/* dev_id requested by DFU MMC */
|
/* dev_id requested by DFU MMC */
|
||||||
if (part->target == STM32PROG_MMC)
|
if (part->target == STM32PROG_MMC)
|
||||||
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
||||||
|
@ -914,6 +1014,14 @@ static int stm32prog_alt_add(struct stm32prog_data *data,
|
||||||
sprintf(dfustr, "mmc");
|
sprintf(dfustr, "mmc");
|
||||||
sprintf(devstr, "%d", part->dev_id);
|
sprintf(devstr, "%d", part->dev_id);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_MTD
|
||||||
|
case STM32PROG_NAND:
|
||||||
|
case STM32PROG_NOR:
|
||||||
|
case STM32PROG_SPI_NAND:
|
||||||
|
sprintf(dfustr, "mtd");
|
||||||
|
get_mtd_by_target(devstr, part->target, part->dev_id);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
stm32prog_err("invalid target: %d", part->target);
|
stm32prog_err("invalid target: %d", part->target);
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
enum stm32prog_target {
|
enum stm32prog_target {
|
||||||
STM32PROG_NONE,
|
STM32PROG_NONE,
|
||||||
STM32PROG_MMC,
|
STM32PROG_MMC,
|
||||||
|
STM32PROG_NAND,
|
||||||
|
STM32PROG_NOR,
|
||||||
|
STM32PROG_SPI_NAND
|
||||||
};
|
};
|
||||||
|
|
||||||
enum stm32prog_link_t {
|
enum stm32prog_link_t {
|
||||||
|
@ -67,6 +70,7 @@ struct stm32prog_dev_t {
|
||||||
char dev_id;
|
char dev_id;
|
||||||
u32 erase_size;
|
u32 erase_size;
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
|
struct mtd_info *mtd;
|
||||||
/* list of partition for this device / ordered in offset */
|
/* list of partition for this device / ordered in offset */
|
||||||
struct list_head part_list;
|
struct list_head part_list;
|
||||||
bool full_update;
|
bool full_update;
|
||||||
|
|
|
@ -36,7 +36,6 @@ CONFIG_CMD_FUSE=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
CONFIG_CMD_I2C=y
|
CONFIG_CMD_I2C=y
|
||||||
CONFIG_CMD_MMC=y
|
CONFIG_CMD_MMC=y
|
||||||
CONFIG_CMD_MTD=y
|
|
||||||
CONFIG_CMD_REMOTEPROC=y
|
CONFIG_CMD_REMOTEPROC=y
|
||||||
CONFIG_CMD_SPI=y
|
CONFIG_CMD_SPI=y
|
||||||
CONFIG_CMD_USB=y
|
CONFIG_CMD_USB=y
|
||||||
|
@ -66,7 +65,6 @@ CONFIG_ENV_UBI_VOLUME="uboot_config"
|
||||||
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
|
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
|
||||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
CONFIG_STM32_ADC=y
|
CONFIG_STM32_ADC=y
|
||||||
CONFIG_DFU_MTD=y
|
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
||||||
|
|
|
@ -25,7 +25,6 @@ CONFIG_CMD_FUSE=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
CONFIG_CMD_I2C=y
|
CONFIG_CMD_I2C=y
|
||||||
CONFIG_CMD_MMC=y
|
CONFIG_CMD_MMC=y
|
||||||
CONFIG_CMD_MTD=y
|
|
||||||
CONFIG_CMD_REMOTEPROC=y
|
CONFIG_CMD_REMOTEPROC=y
|
||||||
CONFIG_CMD_SPI=y
|
CONFIG_CMD_SPI=y
|
||||||
CONFIG_CMD_USB=y
|
CONFIG_CMD_USB=y
|
||||||
|
@ -53,7 +52,6 @@ CONFIG_ENV_UBI_VOLUME="uboot_config"
|
||||||
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
|
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
|
||||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
CONFIG_STM32_ADC=y
|
CONFIG_STM32_ADC=y
|
||||||
CONFIG_DFU_MTD=y
|
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue