From mboxrd@z Thu Jan 1 00:00:00 1970 From: Patrice CHOTARD Date: Tue, 14 Apr 2020 13:05:23 +0000 Subject: [PATCH 07/18] stm32mp: stm32prog: add support of boot partition for eMMC device In-Reply-To: <20200318082503.8025-8-patrick.delaunay@st.com> References: <20200318082503.8025-1-patrick.delaunay@st.com> <20200318082503.8025-8-patrick.delaunay@st.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi On 3/18/20 9:24 AM, Patrick Delaunay wrote: > Add support of eMMC device boot partition with > part_id = -1 for offset="boot1" > or = -2 for offset="boot2" > > The stm32prog command configures the MMC DFU backend with "mmcpart" > and configure the eMMC (command "mmc bootbus" and "mmc partconf") > when the update is done. > > Signed-off-by: Patrick Delaunay > --- > > .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 124 +++++++++++++----- > .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 +- > 2 files changed, 90 insertions(+), 36 deletions(-) > > diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c > index feb83670b5..f63036606e 100644 > --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c > +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c > @@ -259,12 +259,30 @@ static int parse_offset(struct stm32prog_data *data, > char *tail; > > part->part_id = 0; > + part->addr = 0; > part->size = 0; > - part->addr = simple_strtoull(p, &tail, 0); > - if (tail == p || *tail != '\0') { > - stm32prog_err("Layout line %d: invalid offset '%s'", > - i, p); > - result = -EINVAL; > + /* eMMC boot parttion */ > + if (!strncmp(p, "boot", 4)) { > + if (strlen(p) != 5) { > + result = -EINVAL; > + } else { > + if (p[4] == '1') > + part->part_id = -1; > + else if (p[4] == '2') > + part->part_id = -2; > + else > + result = -EINVAL; > + } > + if (result) > + stm32prog_err("Layout line %d: invalid part '%s'", > + i, p); > + } else { > + part->addr = simple_strtoull(p, &tail, 0); > + if (tail == p || *tail != '\0') { > + stm32prog_err("Layout line %d: invalid offset '%s'", > + i, p); > + result = -EINVAL; > + } > } > > return result; > @@ -451,7 +469,10 @@ static int __init part_cmp(void *priv, struct list_head *a, struct list_head *b) > parta = container_of(a, struct stm32prog_part_t, list); > partb = container_of(b, struct stm32prog_part_t, list); > > - return parta->addr > partb->addr ? 1 : -1; > + if (parta->part_id != partb->part_id) > + return parta->part_id - partb->part_id; > + else > + return parta->addr > partb->addr ? 1 : -1; > } > > static int init_device(struct stm32prog_data *data, > @@ -520,44 +541,53 @@ static int init_device(struct stm32prog_data *data, > part->dev_id, part->addr, part->size); > continue; > } > - > - part->part_id = part_id++; > - > - /* last partition : size to the end of the device */ > - if (part->list.next != &dev->part_list) { > - next_part = > - container_of(part->list.next, > - struct stm32prog_part_t, > - list); > - if (part->addr < next_part->addr) { > - part->size = next_part->addr - > - part->addr; > + if (part->part_id < 0) { /* boot hw partition for eMMC */ > + if (mmc) { > + part->size = mmc->capacity_boot; > } else { > - stm32prog_err("%s (0x%x): same address : 0x%llx == %s (0x%x): 0x%llx", > + stm32prog_err("%s (0x%x): hw partition not expected : %d", > part->name, part->id, > - part->addr, > - next_part->name, > - next_part->id, > - next_part->addr); > - return -EINVAL; > + part->part_id); > + return -ENODEV; > } > } else { > - if (part->addr <= last_addr) { > - part->size = last_addr - part->addr; > + part->part_id = part_id++; > + > + /* last partition : size to the end of the device */ > + if (part->list.next != &dev->part_list) { > + next_part = > + container_of(part->list.next, > + struct stm32prog_part_t, > + list); > + if (part->addr < next_part->addr) { > + part->size = next_part->addr - > + part->addr; > + } else { > + stm32prog_err("%s (0x%x): same address : 0x%llx == %s (0x%x): 0x%llx", > + part->name, part->id, > + part->addr, > + next_part->name, > + next_part->id, > + next_part->addr); > + return -EINVAL; > + } > } else { > - stm32prog_err("%s (0x%x): invalid address 0x%llx (max=0x%llx)", > + if (part->addr <= last_addr) { > + part->size = last_addr - part->addr; > + } else { > + stm32prog_err("%s (0x%x): invalid address 0x%llx (max=0x%llx)", > + part->name, part->id, > + part->addr, last_addr); > + return -EINVAL; > + } > + } > + if (part->addr < first_addr) { > + stm32prog_err("%s (0x%x): invalid address 0x%llx (min=0x%llx)", > part->name, part->id, > - part->addr, last_addr); > + part->addr, first_addr); > return -EINVAL; > } > } > - if (part->addr < first_addr) { > - stm32prog_err("%s (0x%x): invalid address 0x%llx (min=0x%llx)", > - part->name, part->id, > - part->addr, first_addr); > - return -EINVAL; > - } > - > if ((part->addr & ((u64)part->dev->erase_size - 1)) != 0) { > stm32prog_err("%s (0x%x): not aligned address : 0x%llx on erase size 0x%x", > part->name, part->id, part->addr, > @@ -657,6 +687,9 @@ static int create_partitions(struct stm32prog_data *data) > memset(buf, 0, buflen); > > list_for_each_entry(part, &data->dev[i].part_list, list) { > + /* skip eMMC boot partitions */ > + if (part->part_id < 0) > + continue; > /* skip Raw Image */ > if (part->part_type == RAW_IMAGE) > continue; > @@ -787,6 +820,14 @@ static int stm32prog_alt_add(struct stm32prog_data *data, > dfu_size = part->size; > offset += snprintf(buf + offset, ALT_BUF_LEN - offset, > "raw 0x0 0x%llx", dfu_size); > + } else if (part->part_id < 0) { > + u64 nb_blk = part->size / part->dev->mmc->read_bl_len; > + > + offset += snprintf(buf + offset, ALT_BUF_LEN - offset, > + "raw 0x%llx 0x%llx", > + part->addr, nb_blk); > + offset += snprintf(buf + offset, ALT_BUF_LEN - offset, > + " mmcpart %d;", -(part->part_id)); > } else { > offset += snprintf(buf + offset, > ALT_BUF_LEN - offset, > @@ -908,6 +949,19 @@ static void stm32prog_end_phase(struct stm32prog_data *data) > > if (!data->cur_part) > return; > + > + if (CONFIG_IS_ENABLED(MMC) && > + data->cur_part->part_id < 0) { > + char cmdbuf[60]; > + > + sprintf(cmdbuf, "mmc bootbus %d 0 0 0; mmc partconf %d 1 %d 0", > + data->cur_part->dev_id, data->cur_part->dev_id, > + -(data->cur_part->part_id)); > + if (run_command(cmdbuf, 0)) { > + stm32prog_err("commands '%s' failed", cmdbuf); > + return; > + } > + } > } > > void stm32prog_do_reset(struct stm32prog_data *data) > diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h > index 228a25d37f..6c3ad56a38 100644 > --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h > +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h > @@ -89,7 +89,7 @@ struct stm32prog_part_t { > > /* information on associated device */ > struct stm32prog_dev_t *dev; /* pointer to device */ > - u16 part_id; /* partition id in device */ > + s16 part_id; /* partition id in device */ > int alt_id; /* alt id in usb/dfu */ > > struct list_head list; Reviewed-by: Patrice Chotard Thanks Patrice