From 04d99019b2c25d15081c6613907746cd242a9735 Mon Sep 17 00:00:00 2001 From: Rajkumar Ayyasamy Date: Thu, 12 Sep 2019 14:21:39 +0530 Subject: [PATCH] ipq6018: add support to flash individual ubi volumes Change-Id: I660879ffa28437eb88faa04ee61d329c224d16f9 Signed-off-by: Rajkumar Ayyasamy --- arch/arm/cpu/armv7/qca/common/smem.c | 87 ++++++++++++++++++++- arch/arm/include/asm/arch-qca-common/smem.h | 3 + common/cmd_flashwrite.c | 73 ++++++++++++++++- include/configs/ipq6018.h | 1 + 4 files changed, 161 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv7/qca/common/smem.c b/arch/arm/cpu/armv7/qca/common/smem.c index a63c506686..e5e52a46da 100644 --- a/arch/arm/cpu/armv7/qca/common/smem.c +++ b/arch/arm/cpu/armv7/qca/common/smem.c @@ -36,7 +36,12 @@ #include #include #include "fdt_info.h" +#include +#include +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT +static struct ubi_device *ubi; +#endif typedef struct smem_pmic_type { unsigned pmic_model; @@ -970,12 +975,86 @@ int getpart_offset_size(char *part_name, uint32_t *offset, uint32_t *size) return 0; } +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT +int ubi_set_rootfs_part(void) +{ + int ret; + uint32_t offset; + uint32_t part_size = 0; + uint32_t size_block, start_block; + qca_smem_flash_info_t *sfi = &qca_smem_flash_info; + char runcmd[256]; + + if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) { + ret = smem_getpart(QCA_ROOT_FS_PART_NAME, + &start_block, &size_block); + if (ret) + return ret; + + offset = sfi->flash_block_size * start_block; + part_size = sfi->flash_block_size * size_block; + } else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH && + get_which_flash_param(QCA_ROOT_FS_PART_NAME)) { + ret = getpart_offset_size(QCA_ROOT_FS_PART_NAME, &offset, + &part_size); + if (ret) + return ret; + } + + if (!part_size) + return -ENOENT; + + snprintf(runcmd, sizeof(runcmd), + "nand device %d && " + "setenv mtdids nand%d=nand%d && " + "setenv mtdparts mtdparts=nand%d:0x%x@0x%x(fs),${msmparts} && " + "ubi part fs && ", is_spi_nand_available(), + is_spi_nand_available(), + is_spi_nand_available(), + is_spi_nand_available(), + part_size, offset); + + if (run_command(runcmd, 0) != CMD_RET_SUCCESS) + return CMD_RET_FAILURE; + + ubi = ubi_devices[0]; + return 0; +} + +static void print_ubi_vol_info(void) +{ + int i; + int j=0; + struct ubi_volume *vol; + + for (i = 0; i < (ubi->vtbl_slots + 1); i++) { + vol = ubi->volumes[i]; + if (!vol) + continue; /* Empty record */ + if (vol->name_len <= UBI_VOL_NAME_MAX && strnlen(vol->name, + vol->name_len + 1) == vol->name_len) { + printf("\tubi vol %d %s\n", vol->vol_id, vol->name); + j++; + } else { + printf("\tubi vol %d %c%c%c%c%c\n", + vol->vol_id, vol->name[0], vol->name[1], + vol->name[2], vol->name[3], vol->name[4]); + j++; + } + if (j == ubi->vol_count - UBI_INT_VOL_COUNT) + break; + } +} +#endif + int do_smeminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { qca_smem_flash_info_t *sfi = &qca_smem_flash_info; int i; uint32_t bsize; - +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT + ubi_set_rootfs_part(); +#endif if(sfi->flash_density != 0) { printf( "flash_type: 0x%x\n" "flash_index: 0x%x\n" @@ -1022,6 +1101,12 @@ int do_smeminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("%3d: " smem_ptn_name_fmt " 0x%08x %#16llx %#16llx\n", i, p->name, p->attr, ((loff_t)p->start) * bsize, psize); +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT + if (!strncmp(p->name, QCA_ROOT_FS_PART_NAME, SMEM_PTN_NAME_MAX) + && ubi) { + print_ubi_vol_info(); + } +#endif } return 0; } diff --git a/arch/arm/include/asm/arch-qca-common/smem.h b/arch/arm/include/asm/arch-qca-common/smem.h index 6c6a229abe..21cc06e70d 100644 --- a/arch/arm/include/asm/arch-qca-common/smem.h +++ b/arch/arm/include/asm/arch-qca-common/smem.h @@ -71,6 +71,9 @@ void ipq_fdt_fixup_usb_device_mode(void *blob); void fdt_fixup_auto_restart(void *blob); int get_soc_version(uint32_t *soc_ver_major, uint32_t *soc_ver_minor); unsigned int get_dts_machid(unsigned int machid); +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT +int ubi_set_rootfs_part(void); +#endif typedef struct { loff_t offset; diff --git a/common/cmd_flashwrite.c b/common/cmd_flashwrite.c index 8c9654ec1d..3bc958bd41 100644 --- a/common/cmd_flashwrite.c +++ b/common/cmd_flashwrite.c @@ -22,6 +22,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_SDHCI_SUPPORT @@ -117,6 +118,62 @@ static int fl_erase(int flash_type, uint32_t offset, uint32_t part_size, return CMD_RET_SUCCESS; } +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT +int ubi_vol_present(char* ubi_vol_name) +{ + int i; + int j=0; + struct ubi_device *ubi; + struct ubi_volume *vol; + + if (ubi_set_rootfs_part()) + return 0; + + ubi = ubi_devices[0]; + for (i = 0; ubi && i < (ubi->vtbl_slots + 1); i++) { + vol = ubi->volumes[i]; + if (!vol) + continue; /* Empty record */ + if (vol->name_len <= UBI_VOL_NAME_MAX && + strnlen(vol->name, vol->name_len + 1) == vol->name_len) { + j++; + if (!strncmp(ubi_vol_name, vol->name, + UBI_VOL_NAME_MAX)) { + return 1; + } + } + + if (j == ubi->vol_count - UBI_INT_VOL_COUNT) + break; + } + + printf("volume or partition %s not found\n", ubi_vol_name); + return 0; +} + +int write_ubi_vol(char* ubi_vol_name, uint32_t load_addr, uint32_t file_size) +{ + char runcmd[256]; + + if (!strncmp(ubi_vol_name, "ubi_rootfs", UBI_VOL_NAME_MAX)) { + snprintf(runcmd, sizeof(runcmd), + "ubi remove rootfs_data &&" + "ubi remove %s &&" + "ubi create %s 0x%x &&" + "ubi write 0x%x %s 0x%x &&" + "ubi create rootfs_data", + ubi_vol_name, ubi_vol_name, file_size, + load_addr, ubi_vol_name, file_size); + } else { + snprintf(runcmd, sizeof(runcmd), + "ubi write 0x%x %s 0x%x ", + load_addr, ubi_vol_name, file_size); + } + + return run_command(runcmd, 0); +} +#endif + static int do_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -185,8 +242,14 @@ char * const argv[]) if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) { ret = smem_getpart(part_name, &start_block, &size_block); - if (ret) + if (ret) { +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT + if (ubi_vol_present(part_name)) + return write_ubi_vol(part_name, load_addr, + file_size); +#endif return retn; + } offset = sfi->flash_block_size * start_block; part_size = sfi->flash_block_size * size_block; @@ -269,8 +332,14 @@ char * const argv[]) ret = smem_getpart(part_name, &start_block, &size_block); - if (ret) + if (ret) { +#ifdef IPQ_UBI_VOL_WRITE_SUPPORT + if (ubi_vol_present(part_name)) + return write_ubi_vol(part_name, + load_addr, file_size); +#endif return retn; + } offset = sfi->flash_block_size * start_block; part_size = sfi->flash_block_size * size_block; diff --git a/include/configs/ipq6018.h b/include/configs/ipq6018.h index 063c1fc1f6..52d1c6e178 100644 --- a/include/configs/ipq6018.h +++ b/include/configs/ipq6018.h @@ -360,5 +360,6 @@ extern loff_t board_env_size; #define CONFIG_CMD_RUN #define CONFIG_ARMV7_PSCI #define CONFIG_IPQ_ELF_AUTH +#define IPQ_UBI_VOL_WRITE_SUPPORT #endif /* _IPQ6018_H */