qca: Add uboot-CLI command "flash"

The "flash" command erases given partition and
writes the image to flash.

Change-Id: I059414fd3d7eefeac0c626e1980a70985f2de986
Signed-off-by: Pavithra Palanisamy <pavip@codeaurora.org>
This commit is contained in:
Pavithra Palanisamy 2018-05-11 18:05:27 +05:30
parent af7feada2e
commit 316e48fb0d
7 changed files with 293 additions and 0 deletions

View file

@ -649,6 +649,49 @@ unsigned int get_which_flash_param(char *part_name)
return flash_var;
}
/*
* getpart_offset_size - retreive partition offset and size
* @part_name - partition name
* @offset - location where the offset of partition to be stored
* @size - location where partition size to be stored
*
* Retreive partition offset and size in bytes with respect to the
* partition specific flash block size
*/
int getpart_offset_size(char *part_name, uint32_t *offset, uint32_t *size)
{
int i;
uint32_t bsize;
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
for (i = 0; i < smem_ptable.len; i++) {
struct smem_ptn *p = &smem_ptable.parts[i];
loff_t psize;
if (!strncmp(p->name, part_name, SMEM_PTN_NAME_MAX)) {
bsize = get_part_block_size(p, sfi);
if (p->size == (~0u)) {
/*
* Partition size is 'till end of device', calculate
* appropriately
*/
psize = nand_info[get_device_id_by_part(p)].size
- (((loff_t)p->start) * bsize);
} else {
psize = ((loff_t)p->size) * bsize;
}
*offset = ((loff_t)p->start) * bsize;
*size = psize;
break;
}
}
if (i == smem_ptable.len)
return -ENOENT;
return 0;
}
int do_smeminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;

View file

@ -60,6 +60,7 @@ int smem_get_boot_flash(uint32_t *flash_type,
uint32_t *flash_block_size,
uint32_t *flash_density);
int smem_getpart(char *name, uint32_t *start, uint32_t *size);
int getpart_offset_size(char *part_name, uint32_t *offset, uint32_t *size);
unsigned int smem_get_board_machtype(void);
uint32_t get_nand_block_size(uint8_t dev_id);
unsigned int get_which_flash_param(char *part_name);

View file

@ -101,6 +101,7 @@ obj-$(CONFIG_CMD_FDC) += cmd_fdc.o
obj-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
obj-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o
obj-$(CONFIG_CMD_FLASH) += cmd_flash.o
obj-$(CONFIG_CMD_FLASHWRITE) += cmd_flashwrite.o
ifdef CONFIG_FPGA
obj-$(CONFIG_CMD_FPGA) += cmd_fpga.o
endif

245
common/cmd_flashwrite.c Normal file
View file

@ -0,0 +1,245 @@
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* FlashWrite command support
*/
#include <common.h>
#include <command.h>
#include <asm/arch-qca-common/smem.h>
#include <part.h>
#include <linux/mtd/mtd.h>
#include <nand.h>
#include <mmc.h>
#include <sdhci.h>
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SDHCI_SUPPORT
extern qca_mmc mmc_host;
#else
extern struct sdhci_host mmc_host;
#endif
#define SMEM_PTN_NAME_MAX 16
static int write_to_flash(int flash_type, uint32_t address, uint32_t offset,
uint32_t part_size, uint32_t file_size, char *layout)
{
char runcmd[256];
int nand_dev = CONFIG_NAND_FLASH_INFO_IDX;
if (flash_type == SMEM_BOOT_NAND_FLASH) {
snprintf(runcmd, sizeof(runcmd), "nand device %d && ", nand_dev);
if (strcmp(layout, "default") != 0) {
snprintf(runcmd + strlen(runcmd), sizeof(runcmd),
"ipq_nand %s && ", layout);
}
snprintf(runcmd + strlen(runcmd), sizeof(runcmd),
"nand erase 0x%x 0x%x && "
"nand write 0x%x 0x%x 0x%x && ",
offset, part_size,
address, offset, file_size);
} else if (flash_type == SMEM_BOOT_MMC_FLASH) {
snprintf(runcmd, sizeof(runcmd),
"mmc erase 0x%x 0x%x && "
"mmc write 0x%x 0x%x 0x%x && ",
offset, part_size,
address, offset, file_size);
} else if (flash_type == SMEM_BOOT_SPI_FLASH) {
snprintf(runcmd, sizeof(runcmd),
"sf probe && "
"sf erase 0x%x 0x%x && "
"sf write 0x%x 0x%x 0x%x && ",
offset, part_size,
address, offset, file_size);
}
if (run_command(runcmd, 0) != CMD_RET_SUCCESS)
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
static int do_flash(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
uint32_t load_addr, offset, part_size, file_size, adj_size;
uint32_t size_block, start_block, file_size_cpy;
char *part_name = NULL, *filesize;
int flash_type, ret, retn;
unsigned int active_part = 0;
char *layout = NULL;
#ifdef CONFIG_IPQ806X
char* layout_linux[] = {"rootfs", "0:BOOTCONFIG", "0:BOOTCONFIG1"};
int len, i;
#endif
retn = CMD_RET_FAILURE;
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
nand_info_t *nand = &nand_info[CONFIG_NAND_FLASH_INFO_IDX];
if ((argc < 3) || (argc > 4))
return CMD_RET_USAGE;
if (argc == 4)
file_size = simple_strtoul(argv[3], NULL, 16);
else {
filesize = getenv("filesize");
if (filesize != NULL)
file_size = simple_strtoul(filesize, NULL, 16);
else
return CMD_RET_USAGE;
}
if (strncmp(argv[2], "default", 7) == 0)
load_addr = CONFIG_SYS_LOAD_ADDR;
else
load_addr = simple_strtoul(argv[2], NULL, 16);
flash_type = sfi->flash_type;
part_name = argv[1];
if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
ret = smem_getpart(part_name, &start_block, &size_block);
if (ret)
return retn;
offset = sfi->flash_block_size * start_block;
part_size = sfi->flash_block_size * size_block;
layout = "default";
#ifdef CONFIG_IPQ806X
len = sizeof(layout_linux)/sizeof(layout_linux[0]);
for (i = 0; i < len; i++) {
if (!strncmp(layout_linux[i], part_name,
SMEM_PTN_NAME_MAX)) {
layout = "linux";
break;
}
}
if (i == len )
layout = "sbl";
#endif
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
blk_dev = mmc_get_dev(mmc_host.dev_num);
if (blk_dev != NULL) {
ret = get_partition_info_efi_by_name(blk_dev,
part_name, &disk_info);
if (ret)
return retn;
offset = (ulong)disk_info.start;
part_size = (ulong)disk_info.size;
file_size_cpy = file_size;
}
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
if (get_which_flash_param(part_name)) {
/* NOR + NAND*/
flash_type = SMEM_BOOT_NAND_FLASH;
ret = getpart_offset_size(part_name, &offset, &part_size);
if (ret)
return retn;
} else if ((sfi->flash_secondary_type == SMEM_BOOT_NAND_FLASH)
&& (strncmp(part_name, "rootfs", 6) == 0)) {
/* IPQ806X - NOR + NAND */
flash_type = SMEM_BOOT_NAND_FLASH;
if (sfi->rootfs.offset == 0xBAD0FF5E) {
if (smem_bootconfig_info() == 0)
active_part = get_rootfs_active_partition();
offset = (ulong) active_part * IPQ_NAND_ROOTFS_SIZE;
part_size = (ulong) IPQ_NAND_ROOTFS_SIZE;
}
}else if ((smem_getpart(part_name, &start_block, &size_block)
== -ENOENT) && (sfi->rootfs.offset == 0xBAD0FF5E)){
/* NOR + EMMC */
flash_type = SMEM_BOOT_MMC_FLASH;
blk_dev = mmc_get_dev(mmc_host.dev_num);
if (blk_dev != NULL) {
ret = get_partition_info_efi_by_name(blk_dev,
part_name, &disk_info);
if (ret)
return retn;
offset = (ulong)disk_info.start;
part_size = (ulong)disk_info.size;
file_size_cpy = file_size;
}
} else {
ret = smem_getpart(part_name, &start_block,
&size_block);
if (ret)
return retn;
offset = sfi->flash_block_size * start_block;
part_size = sfi->flash_block_size * size_block;
}
}
if (flash_type == SMEM_BOOT_NAND_FLASH) {
adj_size = file_size % nand->writesize;
if (adj_size)
file_size = file_size + (nand->writesize - adj_size);
}
if (flash_type == SMEM_BOOT_MMC_FLASH) {
file_size = file_size / disk_info.blksz;
adj_size = file_size_cpy % disk_info.blksz;
if (adj_size)
file_size = file_size + 1;
}
ret = write_to_flash(flash_type, load_addr, offset, part_size,
file_size, layout);
return ret;
}
U_BOOT_CMD(
flash, 4, 0, do_flash,
"flash part_name load_addr [file_size] \n"
"\tflash part_name 'default' \n",
"flash the image at load_addr, given file_size in hex\n"
);

View file

@ -122,6 +122,7 @@ typedef struct {
#define QCA_BOOT_PARAMS_ADDR (QCA_KERNEL_START_ADDR + 0x100)
#endif
#define CONFIG_FLASH_PROTECT
#define CONFIG_CMD_FLASHWRITE
/* Environment */
#define CONFIG_ARCH_CPU_INIT

View file

@ -93,6 +93,7 @@
#define CONFIG_SYS_DEVICE_NULLDEV
#define CONFIG_FLASH_PROTECT
#define CONFIG_CMD_FLASHWRITE
/* Environment */
#define CONFIG_MSM_PCOMM

View file

@ -140,6 +140,7 @@ extern loff_t board_env_size;
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_FLASH_PROTECT
#define CONFIG_CMD_FLASHWRITE
/* Allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE