mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 22:20:45 +00:00
stm32mp: stm32prog: add support of boot partition for eMMC device
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 <patrick.delaunay@st.com> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
This commit is contained in:
parent
aff4c5dd82
commit
878f7542f1
2 changed files with 90 additions and 36 deletions
|
@ -259,12 +259,30 @@ static int parse_offset(struct stm32prog_data *data,
|
||||||
char *tail;
|
char *tail;
|
||||||
|
|
||||||
part->part_id = 0;
|
part->part_id = 0;
|
||||||
|
part->addr = 0;
|
||||||
part->size = 0;
|
part->size = 0;
|
||||||
part->addr = simple_strtoull(p, &tail, 0);
|
/* eMMC boot parttion */
|
||||||
if (tail == p || *tail != '\0') {
|
if (!strncmp(p, "boot", 4)) {
|
||||||
stm32prog_err("Layout line %d: invalid offset '%s'",
|
if (strlen(p) != 5) {
|
||||||
i, p);
|
result = -EINVAL;
|
||||||
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;
|
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);
|
parta = container_of(a, struct stm32prog_part_t, list);
|
||||||
partb = container_of(b, 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,
|
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);
|
part->dev_id, part->addr, part->size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (part->part_id < 0) { /* boot hw partition for eMMC */
|
||||||
part->part_id = part_id++;
|
if (mmc) {
|
||||||
|
part->size = mmc->capacity_boot;
|
||||||
/* 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 {
|
} 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->name, part->id,
|
||||||
part->addr,
|
part->part_id);
|
||||||
next_part->name,
|
return -ENODEV;
|
||||||
next_part->id,
|
|
||||||
next_part->addr);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (part->addr <= last_addr) {
|
part->part_id = part_id++;
|
||||||
part->size = last_addr - part->addr;
|
|
||||||
|
/* 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 {
|
} 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->name, part->id,
|
||||||
part->addr, last_addr);
|
part->addr, first_addr);
|
||||||
return -EINVAL;
|
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) {
|
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",
|
stm32prog_err("%s (0x%x): not aligned address : 0x%llx on erase size 0x%x",
|
||||||
part->name, part->id, part->addr,
|
part->name, part->id, part->addr,
|
||||||
|
@ -657,6 +687,9 @@ static int create_partitions(struct stm32prog_data *data)
|
||||||
memset(buf, 0, buflen);
|
memset(buf, 0, buflen);
|
||||||
|
|
||||||
list_for_each_entry(part, &data->dev[i].part_list, list) {
|
list_for_each_entry(part, &data->dev[i].part_list, list) {
|
||||||
|
/* skip eMMC boot partitions */
|
||||||
|
if (part->part_id < 0)
|
||||||
|
continue;
|
||||||
/* skip Raw Image */
|
/* skip Raw Image */
|
||||||
if (part->part_type == RAW_IMAGE)
|
if (part->part_type == RAW_IMAGE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -787,6 +820,14 @@ static int stm32prog_alt_add(struct stm32prog_data *data,
|
||||||
dfu_size = part->size;
|
dfu_size = part->size;
|
||||||
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
|
||||||
"raw 0x0 0x%llx", dfu_size);
|
"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 {
|
} else {
|
||||||
offset += snprintf(buf + offset,
|
offset += snprintf(buf + offset,
|
||||||
ALT_BUF_LEN - offset,
|
ALT_BUF_LEN - offset,
|
||||||
|
@ -908,6 +949,19 @@ static void stm32prog_end_phase(struct stm32prog_data *data)
|
||||||
|
|
||||||
if (!data->cur_part)
|
if (!data->cur_part)
|
||||||
return;
|
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)
|
void stm32prog_do_reset(struct stm32prog_data *data)
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct stm32prog_part_t {
|
||||||
|
|
||||||
/* information on associated device */
|
/* information on associated device */
|
||||||
struct stm32prog_dev_t *dev; /* pointer to 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 */
|
int alt_id; /* alt id in usb/dfu */
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
Loading…
Reference in a new issue