diff options
author | Liang Yang <liang.yang@amlogic.com> | 2019-02-22 16:52:24 +0800 |
---|---|---|
committer | Dongjin Kim <tobetter@gmail.com> | 2019-05-16 13:19:38 +0900 |
commit | c9938076dbd4c4ecf8a5c123a82722adbc34d1ed (patch) | |
tree | 87e86addc39e23e5d96533ddd20c12e921f3645e | |
parent | b573105a2ddda09b36e877ef6f996a0f95154347 (diff) | |
download | u-boot-odroid-c1-c9938076dbd4c4ecf8a5c123a82722adbc34d1ed.tar.gz |
storage: mmc/nand: support support to read saved ddr parameter [1/1]
PD#SWPL-5550
Problem:
Implement to the function that can read ddr
parameter which saved in reserved area.
Solution:
provide interface.
Verify:
tl1-x301
axg-s400
Change-Id: I68a0a83ac435ad6d4a11e01edc290aedae650941
Signed-off-by: Liang Yang <liang.yang@amlogic.com>
Signed-off-by: Qiang Li <qiang.li@amlogic.com>
Signed-off-by: Liang Yang <liang.yang@amlogic.com>
-rw-r--r-- | common/cmd_aml_mmc.c | 6528 | ||||
-rw-r--r-- | common/store_interface.c | 2642 | ||||
-rw-r--r-- | drivers/mmc/aml_emmc_partition.c | 88 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 129 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/aml_dtb.c | 463 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/aml_env.c | 342 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/aml_key.c | 227 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/aml_mtd.h | 55 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/aml_nand.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/boot.c | 11 | ||||
-rw-r--r-- | drivers/mtd/nand/amlogic_mtd/rsv_manage.c | 373 | ||||
-rw-r--r-- | include/amlogic/aml_mmc.h | 29 | ||||
-rw-r--r-- | include/emmc_partitions.h | 6 |
13 files changed, 5061 insertions, 5842 deletions
diff --git a/common/cmd_aml_mmc.c b/common/cmd_aml_mmc.c index 3a345e3def..2436a1579d 100644 --- a/common/cmd_aml_mmc.c +++ b/common/cmd_aml_mmc.c @@ -33,41 +33,43 @@ #include <linux/sizes.h> #include <asm/cpu_id.h> #include <amlogic/aml_mmc.h> +#include <errno.h> #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define SD_EMMC_VDDEE_REG (*((volatile unsigned *)(0xff807000 + (0x01 << 2)))) #ifdef MMC_HS200_MODE +//#define MMC_NO_BOOT_PARTITION /*tl1*/ static int pwm_voltage_table_ee[][2] = { - { 0x1c0000, 681}, - { 0x1b0001, 691}, - { 0x1a0002, 701}, - { 0x190003, 711}, - { 0x180004, 721}, - { 0x170005, 731}, - { 0x160006, 741}, - { 0x150007, 751}, - { 0x140008, 761}, - { 0x130009, 772}, - { 0x12000a, 782}, - { 0x11000b, 792}, - { 0x10000c, 802}, - { 0x0f000d, 812}, - { 0x0e000e, 822}, - { 0x0d000f, 832}, - { 0x0c0010, 842}, - { 0x0b0011, 852}, - { 0x0a0012, 862}, - { 0x090013, 872}, - { 0x080014, 882}, - { 0x070015, 892}, - { 0x060016, 902}, - { 0x050017, 912}, - { 0x040018, 922}, - { 0x030019, 932}, - { 0x02001a, 942}, - { 0x01001b, 952}, - { 0x00001c, 962} + { 0x1c0000, 681}, + { 0x1b0001, 691}, + { 0x1a0002, 701}, + { 0x190003, 711}, + { 0x180004, 721}, + { 0x170005, 731}, + { 0x160006, 741}, + { 0x150007, 751}, + { 0x140008, 761}, + { 0x130009, 772}, + { 0x12000a, 782}, + { 0x11000b, 792}, + { 0x10000c, 802}, + { 0x0f000d, 812}, + { 0x0e000e, 822}, + { 0x0d000f, 832}, + { 0x0c0010, 842}, + { 0x0b0011, 852}, + { 0x0a0012, 862}, + { 0x090013, 872}, + { 0x080014, 882}, + { 0x070015, 892}, + { 0x060016, 902}, + { 0x050017, 912}, + { 0x040018, 922}, + { 0x030019, 932}, + { 0x02001a, 942}, + { 0x01001b, 952}, + { 0x00001c, 962} }; /*g12b*/ @@ -136,63 +138,63 @@ static int pwm_voltage_table_ee[][2] = { //}; /*r311 static int pwm_voltage_table_ee[][2] = { - { 0x1c0000, 810}, - { 0x1b0001, 820}, - { 0x1a0002, 830}, - { 0x190003, 840}, - { 0x180004, 850}, - { 0x170005, 860}, - { 0x160006, 870}, - { 0x150007, 880}, - { 0x140008, 890}, - { 0x130009, 900}, - { 0x12000a, 910}, - { 0x11000b, 920}, - { 0x10000c, 930}, - { 0x0f000d, 940}, - { 0x0e000e, 950}, - { 0x0d000f, 960}, - { 0x0c0010, 970}, - { 0x0b0011, 980}, - { 0x0a0012, 990}, - { 0x090013, 1000}, - { 0x080014, 1010}, - { 0x070015, 1020}, - { 0x060016, 1030}, - { 0x050017, 1040}, - { 0x040018, 1050}, - { 0x030019, 1060}, - { 0x02001a, 1070}, - { 0x01001b, 1080}, - { 0x00001c, 1090} + { 0x1c0000, 810}, + { 0x1b0001, 820}, + { 0x1a0002, 830}, + { 0x190003, 840}, + { 0x180004, 850}, + { 0x170005, 860}, + { 0x160006, 870}, + { 0x150007, 880}, + { 0x140008, 890}, + { 0x130009, 900}, + { 0x12000a, 910}, + { 0x11000b, 920}, + { 0x10000c, 930}, + { 0x0f000d, 940}, + { 0x0e000e, 950}, + { 0x0d000f, 960}, + { 0x0c0010, 970}, + { 0x0b0011, 980}, + { 0x0a0012, 990}, + { 0x090013, 1000}, + { 0x080014, 1010}, + { 0x070015, 1020}, + { 0x060016, 1030}, + { 0x050017, 1040}, + { 0x040018, 1050}, + { 0x030019, 1060}, + { 0x02001a, 1070}, + { 0x01001b, 1080}, + { 0x00001c, 1090} }; */ #endif /* info system. */ #define dtb_err(fmt, ...) printf( "%s()-%d: " fmt , \ - __func__, __LINE__, ##__VA_ARGS__) + __func__, __LINE__, ##__VA_ARGS__) #define dtb_wrn(fmt, ...) printf( "%s()-%d: " fmt , \ - __func__, __LINE__, ##__VA_ARGS__) + __func__, __LINE__, ##__VA_ARGS__) /* for detail debug info */ #define dtb_info(fmt, ...) printf( "%s()-%d: " fmt , \ - __func__, __LINE__, ##__VA_ARGS__) + __func__, __LINE__, ##__VA_ARGS__) #define fb_err(fmt, ...) printf("%s()-%d: " fmt , \ - __func__, __LINE__, ##__VA_ARGS__) + __func__, __LINE__, ##__VA_ARGS__) struct aml_dtb_rsv { - u8 data[DTB_BLK_SIZE*DTB_BLK_CNT - 4*sizeof(u32)]; - u32 magic; - u32 version; - u32 timestamp; - u32 checksum; + u8 data[DTB_BLK_SIZE*DTB_BLK_CNT - 4*sizeof(u32)]; + u32 magic; + u32 version; + u32 timestamp; + u32 checksum; }; struct aml_dtb_info { - u32 stamp[2]; - u8 valid[2]; + u32 stamp[2]; + u8 valid[2]; }; #define stamp_after(a,b) ((int)(b) - (int)(a) < 0) @@ -202,7 +204,7 @@ static struct aml_dtb_info dtb_infos = {{0, 0}, {0, 0}}; #define CONFIG_SECURITYKEY #if !defined(CONFIG_SYS_MMC_BOOT_DEV) - #define CONFIG_SYS_MMC_BOOT_DEV (CONFIG_SYS_MMC_ENV_DEV) + #define CONFIG_SYS_MMC_BOOT_DEV (CONFIG_SYS_MMC_ENV_DEV) #endif #define GXB_START_BLK 0 @@ -217,22 +219,22 @@ bool emmckey_is_protected (struct mmc *mmc) { #ifdef CONFIG_STORE_COMPATIBLE #ifdef CONFIG_SECURITYKEY - if (info_disprotect & DISPROTECT_KEY) { - printf("%s(): disprotect\n", __func__); - return 0; - }else{ - printf("%s(): protect\n", __func__); - return 1; - } + if (info_disprotect & DISPROTECT_KEY) { + printf("%s(): disprotect\n", __func__); + return 0; + }else{ + printf("%s(): protect\n", __func__); + return 1; + } #else - return 0; + return 0; #endif #else #ifdef CONFIG_SECURITYKEY - //return mmc->key_protect; - return 0; /* fixme, */ + //return mmc->key_protect; + return 0; /* fixme, */ #else - return 0; + return 0; #endif #endif } @@ -241,1415 +243,1460 @@ unsigned emmc_cur_partition = 0; int mmc_read_status(struct mmc *mmc, int timeout) { - struct mmc_cmd cmd; - int err, retries = 5; - int status; - - cmd.cmdidx = MMC_CMD_SEND_STATUS; - cmd.resp_type = MMC_RSP_R1; - if (!mmc_host_is_spi(mmc)) - cmd.cmdarg = mmc->rca << 16; - do { - err = mmc_send_cmd(mmc, &cmd, NULL); - if (!err) { - if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && - (cmd.response[0] & MMC_STATUS_CURR_STATE) != - MMC_STATE_PRG) - break; - else if (cmd.response[0] & MMC_STATUS_MASK) { - printf("Status Error: 0x%08X\n", - cmd.response[0]); - return COMM_ERR; - } - } else if (--retries < 0) - return err; - - udelay(1000); - - } while (timeout--); - - status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; - printf("CURR STATE:%d, status = 0x%x\n", status, cmd.response[0]); - - if (timeout <= 0) { - printf("read status Timeout waiting card ready\n"); - return TIMEOUT; - } - if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) { - printf("mmc status swwitch error status =0x%x\n", status); - return SWITCH_ERR; - } - return 0; + struct mmc_cmd cmd; + int err, retries = 5; + int status; + + cmd.cmdidx = MMC_CMD_SEND_STATUS; + cmd.resp_type = MMC_RSP_R1; + if (!mmc_host_is_spi(mmc)) + cmd.cmdarg = mmc->rca << 16; + do { + err = mmc_send_cmd(mmc, &cmd, NULL); + if (!err) { + if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && + (cmd.response[0] & MMC_STATUS_CURR_STATE) != + MMC_STATE_PRG) + break; + else if (cmd.response[0] & MMC_STATUS_MASK) { + printf("Status Error: 0x%08X\n", + cmd.response[0]); + return COMM_ERR; + } + } else if (--retries < 0) + return err; + + udelay(1000); + + } while (timeout--); + + status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; + printf("CURR STATE:%d, status = 0x%x\n", status, cmd.response[0]); + + if (timeout <= 0) { + printf("read status Timeout waiting card ready\n"); + return TIMEOUT; + } + if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) { + printf("mmc status swwitch error status =0x%x\n", status); + return SWITCH_ERR; + } + return 0; } static int get_off_size(struct mmc * mmc, char * name, uint64_t offset, uint64_t size, u64 * blk, u64 * cnt, u64 * sz_byte) { - struct partitions *part_info = NULL; - uint64_t off = 0; - int blk_shift = 0; - - blk_shift = ffs(mmc->read_bl_len) - 1; - // printf("blk_shift:%d , off:0x%llx , size:0x%llx.\n ",blk_shift,off,size ); - part_info = find_mmc_partition_by_name(name); - if (part_info == NULL) { - printf("get partition info failed !!\n"); - return -1; - } - off = part_info->offset + offset; - - // printf("part_info->offset:0x%llx , off:0x%llx , size:0x%llx.\n",part_info->offset ,off,size); - - *blk = off >> blk_shift ; - *cnt = size >> blk_shift ; - *sz_byte = size - ((*cnt) << blk_shift) ; - - // printf("get_partition_off_size : blk:0x%llx , cnt:0x%llx.\n",*blk,*cnt); - return 0; + struct partitions *part_info = NULL; + uint64_t off = 0; + int blk_shift = 0; + + blk_shift = ffs(mmc->read_bl_len) - 1; + // printf("blk_shift:%d , off:0x%llx , size:0x%llx.\n ",blk_shift,off,size ); + part_info = find_mmc_partition_by_name(name); + if (part_info == NULL) { + printf("get partition info failed !!\n"); + return -1; + } + off = part_info->offset + offset; + + // printf("part_info->offset:0x%llx , off:0x%llx , size:0x%llx.\n",part_info->offset ,off,size); + + *blk = off >> blk_shift ; + *cnt = size >> blk_shift ; + *sz_byte = size - ((*cnt) << blk_shift) ; + + // printf("get_partition_off_size : blk:0x%llx , cnt:0x%llx.\n",*blk,*cnt); + return 0; } static int get_partition_size(unsigned char* name, uint64_t* addr) { - struct partitions *part_info = NULL; - part_info = find_mmc_partition_by_name((char *)name); - if (part_info == NULL) { - printf("get partition info failed !!\n"); - return -1; - } - - *addr = part_info->size >> 9; // unit: 512 bytes - return 0; + struct partitions *part_info = NULL; + part_info = find_mmc_partition_by_name((char *)name); + if (part_info == NULL) { + printf("get partition info failed !!\n"); + return -1; + } + + *addr = part_info->size >> 9; // unit: 512 bytes + return 0; } static inline int isstring(char *p) { - char *endptr = p; - while (*endptr != '\0') { - if (!(((*endptr >= '0') && (*endptr <= '9')) - || ((*endptr >= 'a') && (*endptr <= 'f')) - || ((*endptr >= 'A') && (*endptr <= 'F')) - || (*endptr == 'x') || (*endptr == 'X'))) - return 1; - endptr++; - } - - return 0; + char *endptr = p; + while (*endptr != '\0') { + if (!(((*endptr >= '0') && (*endptr <= '9')) + || ((*endptr >= 'a') && (*endptr <= 'f')) + || ((*endptr >= 'A') && (*endptr <= 'F')) + || (*endptr == 'x') || (*endptr == 'X'))) + return 1; + endptr++; + } + + return 0; } /* - erase bootloader on user/boot0/boot1 which indicate by map. - bit 0: user - bit 1: boot0 - bit 2: boot1 + erase bootloader on user/boot0/boot1 which indicate by map. + bit 0: user + bit 1: boot0 + bit 2: boot1 */ int amlmmc_erase_bootloader(int dev, int map) { - int ret = 0, i, count = 3; - int blk_shift; - unsigned long n; - char *partname[3] = {"user", "boot0", "boot1"}; - cpu_id_t cpu_id = get_cpu_id(); - struct mmc *mmc = find_mmc_device(dev); - - /* do nothing */ - if (0 == map) - goto _out; - - if (!mmc) { - printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev); - ret = -1; - goto _out; - } - /* make sure mmc is initilized! */ - ret = mmc_init(mmc); - if (ret) { - printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret); - ret = -2; - goto _out; - } - - blk_shift = ffs(mmc->read_bl_len) -1; - /* erase bootloader in user/boot0/boot1 */ - for (i = 0; i < count; i++) { - if (map & (0x1 << i)) { - if (!mmc_select_hwpart(dev, i)) { - lbaint_t start = 0, blkcnt; - - blkcnt = mmc->capacity >> blk_shift; - if (0 == i) { - struct partitions *part_info; - /* get info by partition */ - part_info = find_mmc_partition_by_name(MMC_BOOT_NAME); - if (part_info == NULL) { - printf("%s() %d: error!!\n", __func__, __LINE__); - /* fixme, do somthing! */ - continue; - } else { - start = part_info->offset>> blk_shift; - blkcnt = part_info->size>> blk_shift; - if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) { - start = GXL_START_BLK; - blkcnt -= GXL_START_BLK; - } - } - } + int ret = 0, i, count = 3; + int blk_shift; + unsigned long n; + char *partname[3] = {"user", "boot0", "boot1"}; + cpu_id_t cpu_id = get_cpu_id(); + struct mmc *mmc = find_mmc_device(dev); + + /* do nothing */ + if (0 == map) + goto _out; + + if (!mmc) { + printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev); + ret = -1; + goto _out; + } + /* make sure mmc is initilized! */ + ret = mmc_init(mmc); + if (ret) { + printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret); + ret = -2; + goto _out; + } + + blk_shift = ffs(mmc->read_bl_len) -1; + /* erase bootloader in user/boot0/boot1 */ + for (i = 0; i < count; i++) { + if (map & (0x1 << i)) { + if (!mmc_select_hwpart(dev, i)) { + lbaint_t start = 0, blkcnt; + + blkcnt = mmc->capacity >> blk_shift; + if (0 == i) { + struct partitions *part_info; + /* get info by partition */ + part_info = find_mmc_partition_by_name(MMC_BOOT_NAME); + if (part_info == NULL) { + printf("%s() %d: error!!\n", __func__, __LINE__); + /* fixme, do somthing! */ + continue; + } else { + start = part_info->offset>> blk_shift; + blkcnt = part_info->size>> blk_shift; + if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) { + start = GXL_START_BLK; + blkcnt -= GXL_START_BLK; + } + } + } /* some customer may use boot1 higher 2M as private data. */ #ifdef CONFIG_EMMC_BOOT1_TOUCH_REGION - if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= mmc->capacity) { - blkcnt = CONFIG_EMMC_BOOT1_TOUCH_REGION >> blk_shift; - } + if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= mmc->capacity) { + blkcnt = CONFIG_EMMC_BOOT1_TOUCH_REGION >> blk_shift; + } #endif/* CONFIG_EMMC_BOOT1_TOUCH_REGION */ - printf("Erasing blocks " LBAFU " to " LBAFU " @ %s\n", - start, blkcnt, partname[i]); - n = mmc->block_dev.block_erase(dev, start, blkcnt); - if (n != 0) { - printf("mmc erase %s failed\n", partname[i]); - ret = -3; - break; - } - } else - printf("%s() %d: switch dev %d to %s fail\n", - __func__, __LINE__, dev, partname[i]); - } - } - /* try to switch back to user. */ - mmc_select_hwpart(dev, 0); + printf("Erasing blocks " LBAFU " to " LBAFU " @ %s\n", + start, blkcnt, partname[i]); + n = mmc->block_dev.block_erase(dev, start, blkcnt); + if (n != 0) { + printf("mmc erase %s failed\n", partname[i]); + ret = -3; + break; + } + } else + printf("%s() %d: switch dev %d to %s fail\n", + __func__, __LINE__, dev, partname[i]); + } + } + /* try to switch back to user. */ + mmc_select_hwpart(dev, 0); _out: - return ret; + return ret; +} + +/* dtb read&write operation with backup updates */ +static u32 _calc_boot_info_checksum(struct storage_emmc_boot_info *boot_info) +{ + u32 *buffer = (u32*)boot_info; + u32 checksum = 0; + int i = 0; + + do { + checksum += buffer[i];
+ } while (i++ < ((EMMC_BOOT_INFO_SIZE >> 2) - 2)); + + return checksum; +} + +#define GET_RSERVED_BASE_ADDR() (_get_inherent_offset(MMC_RESERVED_NAME)) +static int amlmmc_write_info_sector(struct mmc *mmc, int dev) +{ + struct storage_emmc_boot_info *boot_info; + struct virtual_partition *ddr_part; + u8 *buffer; + int ret = 0; + + buffer = malloc(MMC_BLOCK_SIZE); + if (!buffer) + return -ENOMEM; + + memset(buffer, 0, sizeof(*boot_info)); + boot_info = (struct storage_emmc_boot_info *)buffer; + boot_info->rsv_base_addr = GET_RSERVED_BASE_ADDR() / MMC_BLOCK_SIZE; + ddr_part = aml_get_virtual_partition_by_name(MMC_DDR_PARAMETER_NAME); + boot_info->ddr.addr = ddr_part->offset / MMC_BLOCK_SIZE; + boot_info->ddr.size = ddr_part->size / MMC_BLOCK_SIZE; + boot_info->version = 1; + boot_info->checksum = _calc_boot_info_checksum(boot_info); + + printf("boot_info.rsv_base_addr\t:\t%04x\n", boot_info->rsv_base_addr); + printf("boot_info.ddr.addr\t:\t%04x\n", boot_info->ddr.addr); + printf("boot_info.ddr.size\t:\t%04x\n", boot_info->ddr.size); + printf("boot_info.version\t:\t%04x\n", boot_info->version); + printf("boot_info.checksum\t:\t%04x\n", boot_info->checksum); + + if (mmc->block_dev.block_write(dev, 0, 1, buffer) != 1) + ret = -EIO; + + free(buffer); + return ret; } /* - write bootloader on user/boot0/boot1 which indicate by map. - bit 0: user - bit 1: boot0 - bit 2: boot1 + write bootloader on user/boot0/boot1 which indicate by map. + bit 0: user + bit 1: boot0 + bit 2: boot1 */ int amlmmc_write_bootloader(int dev, int map, unsigned int size, const void *src) { - int ret = 0, i, count = 3; - unsigned long n; - char *partname[3] = {"user", "boot0", "boot1"}; - struct mmc *mmc = find_mmc_device(dev); - lbaint_t start = GXB_START_BLK, blkcnt; - cpu_id_t cpu_id = get_cpu_id(); - - /* do nothing */ - if (0 == map) - goto _out; - - if (!mmc) { - printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev); - ret = -1; - goto _out; - } - /* make sure mmc is initilized! */ - ret = mmc_init(mmc); - if (ret) { - printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret); - ret = -2; - goto _out; - } - - if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) - start = GXL_START_BLK; - blkcnt = (size + mmc->read_bl_len - 1) / mmc->read_bl_len; - - /* erase bootloader in user/boot0/boot1 */ - for (i = 0; i < count; i++) { - if (map & (0x1 << i)) { - if (!mmc_select_hwpart(dev, i)) { + int ret = 0, i, count = 3; + unsigned long n; + char *partname[3] = {"user", "boot0", "boot1"}; + struct mmc *mmc = find_mmc_device(dev); + lbaint_t start = GXB_START_BLK, blkcnt; + cpu_id_t cpu_id = get_cpu_id(); + + /* do nothing */ + if (0 == map) + goto _out; + + if (!mmc) { + printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev); + ret = -1; + goto _out; + } + /* make sure mmc is initilized! */ + ret = mmc_init(mmc); + if (ret) { + printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret); + ret = -2; + goto _out; + } +#ifdef MMC_NO_BOOT_PARTITION + map = map & ~AML_BL_BOOT; +#endif + if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) + start = GXL_START_BLK; + blkcnt = (size + mmc->read_bl_len - 1) / mmc->read_bl_len; + + /* erase bootloader in user/boot0/boot1 */ + for (i = 0; i < count; i++) { + if (map & (0x1 << i)) { + if (!mmc_select_hwpart(dev, i)) { /* some customer may use boot1 higher 2M as private data. */ #ifdef CONFIG_EMMC_BOOT1_TOUCH_REGION - if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= size) { - printf("%s(), size %d exceeds TOUCH_REGION %d, skip\n", - __func__, size, CONFIG_EMMC_BOOT1_TOUCH_REGION); - break; - } + if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= size) { + printf("%s(), size %d exceeds TOUCH_REGION %d, skip\n", + __func__, size, CONFIG_EMMC_BOOT1_TOUCH_REGION); + break; + } #endif /* CONFIG_EMMC_BOOT1_TOUCH_REGION */ - printf("Wrting blocks " LBAFU " to " LBAFU " @ %s\n", - start, blkcnt, partname[i]); - n = mmc->block_dev.block_write(dev, start, blkcnt, src); - if (n != blkcnt) { - printf("mmc write %s failed\n", partname[i]); - ret = -3; - break; - } - } else - printf("%s() %d: switch dev %d to %s fail\n", - __func__, __LINE__, dev, partname[i]); - } - } - /* try to switch back to user. */ - mmc_select_hwpart(dev, 0); + printf("Wrting blocks " LBAFU " to " LBAFU " @ %s\n", + start, blkcnt, partname[i]); + if (i != 0) + amlmmc_write_info_sector(mmc, dev); + n = mmc->block_dev.block_write(dev, start, blkcnt, src); + if (n != blkcnt) { + printf("mmc write %s failed\n", partname[i]); + ret = -3; + break; + } + } else + printf("%s() %d: switch dev %d to %s fail\n", + __func__, __LINE__, dev, partname[i]); + } + } + /* try to switch back to user. */ + mmc_select_hwpart(dev, 0); _out: - return ret; + return ret; } static int amlmmc_erase_in_dev(int argc, char *const argv[]) { - int dev = 0; - u64 cnt = 0, blk = 0, n = 0; - struct mmc *mmc; + int dev = 0; + u64 cnt = 0, blk = 0, n = 0; + struct mmc *mmc; - dev = simple_strtoul(argv[2], NULL, 10); - blk = simple_strtoull(argv[3], NULL, 16); - cnt = simple_strtoull(argv[4], NULL, 16); + dev = simple_strtoul(argv[2], NULL, 10); + blk = simple_strtoull(argv[3], NULL, 16); + cnt = simple_strtoull(argv[4], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) - return 1; + if (!mmc) + return 1; - printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ - several blocks # %lld will be erased ...\n ", - dev, blk, cnt); + printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ + several blocks # %lld will be erased ...\n ", + dev, blk, cnt); - mmc_init(mmc); + mmc_init(mmc); - if (cnt != 0) - n = mmc->block_dev.block_erase(dev, blk, cnt); + if (cnt != 0) + n = mmc->block_dev.block_erase(dev, blk, cnt); - printf("dev # %d, %s, several blocks erased %s\n", - dev, " ", (n == 0) ? "OK" : "ERROR"); + printf("dev # %d, %s, several blocks erased %s\n", + dev, " ", (n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; + return (n == 0) ? 0 : 1; } static int amlmmc_erase_in_card(int argc, char *const argv[]) { - int dev = 0; - u64 cnt = 0, blk = 0, n = 0; - /*sz_byte =0;*/ - char *name = NULL; - u64 offset_addr = 0, size = 0; - struct mmc *mmc; - int tmp_shift; + int dev = 0; + u64 cnt = 0, blk = 0, n = 0; + /*sz_byte =0;*/ + char *name = NULL; + u64 offset_addr = 0, size = 0; + struct mmc *mmc; + int tmp_shift; - name = argv[2]; - dev = find_dev_num_by_partition_name (name); - offset_addr = simple_strtoull(argv[3], NULL, 16); - size = simple_strtoull(argv[4], NULL, 16); - mmc = find_mmc_device(dev); + name = argv[2]; + dev = find_dev_num_by_partition_name (name); + offset_addr = simple_strtoull(argv[3], NULL, 16); + size = simple_strtoull(argv[4], NULL, 16); + mmc = find_mmc_device(dev); - tmp_shift = ffs(mmc->read_bl_len) -1; - cnt = size >> tmp_shift; - blk = offset_addr >> tmp_shift; - /* sz_byte = size - (cnt<<tmp_shift); */ + tmp_shift = ffs(mmc->read_bl_len) -1; + cnt = size >> tmp_shift; + blk = offset_addr >> tmp_shift; + /* sz_byte = size - (cnt<<tmp_shift); */ - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) - return 1; + if (!mmc) + return 1; - printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ - several blocks # %lld will be erased ...\n ", - dev, blk, cnt); + printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ + several blocks # %lld will be erased ...\n ", + dev, blk, cnt); - mmc_init(mmc); + mmc_init(mmc); - if (cnt != 0) - n = mmc->block_dev.block_erase(dev, blk, cnt); + if (cnt != 0) + n = mmc->block_dev.block_erase(dev, blk, cnt); - printf("dev # %d, %s, several blocks erased %s\n", - dev, argv[2], (n == 0) ? "OK" : "ERROR"); + printf("dev # %d, %s, several blocks erased %s\n", + dev, argv[2], (n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; + return (n == 0) ? 0 : 1; } static int amlmmc_erase_in_part(int argc, char *const argv[]) { - int dev = 0; - u64 cnt = 0, blk = 0, n = 0, sz_byte =0; - char *name = NULL; - u64 offset_addr = 0, size = 0; - struct mmc *mmc; - struct partitions *part_info; - - name = argv[2]; - dev = find_dev_num_by_partition_name (name); - offset_addr = simple_strtoull(argv[3], NULL, 16); - size = simple_strtoull(argv[4], NULL, 16); - part_info = find_mmc_partition_by_name(name); - mmc = find_mmc_device(dev); - - if (offset_addr >= part_info->size) { - printf("Start address out #%s# partition'address region,(addr_byte < 0x%llx)\n", - name, part_info->size); - return 1; - } - if ((offset_addr+size) > part_info->size) { - printf("End address exceeds #%s# partition,(offset = 0x%llx,size = 0x%llx)\n", - name, part_info->offset,part_info->size); - return 1; - } - get_off_size(mmc, name, offset_addr, size, &blk, &cnt, &sz_byte); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - - if (!mmc) - return 1; - - printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ - several blocks # %lld will be erased ...\n ", - dev, blk, cnt); - - mmc_init(mmc); - - if (cnt != 0) - n = mmc->block_dev.block_erase(dev, blk, cnt); - - printf("dev # %d, %s, several blocks erased %s\n", - dev, argv[2], (n == 0) ? "OK" : "ERROR"); - - return (n == 0) ? 0 : 1; + int dev = 0; + u64 cnt = 0, blk = 0, n = 0, sz_byte =0; + char *name = NULL; + u64 offset_addr = 0, size = 0; + struct mmc *mmc; + struct partitions *part_info; + + name = argv[2]; + dev = find_dev_num_by_partition_name (name); + offset_addr = simple_strtoull(argv[3], NULL, 16); + size = simple_strtoull(argv[4], NULL, 16); + part_info = find_mmc_partition_by_name(name); + mmc = find_mmc_device(dev); + if (!mmc) + return -ENODEV; + + if (offset_addr >= part_info->size) { + printf("Start address out #%s# partition'address region,(addr_byte < 0x%llx)\n", + name, part_info->size); + return 1; + } + if ((offset_addr+size) > part_info->size) { + printf("End address exceeds #%s# partition,(offset = 0x%llx,size = 0x%llx)\n", + name, part_info->offset,part_info->size); + return 1; + } + get_off_size(mmc, name, offset_addr, size, &blk, &cnt, &sz_byte); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\ + several blocks # %lld will be erased ...\n ", + dev, blk, cnt); + + mmc_init(mmc); + + if (cnt != 0) + n = mmc->block_dev.block_erase(dev, blk, cnt); + + printf("dev # %d, %s, several blocks erased %s\n", + dev, argv[2], (n == 0) ? "OK" : "ERROR"); + + return (n == 0) ? 0 : 1; } static int amlmmc_erase_by_add(int argc, char *const argv[]) { - int ret = 0; + int ret = 0; - if (argc != 5) - return CMD_RET_USAGE; + if (argc != 5) + return CMD_RET_USAGE; - if (isdigit(argv[2][0])) - ret = amlmmc_erase_in_dev(argc, argv); - else if (strcmp(argv[2], "card") == 0) - ret = amlmmc_erase_in_card(argc, argv); - else if (isstring(argv[2])) - ret = amlmmc_erase_in_part(argc, argv); + if (isdigit(argv[2][0])) + ret = amlmmc_erase_in_dev(argc, argv); + else if (strcmp(argv[2], "card") == 0) + ret = amlmmc_erase_in_card(argc, argv); + else if (isstring(argv[2])) + ret = amlmmc_erase_in_part(argc, argv); - return ret; + return ret; } static int amlmmc_erase_non_loader(int argc, char *const argv[]) { - int dev; - u32 n = 0; - int blk_shift; - u64 blk = 0, start_blk = 0; - struct partitions *part_info; - struct mmc *mmc; - - dev = 1; - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - - if (!mmc) - return 1; - - mmc_init(mmc); - - blk_shift = ffs(mmc->read_bl_len) -1; - part_info = find_mmc_partition_by_name(MMC_BOOT_NAME); - - if (part_info == NULL) { - start_blk = 0; - printf("no uboot partition for eMMC boot, just erase from 0\n"); - } - else - start_blk = (part_info->offset + part_info->size) >> blk_shift; - - if (emmckey_is_protected(mmc)) { - part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); - if (part_info == NULL) { - return 1; - } - blk = part_info->offset; - // it means: there should be other partitions before reserve-partition. - if (blk > 0) - blk -= PARTITION_RESERVED; - blk >>= blk_shift; - blk -= start_blk; - // (1) erase all the area before reserve-partition - if (blk > 0) - n = mmc->block_dev.block_erase(dev, start_blk, blk); - if (n == 0) { // not error - // (2) erase all the area after reserve-partition - start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) - >> blk_shift; - u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; - n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); - } - } else { - n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card - } - return (n == 0) ? 0 : 1; + int dev; + u32 n = 0; + int blk_shift; + u64 blk = 0, start_blk = 0; + struct partitions *part_info; + struct mmc *mmc; + + dev = 1; + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + + if (!mmc) + return 1; + + mmc_init(mmc); + + blk_shift = ffs(mmc->read_bl_len) -1; + part_info = find_mmc_partition_by_name(MMC_BOOT_NAME); + + if (part_info == NULL) { + start_blk = 0; + printf("no uboot partition for eMMC boot, just erase from 0\n"); + } + else + start_blk = (part_info->offset + part_info->size) >> blk_shift; + + if (emmckey_is_protected(mmc)) { + part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); + if (part_info == NULL) { + return 1; + } + blk = part_info->offset; + // it means: there should be other partitions before reserve-partition. + if (blk > 0) + blk -= PARTITION_RESERVED; + blk >>= blk_shift; + blk -= start_blk; + // (1) erase all the area before reserve-partition + if (blk > 0) + n = mmc->block_dev.block_erase(dev, start_blk, blk); + if (n == 0) { // not error + // (2) erase all the area after reserve-partition + start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) + >> blk_shift; + u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; + n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); + } + } else { + n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card + } + return (n == 0) ? 0 : 1; } static int amlmmc_erase_single_part(int argc, char *const argv[]) { - char *name = NULL; - int dev; - u32 n = 0; - int blk_shift; - u64 cnt = 0, blk = 0; - struct partitions *part_info; - struct mmc *mmc; - name = argv[2]; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - - if (!mmc) - return 1; - - mmc_init(mmc); - - blk_shift = ffs(mmc->read_bl_len) -1; - if (emmckey_is_protected(mmc) - && (strncmp(name, MMC_RESERVED_NAME, sizeof(MMC_RESERVED_NAME)) == 0x00)) { - printf("\"%s-partition\" is been protecting and should no be erased!\n", - MMC_RESERVED_NAME); - return 1; - } - - part_info = find_mmc_partition_by_name(name); - if (part_info == NULL) { - return 1; - } - - blk = part_info->offset >> blk_shift; - if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader"))) - cnt = mmc->boot_size >> blk_shift; - else - cnt = part_info->size >> blk_shift; - n = mmc->block_dev.block_erase(dev, blk, cnt); - - return (n == 0) ? 0 : 1; + char *name = NULL; + int dev; + u32 n = 0; + int blk_shift; + u64 cnt = 0, blk = 0; + struct partitions *part_info; + struct mmc *mmc; + name = argv[2]; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + + if (!mmc) + return 1; + + mmc_init(mmc); + + blk_shift = ffs(mmc->read_bl_len) -1; + if (emmckey_is_protected(mmc) + && (strncmp(name, MMC_RESERVED_NAME, sizeof(MMC_RESERVED_NAME)) == 0x00)) { + printf("\"%s-partition\" is been protecting and should no be erased!\n", + MMC_RESERVED_NAME); + return 1; + } + + part_info = find_mmc_partition_by_name(name); + if (part_info == NULL) { + return 1; + } + + blk = part_info->offset >> blk_shift; + if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader"))) + cnt = mmc->boot_size >> blk_shift; + else + cnt = part_info->size >> blk_shift; + n = mmc->block_dev.block_erase(dev, blk, cnt); + + return (n == 0) ? 0 : 1; } static int amlmmc_erase_whole(int argc, char *const argv[]) { - char *name = NULL; - int dev; - u32 n = 0; - int blk_shift; - //u64 cnt = 0, - u64 blk = 0, start_blk = 0; - struct partitions *part_info; - struct mmc *mmc; - int map; - - name = "logo"; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - mmc_init(mmc); - blk_shift = ffs(mmc->read_bl_len) -1; - start_blk = 0; - - if (emmckey_is_protected(mmc)) { - part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); - if (part_info == NULL) { - return 1; - } - blk = part_info->offset; - // it means: there should be other partitions before reserve-partition. - if (blk > 0) - blk -= PARTITION_RESERVED; - blk >>= blk_shift; - blk -= start_blk; - // (1) erase all the area before reserve-partition - if (blk > 0) - n = mmc->block_dev.block_erase(dev, start_blk, blk); - if (n == 0) { // not error - // (2) erase all the area after reserve-partition - start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) - >> blk_shift; - u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; - n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); - } - } else { - n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card - } - map = AML_BL_BOOT; - if (n == 0) - n = amlmmc_erase_bootloader(dev, map); - if (n) - printf("erase bootloader in boot partition failed\n"); - return (n == 0) ? 0 : 1; + char *name = NULL; + int dev; + u32 n = 0; + int blk_shift; + //u64 cnt = 0, + u64 blk = 0, start_blk = 0; + struct partitions *part_info; + struct mmc *mmc; + int map; + + name = "logo"; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + mmc_init(mmc); + blk_shift = ffs(mmc->read_bl_len) -1; + start_blk = 0; + + if (emmckey_is_protected(mmc)) { + part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); + if (part_info == NULL) { + return 1; + } + blk = part_info->offset; + // it means: there should be other partitions before reserve-partition. + if (blk > 0) + blk -= PARTITION_RESERVED; + blk >>= blk_shift; + blk -= start_blk; + // (1) erase all the area before reserve-partition + if (blk > 0) + n = mmc->block_dev.block_erase(dev, start_blk, blk); + if (n == 0) { // not error + // (2) erase all the area after reserve-partition + start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) + >> blk_shift; + u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; + n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); + } + } else { + n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card + } + map = AML_BL_BOOT; + if (n == 0) + n = amlmmc_erase_bootloader(dev, map); + if (n) + printf("erase bootloader in boot partition failed\n"); + return (n == 0) ? 0 : 1; } static int amlmmc_erase_non_cache(int arc, char *const argv[]) { - char *name = NULL; - int dev; - u32 n = 0; - int blk_shift; - u64 blk = 0, start_blk = 0; - struct partitions *part_info; - struct mmc *mmc; - int map; - - name = "logo"; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - mmc_init(mmc); - blk_shift = ffs(mmc->read_bl_len) -1; - if (emmckey_is_protected(mmc)) { - part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); - if (part_info == NULL) { - return 1; - } - - blk = part_info->offset; - // it means: there should be other partitions before reserve-partition. - if (blk > 0) { - blk -= PARTITION_RESERVED; - } - blk >>= blk_shift; - blk -= start_blk; - // (1) erase all the area before reserve-partition - if (blk > 0) { - n = mmc->block_dev.block_erase(dev, start_blk, blk); - // printf("(1) erase blk: 0 --> %llx %s\n", blk, (n == 0) ? "OK" : "ERROR"); - } - if (n == 0) { // not error - // (2) erase all the area after reserve-partition - part_info = find_mmc_partition_by_name(MMC_CACHE_NAME); - if (part_info == NULL) { - return 1; - } - start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) - >> blk_shift; - u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; - n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); - } - } else { - n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card - } - map = AML_BL_BOOT; - if (n == 0) { - n = amlmmc_erase_bootloader(dev, map); - if (n) - printf("erase bootloader in boot partition failed\n"); - } - return (n == 0) ? 0 : 1; + char *name = NULL; + int dev; + u32 n = 0; + int blk_shift; + u64 blk = 0, start_blk = 0; + struct partitions *part_info; + struct mmc *mmc; + int map; + + name = "logo"; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + mmc_init(mmc); + blk_shift = ffs(mmc->read_bl_len) -1; + if (emmckey_is_protected(mmc)) { + part_info = find_mmc_partition_by_name(MMC_RESERVED_NAME); + if (part_info == NULL) { + return 1; + } + + blk = part_info->offset; + // it means: there should be other partitions before reserve-partition. + if (blk > 0) { + blk -= PARTITION_RESERVED; + } + blk >>= blk_shift; + blk -= start_blk; + // (1) erase all the area before reserve-partition + if (blk > 0) { + n = mmc->block_dev.block_erase(dev, start_blk, blk); + // printf("(1) erase blk: 0 --> %llx %s\n", blk, (n == 0) ? "OK" : "ERROR"); + } + if (n == 0) { // not error + // (2) erase all the area after reserve-partition + part_info = find_mmc_partition_by_name(MMC_CACHE_NAME); + if (part_info == NULL) { + return 1; + } + start_blk = (part_info->offset + part_info->size + PARTITION_RESERVED) + >> blk_shift; + u64 erase_cnt = (mmc->capacity >> blk_shift) - start_blk; + n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt); + } + } else { + n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card + } + map = AML_BL_BOOT; + if (n == 0) { + n = amlmmc_erase_bootloader(dev, map); + if (n) + printf("erase bootloader in boot partition failed\n"); + } + return (n == 0) ? 0 : 1; } static int amlmmc_erase_dev(int argc, char *const argv[]) { - return amlmmc_erase_whole(argc, argv); + return amlmmc_erase_whole(argc, argv); } static int amlmmc_erase_allbootloader(int argc, char*const argv[]) { - int map; - int rc; - char *name = NULL; - int dev; - map = AML_BL_ALL; - - name = "bootloader"; - dev = find_dev_num_by_partition_name(name); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - rc = amlmmc_erase_bootloader(dev, map); - return rc; + int map; + int rc; + char *name = NULL; + int dev; + map = AML_BL_ALL; + + name = "bootloader"; + dev = find_dev_num_by_partition_name(name); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + rc = amlmmc_erase_bootloader(dev, map); + return rc; } static int amlmmc_erase_by_part(int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; - - if (argc != 3) - return ret; - - if (isdigit(argv[2][0])) - ret = amlmmc_erase_dev(argc, argv); - else if (strcmp(argv[2], "whole") == 0) - ret = amlmmc_erase_whole(argc, argv); - else if (strcmp(argv[2], "non_cache") == 0) - ret = amlmmc_erase_non_cache(argc, argv); - else if (strcmp(argv[2], "non_loader") == 0) - ret = amlmmc_erase_non_loader(argc, argv); - else if (strcmp(argv[2], "allbootloader") == 0) - ret = amlmmc_erase_allbootloader(argc, argv); - else - ret = amlmmc_erase_single_part(argc, argv); - return ret; + int ret = CMD_RET_USAGE; + + if (argc != 3) + return ret; + + if (isdigit(argv[2][0])) + ret = amlmmc_erase_dev(argc, argv); + else if (strcmp(argv[2], "whole") == 0) + ret = amlmmc_erase_whole(argc, argv); + else if (strcmp(argv[2], "non_cache") == 0) + ret = amlmmc_erase_non_cache(argc, argv); + else if (strcmp(argv[2], "non_loader") == 0) + ret = amlmmc_erase_non_loader(argc, argv); + else if (strcmp(argv[2], "allbootloader") == 0) + ret = amlmmc_erase_allbootloader(argc, argv); + else + ret = amlmmc_erase_single_part(argc, argv); + return ret; } static int do_amlmmc_erase(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; + int ret = CMD_RET_USAGE; - if (argc == 3) - ret = amlmmc_erase_by_part(argc, argv); - else if (argc == 5) - ret = amlmmc_erase_by_add(argc, argv); + if (argc == 3) + ret = amlmmc_erase_by_part(argc, argv); + else if (argc == 5) + ret = amlmmc_erase_by_add(argc, argv); - return ret; + return ret; } static int amlmmc_write_in_part(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; - char *name = NULL; - u64 offset = 0, size = 0; - cpu_id_t cpu_id = get_cpu_id(); - struct mmc *mmc; - - name = argv[2]; - if (strcmp(name, "bootloader") == 0) - dev = CONFIG_SYS_MMC_BOOT_DEV; - else - dev = find_dev_num_by_partition_name (name); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - offset = simple_strtoull(argv[4], NULL, 16); - size = simple_strtoull(argv[5], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - if (strcmp(name, "bootloader") == 0) { - cnt = UBOOT_SIZE; - if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) { - blk = GXL_START_BLK; - cnt -= GXL_START_BLK; - } - else - blk = GXB_START_BLK; - } else - get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte); - - mmc_init(mmc); - n = mmc->block_dev.block_write(dev, blk, cnt, addr); - //write sz_byte bytes - if ((n == cnt) && (sz_byte != 0)) { - // printf("sz_byte=%#llx bytes\n",sz_byte); - void *addr_tmp = malloc(mmc->write_bl_len); - void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len)); - ulong start_blk = blk+cnt; - - if (addr_tmp == NULL) { - printf("mmc write: malloc fail\n"); - return 1; - } - - if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block - free(addr_tmp); - printf("mmc read 1 block fail\n"); - return 1; - } - - memcpy(addr_tmp, addr_byte, sz_byte); - if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block - free(addr_tmp); - printf("mmc write 1 block fail\n"); - return 1; - } - free(addr_tmp); - } - //printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; + int dev, ret; + void *addr = NULL; + u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; + char *name = NULL; + u64 offset = 0, size = 0; + struct mmc *mmc; + + name = argv[2]; + if (strcmp(name, "bootloader") == 0) + dev = CONFIG_SYS_MMC_BOOT_DEV; + else + dev = find_dev_num_by_partition_name (name); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + offset = simple_strtoull(argv[4], NULL, 16); + size = simple_strtoull(argv[5], NULL, 16); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + mmc_init(mmc); + + if (strcmp(name, "bootloader") == 0) { + ret = amlmmc_write_bootloader(dev, AML_BL_ALL, size, addr); + return ret; + } else + get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte); + + n = mmc->block_dev.block_write(dev, blk, cnt, addr); + //write sz_byte bytes + if ((n == cnt) && (sz_byte != 0)) { + // printf("sz_byte=%#llx bytes\n",sz_byte); + void *addr_tmp = malloc(mmc->write_bl_len); + void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len)); + ulong start_blk = blk+cnt; + + if (addr_tmp == NULL) { + printf("mmc write: malloc fail\n"); + return 1; + } + + if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block + free(addr_tmp); + printf("mmc read 1 block fail\n"); + return 1; + } + + memcpy(addr_tmp, addr_byte, sz_byte); + if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block + free(addr_tmp); + printf("mmc write 1 block fail\n"); + return 1; + } + free(addr_tmp); + } + //printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR"); + return (n == cnt) ? 0 : 1; } static int amlmmc_write_in_card(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; - char *name = NULL; - u64 offset = 0, size = 0; - struct mmc *mmc; - - name = argv[2]; - dev = find_dev_num_by_partition_name (name); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - offset = simple_strtoull(argv[4], NULL, 16); - size = simple_strtoull(argv[5], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - int blk_shift = ffs( mmc->read_bl_len) -1; - cnt = size >> blk_shift; - blk = offset >> blk_shift; - sz_byte = size - (cnt<<blk_shift); - mmc_init(mmc); - - n = mmc->block_dev.block_write(dev, blk, cnt, addr); - - //write sz_byte bytes - if ((n == cnt) && (sz_byte != 0)) { - // printf("sz_byte=%#llx bytes\n",sz_byte); - void *addr_tmp = malloc(mmc->write_bl_len); - void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len)); - ulong start_blk = blk+cnt; - - if (addr_tmp == NULL) { - printf("mmc write: malloc fail\n"); - return 1; - } - - if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block - free(addr_tmp); - printf("mmc read 1 block fail\n"); - return 1; - } - - memcpy(addr_tmp, addr_byte, sz_byte); - if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block - free(addr_tmp); - printf("mmc write 1 block fail\n"); - return 1; - } - free(addr_tmp); - } - //printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; + int dev; + void *addr = NULL; + u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; + char *name = NULL; + u64 offset = 0, size = 0; + struct mmc *mmc; + + name = argv[2]; + dev = find_dev_num_by_partition_name (name); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + offset = simple_strtoull(argv[4], NULL, 16); + size = simple_strtoull(argv[5], NULL, 16); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + int blk_shift = ffs( mmc->read_bl_len) -1; + cnt = size >> blk_shift; + blk = offset >> blk_shift; + sz_byte = size - (cnt<<blk_shift); + mmc_init(mmc); + + n = mmc->block_dev.block_write(dev, blk, cnt, addr); + + //write sz_byte bytes + if ((n == cnt) && (sz_byte != 0)) { + // printf("sz_byte=%#llx bytes\n",sz_byte); + void *addr_tmp = malloc(mmc->write_bl_len); + void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len)); + ulong start_blk = blk+cnt; + + if (addr_tmp == NULL) { + printf("mmc write: malloc fail\n"); + return 1; + } + + if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block + free(addr_tmp); + printf("mmc read 1 block fail\n"); + return 1; + } + + memcpy(addr_tmp, addr_byte, sz_byte); + if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block + free(addr_tmp); + printf("mmc write 1 block fail\n"); + return 1; + } + free(addr_tmp); + } + //printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR"); + return (n == cnt) ? 0 : 1; } static int amlmmc_write_in_dev(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - u64 cnt = 0, n = 0, blk = 0; - struct mmc *mmc; - dev = simple_strtoul(argv[2], NULL, 10); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - blk = simple_strtoull(argv[4], NULL, 16); - cnt = simple_strtoull(argv[5], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - //printf("MMC write: dev # %d, block # %#llx, count # %#llx ... ", - //dev, blk, cnt); - - mmc_init(mmc); - - n = mmc->block_dev.block_write(dev, blk, cnt, addr); - return (n == cnt) ? 0 : 1; + int dev; + void *addr = NULL; + u64 cnt = 0, n = 0, blk = 0; + struct mmc *mmc; + dev = simple_strtoul(argv[2], NULL, 10); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + blk = simple_strtoull(argv[4], NULL, 16); + cnt = simple_strtoull(argv[5], NULL, 16); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + //printf("MMC write: dev # %d, block # %#llx, count # %#llx ... ", + //dev, blk, cnt); + + mmc_init(mmc); + + n = mmc->block_dev.block_write(dev, blk, cnt, addr); + return (n == cnt) ? 0 : 1; } static int do_amlmmc_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = 0; - if (argc != 6) - return CMD_RET_USAGE; - - if (isdigit(argv[2][0])) - ret = amlmmc_write_in_dev(argc, argv); - else if (strcmp(argv[2], "card") == 0) - ret = amlmmc_write_in_card(argc, argv); - else if (isstring(argv[2])) - ret = amlmmc_write_in_part(argc, argv); - - return ret; + int ret = 0; + if (argc != 6) + return CMD_RET_USAGE; + + if (isdigit(argv[2][0])) + ret = amlmmc_write_in_dev(argc, argv); + else if (strcmp(argv[2], "card") == 0) + ret = amlmmc_write_in_card(argc, argv); + else if (isstring(argv[2])) + ret = amlmmc_write_in_part(argc, argv); + + return ret; } static int amlmmc_read_in_dev(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - u64 cnt =0, n = 0, blk = 0; - struct mmc *mmc; - - dev = simple_strtoul(argv[2], NULL, 10); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - blk = simple_strtoull(argv[4], NULL, 16); - cnt = simple_strtoull(argv[5], NULL, 16); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - n = mmc->block_dev.block_read(dev, blk, cnt, addr); - return (n == cnt) ? 0 : 1; + int dev; + void *addr = NULL; + u64 cnt =0, n = 0, blk = 0; + struct mmc *mmc; + + dev = simple_strtoul(argv[2], NULL, 10); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + blk = simple_strtoull(argv[4], NULL, 16); + cnt = simple_strtoull(argv[5], NULL, 16); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + n = mmc->block_dev.block_read(dev, blk, cnt, addr); + return (n == cnt) ? 0 : 1; } static int amlmmc_read_in_card(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - //u32 flag =0; - u64 cnt =0, n = 0, blk = 0, sz_byte = 0; - char *name = NULL; - u64 offset = 0, size = 0; - int blk_shift; - struct mmc *mmc; - void *addr_tmp; - void *addr_byte; - ulong start_blk; - - name = argv[2]; - dev = find_dev_num_by_partition_name (name); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - size = simple_strtoull(argv[5], NULL, 16); - offset = simple_strtoull(argv[4], NULL, 16); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - blk_shift = ffs( mmc->read_bl_len) - 1; - cnt = size >> blk_shift; - blk = offset >> blk_shift; - sz_byte = size - (cnt<<blk_shift); - - mmc_init(mmc); - n = mmc->block_dev.block_read(dev, blk, cnt, addr); - - //read sz_byte bytes - if ((n == cnt) && (sz_byte != 0)) { - addr_tmp = malloc(mmc->read_bl_len); - addr_byte = (void *)(addr+cnt*(mmc->read_bl_len)); - start_blk = blk+cnt; - if (addr_tmp == NULL) { - printf("mmc read: malloc fail\n"); - return 1; - } - if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block - free(addr_tmp); - printf("mmc read 1 block fail\n"); - return 1; - } - memcpy(addr_byte, addr_tmp, sz_byte); - free(addr_tmp); - } - return (n == cnt) ? 0 : 1; + int dev; + void *addr = NULL; + //u32 flag =0; + u64 cnt =0, n = 0, blk = 0, sz_byte = 0; + char *name = NULL; + u64 offset = 0, size = 0; + int blk_shift; + struct mmc *mmc; + void *addr_tmp; + void *addr_byte; + ulong start_blk; + + name = argv[2]; + dev = find_dev_num_by_partition_name (name); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + size = simple_strtoull(argv[5], NULL, 16); + offset = simple_strtoull(argv[4], NULL, 16); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + blk_shift = ffs( mmc->read_bl_len) - 1; + cnt = size >> blk_shift; + blk = offset >> blk_shift; + sz_byte = size - (cnt<<blk_shift); + + mmc_init(mmc); + n = mmc->block_dev.block_read(dev, blk, cnt, addr); + + //read sz_byte bytes + if ((n == cnt) && (sz_byte != 0)) { + addr_tmp = malloc(mmc->read_bl_len); + addr_byte = (void *)(addr+cnt*(mmc->read_bl_len)); + start_blk = blk+cnt; + if (addr_tmp == NULL) { + printf("mmc read: malloc fail\n"); + return 1; + } + if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block + free(addr_tmp); + printf("mmc read 1 block fail\n"); + return 1; + } + memcpy(addr_byte, addr_tmp, sz_byte); + free(addr_tmp); + } + return (n == cnt) ? 0 : 1; } static int amlmmc_read_in_part(int argc, char *const argv[]) { - int dev; - void *addr = NULL; - u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; - char *name = NULL; - u64 offset = 0, size = 0; - struct mmc *mmc; - void *addr_tmp; - void *addr_byte; - ulong start_blk; - - name = argv[2]; - dev = find_dev_num_by_partition_name (name); - addr = (void *)simple_strtoul(argv[3], NULL, 16); - offset = simple_strtoull(argv[4], NULL, 16); - size = simple_strtoull(argv[5], NULL, 16); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte); - mmc_init(mmc); - n = mmc->block_dev.block_read(dev, blk, cnt, addr); - - //read sz_byte bytes - if ((n == cnt) && (sz_byte != 0)) { - /*printf("sz_byte=%#llx bytes\n",sz_byte);*/ - addr_tmp = malloc(mmc->read_bl_len); - addr_byte = (void *)(addr+cnt*(mmc->read_bl_len)); - start_blk = blk+cnt; - - if (addr_tmp == NULL) { - printf("mmc read: malloc fail\n"); - return 1; - } - - if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block - free(addr_tmp); - printf("mmc read 1 block fail\n"); - return 1; - } - - memcpy(addr_byte, addr_tmp, sz_byte); - free(addr_tmp); - } - return (n == cnt) ? 0 : 1; + int dev; + void *addr = NULL; + u64 cnt = 0, n = 0, blk = 0, sz_byte = 0; + char *name = NULL; + u64 offset = 0, size = 0; + struct mmc *mmc; + void *addr_tmp; + void *addr_byte; + ulong start_blk; + + name = argv[2]; + dev = find_dev_num_by_partition_name (name); + addr = (void *)simple_strtoul(argv[3], NULL, 16); + offset = simple_strtoull(argv[4], NULL, 16); + size = simple_strtoull(argv[5], NULL, 16); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte); + mmc_init(mmc); + n = mmc->block_dev.block_read(dev, blk, cnt, addr); + + //read sz_byte bytes + if ((n == cnt) && (sz_byte != 0)) { + /*printf("sz_byte=%#llx bytes\n",sz_byte);*/ + addr_tmp = malloc(mmc->read_bl_len); + addr_byte = (void *)(addr+cnt*(mmc->read_bl_len)); + start_blk = blk+cnt; + + if (addr_tmp == NULL) { + printf("mmc read: malloc fail\n"); + return 1; + } + + if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block + free(addr_tmp); + printf("mmc read 1 block fail\n"); + return 1; + } + + memcpy(addr_byte, addr_tmp, sz_byte); + free(addr_tmp); + } + return (n == cnt) ? 0 : 1; } static int do_amlmmc_read(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = 0; + int ret = 0; - if (argc != 6) - return CMD_RET_USAGE; + if (argc != 6) + return CMD_RET_USAGE; - if (isdigit(argv[2][0])) - ret = amlmmc_read_in_dev(argc, argv); - else if (strcmp(argv[2], "card") == 0) - ret = amlmmc_read_in_card(argc, argv); - else if (isstring(argv[2])) - ret = amlmmc_read_in_part(argc, argv); + if (isdigit(argv[2][0])) + ret = amlmmc_read_in_dev(argc, argv); + else if (strcmp(argv[2], "card") == 0) + ret = amlmmc_read_in_card(argc, argv); + else if (isstring(argv[2])) + ret = amlmmc_read_in_part(argc, argv); - return ret; + return ret; } static int do_amlmmc_env(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - printf("herh\n"); - env_relocate(); - return 0; + printf("herh\n"); + env_relocate(); + return 0; } static int do_amlmmc_list(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - print_mmc_devices('\n'); - return 0; + print_mmc_devices('\n'); + return 0; } static int do_amlmmc_size(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - char *name; - uint64_t* addr = NULL; - int dev; - struct mmc *mmc = NULL; - - if (argc != 4) - return CMD_RET_USAGE; - - name = argv[2]; - addr = (uint64_t *)simple_strtoul(argv[3], NULL, 16); - if (!strcmp(name, "wholeDev")) { - dev = CONFIG_SYS_MMC_BOOT_DEV; - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - - *addr = mmc->capacity >> 9; // unit: 512 bytes - return 0; - } - return get_partition_size((unsigned char *)name, addr); + char *name; + uint64_t* addr = NULL; + int dev; + struct mmc *mmc = NULL; + + if (argc != 4) + return CMD_RET_USAGE; + + name = argv[2]; + addr = (uint64_t *)simple_strtoul(argv[3], NULL, 16); + if (!strcmp(name, "wholeDev")) { + dev = CONFIG_SYS_MMC_BOOT_DEV; + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + + *addr = mmc->capacity >> 9; // unit: 512 bytes + return 0; + } + return get_partition_size((unsigned char *)name, addr); } static int amlmmc_get_ext_csd(int argc, char *const argv[]) { - int ret= 0; - u8 ext_csd[512] = {0}; - int dev, byte; - struct mmc *mmc; - - if (argc != 4) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - byte = simple_strtoul(argv[3], NULL, 10); - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - ret = mmc_get_ext_csd(mmc, ext_csd); - printf("read EXT_CSD byte[%d] val[0x%x] %s\n", - byte, ext_csd[byte], (ret == 0) ? "ok" : "fail"); - ret = ret || ret; - return ret; + int ret= 0; + u8 ext_csd[512] = {0}; + int dev, byte; + struct mmc *mmc; + + if (argc != 4) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + byte = simple_strtoul(argv[3], NULL, 10); + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + ret = mmc_get_ext_csd(mmc, ext_csd); + printf("read EXT_CSD byte[%d] val[0x%x] %s\n", + byte, ext_csd[byte], (ret == 0) ? "ok" : "fail"); + ret = ret || ret; + return ret; } static int amlmmc_set_ext_csd(int argc, char *const argv[]) { - int ret = 0; - int dev, byte; - struct mmc *mmc; - int val; - - if (argc != 5) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - byte = simple_strtoul(argv[3], NULL, 10); - val = simple_strtoul(argv[4], NULL, 16); - if ((byte > 191) || (byte < 0)) { - printf("byte is not able to write!\n"); - return 1; - } - - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - - ret = mmc_set_ext_csd(mmc, byte, val); - printf("write EXT_CSD byte[%d] val[0x%x] %s\n", - byte, val, (ret == 0) ? "ok" : "fail"); - ret =ret || ret; - return ret; + int ret = 0; + int dev, byte; + struct mmc *mmc; + int val; + + if (argc != 5) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + byte = simple_strtoul(argv[3], NULL, 10); + val = simple_strtoul(argv[4], NULL, 16); + if ((byte > 191) || (byte < 0)) { + printf("byte is not able to write!\n"); + return 1; + } + + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + + ret = mmc_set_ext_csd(mmc, byte, val); + printf("write EXT_CSD byte[%d] val[0x%x] %s\n", + byte, val, (ret == 0) ? "ok" : "fail"); + ret =ret || ret; + return ret; } static int do_amlmmc_ext_csd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; + int ret = CMD_RET_USAGE; - if (argc == 4) - ret = amlmmc_get_ext_csd(argc,argv); - else if (argc == 5) - ret = amlmmc_set_ext_csd(argc,argv); + if (argc == 4) + ret = amlmmc_get_ext_csd(argc,argv); + else if (argc == 5) + ret = amlmmc_set_ext_csd(argc,argv); - return ret; + return ret; } static int do_amlmmc_switch(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int rc = 0; - int dev; - struct mmc *mmc; - - if (argc != 4) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - printf("mmc switch to "); - - if (strcmp(argv[3], "boot0") == 0) { - rc = mmc_switch_part(dev, 1); - if (rc == 0) { - emmc_cur_partition = 1; - printf("boot0 success\n"); - } else { - printf("boot0 failed\n"); - } - } - else if(strcmp(argv[3], "boot1") == 0) { - rc = mmc_switch_part(dev, 2); - if (rc == 0) { - emmc_cur_partition = 2; - printf("boot1 success\n"); - } else { - printf("boot1 failed\n"); - } - } - else if(strcmp(argv[3], "user") == 0) { - rc = mmc_switch_part(dev, 0); - if (rc == 0) { - emmc_cur_partition = 0; - printf("user success\n"); - } else { - printf("user failed\n"); - } - } + int rc = 0; + int dev; + struct mmc *mmc; + + if (argc != 4) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + printf("mmc switch to "); + + if (strcmp(argv[3], "boot0") == 0) { + rc = mmc_switch_part(dev, 1); + if (rc == 0) { + emmc_cur_partition = 1; + printf("boot0 success\n"); + } else { + printf("boot0 failed\n"); + } + } + else if(strcmp(argv[3], "boot1") == 0) { + rc = mmc_switch_part(dev, 2); + if (rc == 0) { + emmc_cur_partition = 2; + printf("boot1 success\n"); + } else { + printf("boot1 failed\n"); + } + } + else if(strcmp(argv[3], "user") == 0) { + rc = mmc_switch_part(dev, 0); + if (rc == 0) { + emmc_cur_partition = 0; + printf("user success\n"); + } else { + printf("user failed\n"); + } + } #ifdef CONFIG_SUPPORT_EMMC_RPMB - else if(strcmp(argv[3], "rpmb") == 0) { - rc = mmc_switch_part(dev, 3); - if (rc == 0) { - emmc_cur_partition = 3; - printf("rpmb success\n"); - } else { - printf("rpmb failed\n"); - } - } + else if(strcmp(argv[3], "rpmb") == 0) { + rc = mmc_switch_part(dev, 3); + if (rc == 0) { + emmc_cur_partition = 3; + printf("rpmb success\n"); + } else { + printf("rpmb failed\n"); + } + } #endif - else - printf("%s failed\n", argv[3]); - return rc; + else + printf("%s failed\n", argv[3]); + return rc; } static int do_amlmmc_controller(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int dev; - struct mmc *mmc; - struct aml_card_sd_info *aml_priv; - struct sd_emmc_global_regs *sd_emmc_reg; - - if (argc != 3) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - - if (!mmc) - return 1; - - aml_priv = mmc->priv; - sd_emmc_reg = aml_priv->sd_emmc_reg; - - printf("sd_emmc_reg->gclock = 0x%x\n", sd_emmc_reg->gclock); - printf("sd_emmc_reg->gdelay = 0x%x\n", sd_emmc_reg->gdelay); - printf("sd_emmc_reg->gadjust = 0x%x\n", sd_emmc_reg->gadjust); - printf("sd_emmc_reg->gcalout = 0x%x\n", sd_emmc_reg->gcalout); - if (!mmc->has_init) { - printf("mmc dev %d has not been initialed\n", dev); - return 1; - } - printf("sd_emmc_reg->gstart = 0x%x\n", sd_emmc_reg->gstart); - printf("sd_emmc_reg->gcfg = 0x%x\n", sd_emmc_reg->gcfg); - printf("sd_emmc_reg->gstatus = 0x%x\n", sd_emmc_reg->gstatus); - printf("sd_emmc_reg->girq_en = 0x%x\n", sd_emmc_reg->girq_en); - printf("sd_emmc_reg->gcmd_cfg = 0x%x\n", sd_emmc_reg->gcmd_cfg); - printf("sd_emmc_reg->gcmd_arg = 0x%x\n", sd_emmc_reg->gcmd_arg); - printf("sd_emmc_reg->gcmd_dat = 0x%x\n", sd_emmc_reg->gcmd_dat); - printf("sd_emmc_reg->gcmd_rsp0 = 0x%x\n", sd_emmc_reg->gcmd_rsp0); - printf("sd_emmc_reg->gcmd_rsp1 = 0x%x\n", sd_emmc_reg->gcmd_rsp1); - printf("sd_emmc_reg->gcmd_rsp2 = 0x%x\n", sd_emmc_reg->gcmd_rsp2); - printf("sd_emmc_reg->gcmd_rsp3 = 0x%x\n", sd_emmc_reg->gcmd_rsp3); - return 0; + int dev; + struct mmc *mmc; + struct aml_card_sd_info *aml_priv; + struct sd_emmc_global_regs *sd_emmc_reg; + + if (argc != 3) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + + if (!mmc) + return 1; + + aml_priv = mmc->priv; + sd_emmc_reg = aml_priv->sd_emmc_reg; + + printf("sd_emmc_reg->gclock = 0x%x\n", sd_emmc_reg->gclock); + printf("sd_emmc_reg->gdelay = 0x%x\n", sd_emmc_reg->gdelay); + printf("sd_emmc_reg->gadjust = 0x%x\n", sd_emmc_reg->gadjust); + printf("sd_emmc_reg->gcalout = 0x%x\n", sd_emmc_reg->gcalout); + if (!mmc->has_init) { + printf("mmc dev %d has not been initialed\n", dev); + return 1; + } + printf("sd_emmc_reg->gstart = 0x%x\n", sd_emmc_reg->gstart); + printf("sd_emmc_reg->gcfg = 0x%x\n", sd_emmc_reg->gcfg); + printf("sd_emmc_reg->gstatus = 0x%x\n", sd_emmc_reg->gstatus); + printf("sd_emmc_reg->girq_en = 0x%x\n", sd_emmc_reg->girq_en); + printf("sd_emmc_reg->gcmd_cfg = 0x%x\n", sd_emmc_reg->gcmd_cfg); + printf("sd_emmc_reg->gcmd_arg = 0x%x\n", sd_emmc_reg->gcmd_arg); + printf("sd_emmc_reg->gcmd_dat = 0x%x\n", sd_emmc_reg->gcmd_dat); + printf("sd_emmc_reg->gcmd_rsp0 = 0x%x\n", sd_emmc_reg->gcmd_rsp0); + printf("sd_emmc_reg->gcmd_rsp1 = 0x%x\n", sd_emmc_reg->gcmd_rsp1); + printf("sd_emmc_reg->gcmd_rsp2 = 0x%x\n", sd_emmc_reg->gcmd_rsp2); + printf("sd_emmc_reg->gcmd_rsp3 = 0x%x\n", sd_emmc_reg->gcmd_rsp3); + return 0; } static int do_amlmmc_response(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int dev; - struct mmc *mmc; - struct aml_card_sd_info *aml_priv; - struct sd_emmc_global_regs *sd_emmc_reg; + int dev; + struct mmc *mmc; + struct aml_card_sd_info *aml_priv; + struct sd_emmc_global_regs *sd_emmc_reg; - if (argc != 3) - return CMD_RET_USAGE; + if (argc != 3) + return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); + dev = simple_strtoul(argv[2], NULL, 10); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) - return 1; - if (!mmc->has_init) { - printf("mmc dev %d has not been initialed\n", dev); - return 1; - } + if (!mmc) + return 1; + if (!mmc->has_init) { + printf("mmc dev %d has not been initialed\n", dev); + return 1; + } - aml_priv = mmc->priv; - sd_emmc_reg = aml_priv->sd_emmc_reg; + aml_priv = mmc->priv; + sd_emmc_reg = aml_priv->sd_emmc_reg; - printf("last cmd = %d, response0 = 0x%x\n", - (sd_emmc_reg->gcmd_cfg & 0x3f), sd_emmc_reg->gcmd_rsp0); - return 0; + printf("last cmd = %d, response0 = 0x%x\n", + (sd_emmc_reg->gcmd_cfg & 0x3f), sd_emmc_reg->gcmd_rsp0); + return 0; } static int do_amlmmc_status(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int rc = 0; - int dev; - struct mmc *mmc; - - if (argc != 3) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - - if (!mmc) - return 1; - if (!mmc->has_init) { - printf("mmc dev %d has not been initialed\n", dev); - return 1; - } - rc = mmc_read_status(mmc, 1000); - if (rc) - return 1; - else - return 0; + int rc = 0; + int dev; + struct mmc *mmc; + + if (argc != 3) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + + if (!mmc) + return 1; + if (!mmc->has_init) { + printf("mmc dev %d has not been initialed\n", dev); + return 1; + } + rc = mmc_read_status(mmc, 1000); + if (rc) + return 1; + else + return 0; } static int do_amlmmc_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev; - block_dev_desc_t *mmc_dev; - struct mmc *mmc; - - if (argc != 3) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - mmc_dev = mmc_get_dev(dev); - if (mmc_dev != NULL && - mmc_dev->type != DEV_TYPE_UNKNOWN) { - print_part(mmc_dev); - return 0; - } - puts("get mmc type error!\n"); - return 1; + int dev; + block_dev_desc_t *mmc_dev; + struct mmc *mmc; + + if (argc != 3) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + mmc_dev = mmc_get_dev(dev); + if (mmc_dev != NULL && + mmc_dev->type != DEV_TYPE_UNKNOWN) { + print_part(mmc_dev); + return 0; + } + puts("get mmc type error!\n"); + return 1; } static int do_amlmmc_rescan(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev; - struct mmc *mmc; + int dev; + struct mmc *mmc; - if (argc != 3) - return CMD_RET_USAGE; + if (argc != 3) + return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); + dev = simple_strtoul(argv[2], NULL, 10); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) - return 1; + if (!mmc) + return 1; - return mmc_init(mmc); + return mmc_init(mmc); } #ifdef CONFIG_SECURITYKEY static int do_amlmmc_key(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - struct mmc *mmc; - int dev; - - //char *name = "logo"; - dev = CONFIG_SYS_MMC_BOOT_DEV; - mmc = find_mmc_device(dev); - if (!mmc) { - printf("device %d is invalid\n",dev); - return 1; - } - //mmc->key_protect = 0; + struct mmc *mmc; + int dev; + + //char *name = "logo"; + dev = CONFIG_SYS_MMC_BOOT_DEV; + mmc = find_mmc_device(dev); + if (!mmc) { + printf("device %d is invalid\n",dev); + return 1; + } + //mmc->key_protect = 0; #ifdef CONFIG_STORE_COMPATIBLE - info_disprotect |= DISPROTECT_KEY; //disprotect - printf("emmc disprotect key\n"); + info_disprotect |= DISPROTECT_KEY; //disprotect + printf("emmc disprotect key\n"); #endif - return 0; + return 0; } #endif static int set_write_prot(struct mmc *mmc, u64 start) { - struct mmc_cmd cmd; - int err; + struct mmc_cmd cmd; + int err; - cmd.cmdidx = MMC_CMD_SET_WRITE_PROTECT; - cmd.cmdarg = start; - cmd.resp_type = MMC_RSP_R1b; + cmd.cmdidx = MMC_CMD_SET_WRITE_PROTECT; + cmd.cmdarg = start; + cmd.resp_type = MMC_RSP_R1b; - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + goto err_out; - return 0; + return 0; err_out: - puts("Failed: mmc write protect failed\n"); - return err; + puts("Failed: mmc write protect failed\n"); + return err; } static int set_us_wp_en(struct mmc *mmc, u8 *ext_csd, u8 wp_enable_type) { - u8 index = EXT_CSD_USER_WP; - u8 user_wp = ext_csd[index]; - user_wp = user_wp & (~WP_ENABLE_MASK); - user_wp = user_wp | wp_enable_type; - int err = 0; - err = mmc_set_ext_csd(mmc, index, user_wp); - if (err) - printf("Failed: set write protect enable failed\n"); - return err; + u8 index = EXT_CSD_USER_WP; + u8 user_wp = ext_csd[index]; + user_wp = user_wp & (~WP_ENABLE_MASK); + user_wp = user_wp | wp_enable_type; + int err = 0; + err = mmc_set_ext_csd(mmc, index, user_wp); + if (err) + printf("Failed: set write protect enable failed\n"); + return err; } static int mmc_set_us_perm_wp_dis(struct mmc *mmc, u8 *ext_csd) { - u8 usr_wp = ext_csd[EXT_CSD_USER_WP]; - u8 perm_disable_bit = US_PERM_WP_DIS_BIT; - - int err; - if (usr_wp & perm_disable_bit) - return 0; - - usr_wp = usr_wp | perm_disable_bit; - err = mmc_set_ext_csd(mmc, EXT_CSD_USER_WP, usr_wp); - if (err) { - printf("Failed: set permanent write protect disable failed\n"); - return 1; - } - return 0; + u8 usr_wp = ext_csd[EXT_CSD_USER_WP]; + u8 perm_disable_bit = US_PERM_WP_DIS_BIT; + + int err; + if (usr_wp & perm_disable_bit) + return 0; + + usr_wp = usr_wp | perm_disable_bit; + err = mmc_set_ext_csd(mmc, EXT_CSD_USER_WP, usr_wp); + if (err) { + printf("Failed: set permanent write protect disable failed\n"); + return 1; + } + return 0; } static int mmc_is_us_pwr_wp_dis(u8 user_wp) @@ -1664,2393 +1711,2392 @@ static int mmc_is_us_perm_wp_dis(u8 user_wp) static int check_wp_type(u8 *addr, u8 wp_type, u64 set_protect_cnt) { - u8 type_mask = WP_TYPE_MASK; - u64 cnt = set_protect_cnt; - u8 times = 0; - u8 index = 7; - u8 cur_group_wp_type = addr[index]; - - while (cnt != 0) { - if (wp_type != ((type_mask)&(cur_group_wp_type))) { - return 1; - } - if (times == 3) { - times = 0; - index--; - cur_group_wp_type = addr[index]; - } - else { - cur_group_wp_type = cur_group_wp_type >> 2; - times++; - } - cnt--; - } - return 0; + u8 type_mask = WP_TYPE_MASK; + u64 cnt = set_protect_cnt; + u8 times = 0; + u8 index = 7; + u8 cur_group_wp_type = addr[index]; + + while (cnt != 0) { + if (wp_type != ((type_mask)&(cur_group_wp_type))) { + return 1; + } + if (times == 3) { + times = 0; + index--; + cur_group_wp_type = addr[index]; + } + else { + cur_group_wp_type = cur_group_wp_type >> 2; + times++; + } + cnt--; + } + return 0; } static int set_register_to_temporary(struct mmc *mmc, u8 *ext_csd) { - int err; - u8 wp_enable_type = WP_TEMPORARY_EN_BIT; - err = set_us_wp_en(mmc, ext_csd, wp_enable_type); - if (err) - printf("Failed: set temporary write protect failed\n"); - return err; + int err; + u8 wp_enable_type = WP_TEMPORARY_EN_BIT; + err = set_us_wp_en(mmc, ext_csd, wp_enable_type); + if (err) + printf("Failed: set temporary write protect failed\n"); + return err; } static int set_register_to_pwr(struct mmc *mmc, u8 *ext_csd) { - int err; - u8 user_wp = ext_csd[EXT_CSD_USER_WP]; - u8 wp_enable_type = WP_POWER_ON_EN_BIT; - if (mmc_is_us_pwr_wp_dis(user_wp)) { - printf("Failed: power on protection had been disabled\n"); - return 1; - } - - err = mmc_set_us_perm_wp_dis(mmc, ext_csd); - if (err) { - printf("Failed: set permanent protection diable failed\n"); - return 1; - } - - err = set_us_wp_en(mmc, ext_csd, wp_enable_type); - if (err) { - printf("Failed: set power on write protect enable failed\n"); - return 1; - } - return 0; + int err; + u8 user_wp = ext_csd[EXT_CSD_USER_WP]; + u8 wp_enable_type = WP_POWER_ON_EN_BIT; + if (mmc_is_us_pwr_wp_dis(user_wp)) { + printf("Failed: power on protection had been disabled\n"); + return 1; + } + + err = mmc_set_us_perm_wp_dis(mmc, ext_csd); + if (err) { + printf("Failed: set permanent protection diable failed\n"); + return 1; + } + + err = set_us_wp_en(mmc, ext_csd, wp_enable_type); + if (err) { + printf("Failed: set power on write protect enable failed\n"); + return 1; + } + return 0; } static int set_register_to_perm(struct mmc *mmc, u8 *ext_csd) { - int err; - u8 wp_enable_type = WP_PERM_EN_BIT; - u8 user_wp = ext_csd[EXT_CSD_USER_WP]; - - if (mmc_is_us_perm_wp_dis(user_wp)) { - printf("Failed: Permanent protection had been disabled\n"); - return 1; - } - - err = set_us_wp_en(mmc, ext_csd, wp_enable_type); - if (err) { - printf("Failed: set permanent write protect enable failed\n"); - return 1; - } - return 0; + int err; + u8 wp_enable_type = WP_PERM_EN_BIT; + u8 user_wp = ext_csd[EXT_CSD_USER_WP]; + + if (mmc_is_us_perm_wp_dis(user_wp)) { + printf("Failed: Permanent protection had been disabled\n"); + return 1; + } + + err = set_us_wp_en(mmc, ext_csd, wp_enable_type); + if (err) { + printf("Failed: set permanent write protect enable failed\n"); + return 1; + } + return 0; } static int set_wp_register(struct mmc *mmc, u8 *ext_csd, u8 wp_type) { - int ret = 1; - if (wp_type == WP_POWER_ON_TYPE) - ret = set_register_to_pwr(mmc, ext_csd); - else if (wp_type == WP_PERMANENT_TYPE) - ret = set_register_to_perm(mmc, ext_csd); - else if (wp_type == WP_TEMPORARY_TYPE) - ret = set_register_to_temporary(mmc, ext_csd); - return ret; + int ret = 1; + if (wp_type == WP_POWER_ON_TYPE) + ret = set_register_to_pwr(mmc, ext_csd); + else if (wp_type == WP_PERMANENT_TYPE) + ret = set_register_to_perm(mmc, ext_csd); + else if (wp_type == WP_TEMPORARY_TYPE) + ret = set_register_to_temporary(mmc, ext_csd); + return ret; } static u64 write_protect_group_size(struct mmc *mmc, u8 *ext_csd) { - int erase_group_def = ext_csd[EXT_CSD_ERASE_GROUP_DEF]; - u64 write_protect_group_size; - int wp_grp_size = mmc->csd[2] & WP_GRP_SIZE_MASK; - int hc_wp_grp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + int erase_group_def = ext_csd[EXT_CSD_ERASE_GROUP_DEF]; + u64 write_protect_group_size; + int wp_grp_size = mmc->csd[2] & WP_GRP_SIZE_MASK; + int hc_wp_grp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - if (erase_group_def == 0) - write_protect_group_size = (wp_grp_size + 1) * mmc->erase_grp_size; - else - write_protect_group_size = hc_wp_grp_size * mmc->erase_grp_size; + if (erase_group_def == 0) + write_protect_group_size = (wp_grp_size + 1) * mmc->erase_grp_size; + else + write_protect_group_size = hc_wp_grp_size * mmc->erase_grp_size; - return write_protect_group_size; + return write_protect_group_size; } int is_write_protect_valid(u8 *ext_csd) { - u8 class_6_ctrl = ext_csd[EXT_CSD_CLASS_6_CTRL]; - if (class_6_ctrl == 0) - return 1; - return 0; + u8 class_6_ctrl = ext_csd[EXT_CSD_CLASS_6_CTRL]; + if (class_6_ctrl == 0) + return 1; + return 0; } static int compute_write_protect_range(struct mmc *mmc, char *name, - u8 *ext_csd, u64 *wp_grp_size_addr, u64 *start_addr, u64 *end) -{ - int blk_shift; - struct partitions *part_info; - u64 cnt; - u64 start = *start_addr; - u64 align_start = *start_addr; - u64 wp_grp_size = *wp_grp_size_addr; - u64 group_num ; - u64 partition_end; - - wp_grp_size = write_protect_group_size(mmc, ext_csd); - - blk_shift = ffs(mmc->read_bl_len) -1; - - part_info = find_mmc_partition_by_name(name); - if (part_info == NULL) - return 1; - - start = part_info->offset >> blk_shift; - if ((start % wp_grp_size)) { - align_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; - printf("Caution! The partition start address isn't' aligned" - "to group size\n" - "the start address is change from 0x%llx to 0x%llx\n", - start, align_start); - } else { - align_start = start; - } - if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader"))) - cnt = mmc->boot_size >> blk_shift; - else - cnt = part_info->size >> blk_shift; - if (cnt < wp_grp_size) { - printf("Caution: The partition size is 0x%llx sector smaller than " - "the group size 0x%llx sector, \n" - "so the partition can't be protect\n", cnt, wp_grp_size); - return 1; - } - - *start_addr = align_start; - *wp_grp_size_addr = wp_grp_size; - partition_end = start + cnt - 1; - group_num = (cnt - (align_start - start)) / wp_grp_size; - *end = align_start + group_num * wp_grp_size - 1; - - if (partition_end != *end) { - printf("Caution! The boundary of partition isn't aligned with write " - "protected group,\n" - "so the write protected boundry of the " - "partition is 0x%llx, rather than 0x%llx\n", - *end, partition_end); - } - - printf("write_protect group size is 0x%llx sector\n", wp_grp_size); - printf("The %s partition write protect group number is %lld\n", name, group_num); + u8 *ext_csd, u64 *wp_grp_size_addr, u64 *start_addr, u64 *end) +{ + int blk_shift; + struct partitions *part_info; + u64 cnt; + u64 start = *start_addr; + u64 align_start = *start_addr; + u64 wp_grp_size = *wp_grp_size_addr; + u64 group_num ; + u64 partition_end; + + wp_grp_size = write_protect_group_size(mmc, ext_csd); + + blk_shift = ffs(mmc->read_bl_len) -1; + + part_info = find_mmc_partition_by_name(name); + if (part_info == NULL) + return 1; + + start = part_info->offset >> blk_shift; + if ((start % wp_grp_size)) { + align_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; + printf("Caution! The partition start address isn't' aligned" + "to group size\n" + "the start address is change from 0x%llx to 0x%llx\n", + start, align_start); + } else { + align_start = start; + } + if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader"))) + cnt = mmc->boot_size >> blk_shift; + else + cnt = part_info->size >> blk_shift; + if (cnt < wp_grp_size) { + printf("Caution: The partition size is 0x%llx sector smaller than " + "the group size 0x%llx sector, \n" + "so the partition can't be protect\n", cnt, wp_grp_size); + return 1; + } + + *start_addr = align_start; + *wp_grp_size_addr = wp_grp_size; + partition_end = start + cnt - 1; + group_num = (cnt - (align_start - start)) / wp_grp_size; + *end = align_start + group_num * wp_grp_size - 1; + + if (partition_end != *end) { + printf("Caution! The boundary of partition isn't aligned with write " + "protected group,\n" + "so the write protected boundry of the " + "partition is 0x%llx, rather than 0x%llx\n", + *end, partition_end); + } + + printf("write_protect group size is 0x%llx sector\n", wp_grp_size); + printf("The %s partition write protect group number is %lld\n", name, group_num); #ifdef WP_DEBUG - printf("the start address is 0x%llx, group size is 0x%llx, end is 0x%llx\n", - *start_addr, *wp_grp_size_addr, *end); + printf("the start address is 0x%llx, group size is 0x%llx, end is 0x%llx\n", + *start_addr, *wp_grp_size_addr, *end); #endif - return 0; + return 0; } static int send_wp_prot_type(struct mmc *mmc, void *dst, u64 blk) { - struct mmc_cmd cmd; - int err; - struct mmc_data data; + struct mmc_cmd cmd; + int err; + struct mmc_data data; - cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT_TYPE; - cmd.cmdarg = blk; - cmd.resp_type = MMC_RSP_R1; + cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT_TYPE; + cmd.cmdarg = blk; + cmd.resp_type = MMC_RSP_R1; - data.dest = dst; - data.blocks = 1; - data.blocksize = 8; - data.flags = MMC_DATA_READ; + data.dest = dst; + data.blocks = 1; + data.blocksize = 8; + data.flags = MMC_DATA_READ; - err = mmc_send_cmd(mmc, &cmd, &data); - if (err) - goto err_out; + err = mmc_send_cmd(mmc, &cmd, &data); + if (err) + goto err_out; - return 0; + return 0; err_out: - puts("Failed: mmc send write protect type failed\n"); - return err; + puts("Failed: mmc send write protect type failed\n"); + return err; } static int is_wp_set_failed(struct mmc *mmc, u8 wp_type, u64 start, u64 group_cnt) { - u8 *addr = NULL; - u8 err = 0; + u8 *addr = NULL; + u8 err = 0; - addr = malloc(sizeof(u64)); - if (addr == NULL) { - printf("Failed: malloc failed\n"); - return 1; - } + addr = malloc(sizeof(u64)); + if (addr == NULL) { + printf("Failed: malloc failed\n"); + return 1; + } - err = send_wp_prot_type(mmc, addr, start); - if (err) - goto err_out; + err = send_wp_prot_type(mmc, addr, start); + if (err) + goto err_out; #ifdef WP_DEBUG - int i; - for (i = 0; i < 8; i++) - printf("write_protect status is %x\n", ((u8 *)addr)[i]); + int i; + for (i = 0; i < 8; i++) + printf("write_protect status is %x\n", ((u8 *)addr)[i]); #endif - if (check_wp_type(addr, wp_type, group_cnt)) { - printf("Failed: Write Protection set failed\n"); - goto err_out; - } - return 0; + if (check_wp_type(addr, wp_type, group_cnt)) { + printf("Failed: Write Protection set failed\n"); + goto err_out; + } + return 0; err_out: - free(addr); - return 1; + free(addr); + return 1; } static int send_part_wp_type(struct mmc *mmc, char *name) { - int err = 0; - u8 ext_csd[512] = {0}; - u64 wp_grp_size, start, part_end; - u64 group_start; - void *addr = NULL; - int i; - int ret; - - ret = mmc_get_ext_csd(mmc, ext_csd); - if (ret) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - addr = malloc(sizeof(u64)); - if (addr == NULL) { - printf("Failed: malloc failed\n"); - return 1; - } - - err = compute_write_protect_range(mmc, name, ext_csd, - &wp_grp_size, &start, &part_end); - if (err) - return 1; - - group_start = start; - - while ((group_start + wp_grp_size - 1) <= part_end) { - err = send_wp_prot_type(mmc, addr, group_start); - if (err) - return 1; - printf("The write protect type for the 32 groups after 0x%llx is: \n0x", - group_start); - for (i = 0; i < 8; i++) - printf("%02x", ((u8*)addr)[i]); - printf("\n"); - group_start += 32 * wp_grp_size; - } - return 0; + int err = 0; + u8 ext_csd[512] = {0}; + u64 wp_grp_size, start, part_end; + u64 group_start; + void *addr = NULL; + int i; + int ret; + + ret = mmc_get_ext_csd(mmc, ext_csd); + if (ret) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + addr = malloc(sizeof(u64)); + if (addr == NULL) { + printf("Failed: malloc failed\n"); + return 1; + } + + err = compute_write_protect_range(mmc, name, ext_csd, + &wp_grp_size, &start, &part_end); + if (err) + return 1; + + group_start = start; + + while ((group_start + wp_grp_size - 1) <= part_end) { + err = send_wp_prot_type(mmc, addr, group_start); + if (err) + return 1; + printf("The write protect type for the 32 groups after 0x%llx is: \n0x", + group_start); + for (i = 0; i < 8; i++) + printf("%02x", ((u8*)addr)[i]); + printf("\n"); + group_start += 32 * wp_grp_size; + } + return 0; } static int send_add_wp_type(struct mmc *mmc, u64 start, u64 cnt) { - u8 ext_csd[512] = {0}; - u64 wp_grp_size = 0; - u64 part_end = 0; - u64 group_start; - u64 mmc_boundary; - int blk_shift; - void *addr = NULL; - int i; - int ret; - - ret = mmc_get_ext_csd(mmc, ext_csd); - if (ret) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - addr = malloc(sizeof(u64)); - if (addr == NULL) { - printf("Failed: malloc failed\n"); - return 1; - } - - wp_grp_size = write_protect_group_size(mmc, ext_csd); + u8 ext_csd[512] = {0}; + u64 wp_grp_size = 0; + u64 part_end = 0; + u64 group_start; + u64 mmc_boundary; + int blk_shift; + void *addr = NULL; + int i; + int ret; + + ret = mmc_get_ext_csd(mmc, ext_csd); + if (ret) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + addr = malloc(sizeof(u64)); + if (addr == NULL) { + printf("Failed: malloc failed\n"); + return 1; + } + + wp_grp_size = write_protect_group_size(mmc, ext_csd); if ((start % wp_grp_size)) { - group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; - printf("Caution! The partition start address isn't' aligned" - "to group size\n" - "the start address is change from 0x%llx to 0x%llx\n", - start, group_start); - part_end = group_start + (cnt - 1) * wp_grp_size - 1; - printf("The write protect group number is 0x%llx, rather than 0x%lld\n", - cnt - 1, cnt); - } else { - group_start = start; - part_end = group_start + cnt * wp_grp_size - 1; - } - - blk_shift = ffs(mmc->read_bl_len) - 1; - mmc_boundary = mmc->capacity>>blk_shift; - - if ((part_end + 1) > mmc_boundary) { - printf("Error: the operation cross the boundary of mmc\n"); - return 1; - } - - while ((group_start + wp_grp_size - 1) <= part_end) { - ret = send_wp_prot_type(mmc, addr, group_start); - if (ret) - return 1; - printf("The write protect type for the 32 groups after 0x%llx is: \n0x", - group_start); - for (i = 0; i < 8; i++) - printf("%02x", ((u8*)addr)[i]); - printf("\n"); - group_start += 32 * wp_grp_size; - } - return 0; + group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; + printf("Caution! The partition start address isn't' aligned" + "to group size\n" + "the start address is change from 0x%llx to 0x%llx\n", + start, group_start); + part_end = group_start + (cnt - 1) * wp_grp_size - 1; + printf("The write protect group number is 0x%llx, rather than 0x%lld\n", + cnt - 1, cnt); + } else { + group_start = start; + part_end = group_start + cnt * wp_grp_size - 1; + } + + blk_shift = ffs(mmc->read_bl_len) - 1; + mmc_boundary = mmc->capacity>>blk_shift; + + if ((part_end + 1) > mmc_boundary) { + printf("Error: the operation cross the boundary of mmc\n"); + return 1; + } + + while ((group_start + wp_grp_size - 1) <= part_end) { + ret = send_wp_prot_type(mmc, addr, group_start); + if (ret) + return 1; + printf("The write protect type for the 32 groups after 0x%llx is: \n0x", + group_start); + for (i = 0; i < 8; i++) + printf("%02x", ((u8*)addr)[i]); + printf("\n"); + group_start += 32 * wp_grp_size; + } + return 0; } static int set_part_write_protect(struct mmc *mmc, u8 wp_type, char *name) { - int err = 0; - u8 ext_csd[512] = {0}; - u8 group_num = 32; - u64 wp_grp_size, start, part_end; - u64 group_start; - u64 check_group_start; - u64 set_protect_cnt = 0; - - err = mmc_get_ext_csd(mmc, ext_csd); - if (err) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - err = compute_write_protect_range(mmc, name, ext_csd, - &wp_grp_size, &start, &part_end); - if (err) - return 1; - - group_start = start; - err = set_wp_register(mmc, ext_csd, wp_type); - if (err) - return 1; - while ((group_start + wp_grp_size - 1) <= part_end) { - err = set_write_prot(mmc, group_start); - if (err) - return 1; - group_start += wp_grp_size; - set_protect_cnt++; + int err = 0; + u8 ext_csd[512] = {0}; + u8 group_num = 32; + u64 wp_grp_size, start, part_end; + u64 group_start; + u64 check_group_start; + u64 set_protect_cnt = 0; + + err = mmc_get_ext_csd(mmc, ext_csd); + if (err) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + err = compute_write_protect_range(mmc, name, ext_csd, + &wp_grp_size, &start, &part_end); + if (err) + return 1; + + group_start = start; + err = set_wp_register(mmc, ext_csd, wp_type); + if (err) + return 1; + while ((group_start + wp_grp_size - 1) <= part_end) { + err = set_write_prot(mmc, group_start); + if (err) + return 1; + group_start += wp_grp_size; + set_protect_cnt++; //check write protect type every 32 group - if (set_protect_cnt % 32 == 0) { - check_group_start = group_start - group_num * wp_grp_size; - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - } - - group_num = set_protect_cnt % 32; - check_group_start = group_start - group_num * wp_grp_size; - - if (group_num) { - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - - return 0; + if (set_protect_cnt % 32 == 0) { + check_group_start = group_start - group_num * wp_grp_size; + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + } + + group_num = set_protect_cnt % 32; + check_group_start = group_start - group_num * wp_grp_size; + + if (group_num) { + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + + return 0; } static int set_add_write_protect(struct mmc *mmc, u8 wp_type, u64 start, u64 cnt) { - int err = 0; - u8 ext_csd[512] = {0}; - int group_num = 32; - u64 wp_grp_size, part_end; - u64 group_start; - u64 check_group_start; - u64 set_protect_cnt = 0; - u64 mmc_boundary = 0; - int blk_shift; - err = mmc_get_ext_csd(mmc, ext_csd); - - if (err) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - if (err) - return 1; - - wp_grp_size = write_protect_group_size(mmc, ext_csd); - - if ((start % wp_grp_size)) { - group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; - printf("Caution! The partition start address isn't' aligned" - "to group size\n" - "the start address is change from 0x%llx to 0x%llx\n", - start, group_start); - part_end = group_start + (cnt - 1) * wp_grp_size - 1; - printf("The write protect group number is 0x%llx, rather than 0x%lld\n", - cnt - 1, cnt); - } else { - group_start = start; - part_end = group_start + cnt * wp_grp_size - 1; - } - - blk_shift = ffs(mmc->read_bl_len) - 1; - mmc_boundary = mmc->capacity>>blk_shift; - - if ((part_end + 1) > mmc_boundary) { - printf("Error: the operation cross the boundary of mmc\n"); - return 1; - } - - err = set_wp_register(mmc, ext_csd, wp_type); - if (err) - return 1; - - while ((group_start + wp_grp_size - 1) <= part_end) { - err = set_write_prot(mmc, group_start); - if (err) - return 1; - group_start += wp_grp_size; - set_protect_cnt++; + int err = 0; + u8 ext_csd[512] = {0}; + int group_num = 32; + u64 wp_grp_size, part_end; + u64 group_start; + u64 check_group_start; + u64 set_protect_cnt = 0; + u64 mmc_boundary = 0; + int blk_shift; + err = mmc_get_ext_csd(mmc, ext_csd); + + if (err) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + if (err) + return 1; + + wp_grp_size = write_protect_group_size(mmc, ext_csd); + + if ((start % wp_grp_size)) { + group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; + printf("Caution! The partition start address isn't' aligned" + "to group size\n" + "the start address is change from 0x%llx to 0x%llx\n", + start, group_start); + part_end = group_start + (cnt - 1) * wp_grp_size - 1; + printf("The write protect group number is 0x%llx, rather than 0x%lld\n", + cnt - 1, cnt); + } else { + group_start = start; + part_end = group_start + cnt * wp_grp_size - 1; + } + + blk_shift = ffs(mmc->read_bl_len) - 1; + mmc_boundary = mmc->capacity>>blk_shift; + + if ((part_end + 1) > mmc_boundary) { + printf("Error: the operation cross the boundary of mmc\n"); + return 1; + } + + err = set_wp_register(mmc, ext_csd, wp_type); + if (err) + return 1; + + while ((group_start + wp_grp_size - 1) <= part_end) { + err = set_write_prot(mmc, group_start); + if (err) + return 1; + group_start += wp_grp_size; + set_protect_cnt++; //check write protect type every 32 group - if (set_protect_cnt % 32 == 0) { - check_group_start = group_start - group_num * wp_grp_size; - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - } - - group_num = set_protect_cnt % 32; - check_group_start = group_start - group_num * wp_grp_size; - - if (group_num) { - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - - return 0; + if (set_protect_cnt % 32 == 0) { + check_group_start = group_start - group_num * wp_grp_size; + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + } + + group_num = set_protect_cnt % 32; + check_group_start = group_start - group_num * wp_grp_size; + + if (group_num) { + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + + return 0; } static int do_amlmmc_write_protect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; - struct mmc *mmc; - int dev = 1; - char *name = NULL; - char *wp_type_str = NULL; - u8 write_protect_type; - u64 start, cnt; - - if (argc > 5 || argc < 4) - return ret; - if (argc == 4) { - name = argv[2]; - wp_type_str = argv[3]; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Error: Cannot find dev.\n"); - return CMD_RET_USAGE; - } - } else { - start = simple_strtoull(argv[2], NULL, 16); - cnt = simple_strtoull(argv[3], NULL, 0); - wp_type_str = argv[4]; - } - - mmc = find_mmc_device(dev); - - if (IS_SD(mmc)) { - mmc = find_mmc_device(~dev); - if (IS_SD(mmc)) { - printf("SD card can not be write protect\n"); - return 1; - } - } - - if (!mmc) - return 1; - - mmc_init(mmc); - if (!mmc) - return 1; - - if (strcmp(wp_type_str, "temporary") == 0) - write_protect_type = WP_TEMPORARY_TYPE; - else if (strcmp(wp_type_str, "power_on") == 0 ) - write_protect_type = WP_POWER_ON_TYPE; - else if (strcmp(wp_type_str, "permanent") == 0) - write_protect_type = WP_PERMANENT_TYPE; - else - return ret; - - if (argc == 4) - ret = set_part_write_protect(mmc, write_protect_type, name); - else - ret = set_add_write_protect(mmc, write_protect_type, start, cnt); - - return ret; + int ret = CMD_RET_USAGE; + struct mmc *mmc; + int dev = 1; + char *name = NULL; + char *wp_type_str = NULL; + u8 write_protect_type; + u64 start, cnt; + + if (argc > 5 || argc < 4) + return ret; + if (argc == 4) { + name = argv[2]; + wp_type_str = argv[3]; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Error: Cannot find dev.\n"); + return CMD_RET_USAGE; + } + } else { + start = simple_strtoull(argv[2], NULL, 16); + cnt = simple_strtoull(argv[3], NULL, 0); + wp_type_str = argv[4]; + } + + mmc = find_mmc_device(dev); + + if (IS_SD(mmc)) { + mmc = find_mmc_device(~dev); + if (IS_SD(mmc)) { + printf("SD card can not be write protect\n"); + return 1; + } + } + + if (!mmc) + return 1; + + mmc_init(mmc); + if (!mmc) + return 1; + + if (strcmp(wp_type_str, "temporary") == 0) + write_protect_type = WP_TEMPORARY_TYPE; + else if (strcmp(wp_type_str, "power_on") == 0 ) + write_protect_type = WP_POWER_ON_TYPE; + else if (strcmp(wp_type_str, "permanent") == 0) + write_protect_type = WP_PERMANENT_TYPE; + else + return ret; + + if (argc == 4) + ret = set_part_write_protect(mmc, write_protect_type, name); + else + ret = set_add_write_protect(mmc, write_protect_type, start, cnt); + + return ret; } static int clear_write_prot_per_group(struct mmc *mmc, u64 blk) { - struct mmc_cmd cmd; - int err; + struct mmc_cmd cmd; + int err; - cmd.cmdidx = MMC_CMD_CLR_WRITE_PROT; - cmd.cmdarg = blk; - cmd.resp_type = MMC_RSP_R1b; + cmd.cmdidx = MMC_CMD_CLR_WRITE_PROT; + cmd.cmdarg = blk; + cmd.resp_type = MMC_RSP_R1b; - err = mmc_send_cmd(mmc, &cmd, NULL); + err = mmc_send_cmd(mmc, &cmd, NULL); - return err; + return err; } static int set_part_clear_wp(struct mmc *mmc, char *name) { - int err = 0; - u8 ext_csd[512] = {0}; - u8 group_num = 32; - u64 wp_grp_size, start, part_end; - u64 group_start; - u64 check_group_start; - u64 set_protect_cnt = 0; - u8 wp_type = WP_CLEAR_TYPE; - - err = mmc_get_ext_csd(mmc, ext_csd); - if (err) { - printf("get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n"); - return 1; - } - - err = compute_write_protect_range(mmc, name, ext_csd, - &wp_grp_size, &start, &part_end); - if (err) - return 1; - - group_start = start; + int err = 0; + u8 ext_csd[512] = {0}; + u8 group_num = 32; + u64 wp_grp_size, start, part_end; + u64 group_start; + u64 check_group_start; + u64 set_protect_cnt = 0; + u8 wp_type = WP_CLEAR_TYPE; + + err = mmc_get_ext_csd(mmc, ext_csd); + if (err) { + printf("get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n"); + return 1; + } + + err = compute_write_protect_range(mmc, name, ext_csd, + &wp_grp_size, &start, &part_end); + if (err) + return 1; + + group_start = start; /* - if (!is_wp_type_temporary(ext_csd)) { - printf("The write protect can't be clear\n"); - return 1; - } + if (!is_wp_type_temporary(ext_csd)) { + printf("The write protect can't be clear\n"); + return 1; + } */ - while ((group_start + wp_grp_size - 1) <= part_end) { - err = clear_write_prot_per_group(mmc, group_start); - if (err) { - printf("Error: The write protect can't be clear\n"); - return 1; - } - group_start += wp_grp_size; - set_protect_cnt++; + while ((group_start + wp_grp_size - 1) <= part_end) { + err = clear_write_prot_per_group(mmc, group_start); + if (err) { + printf("Error: The write protect can't be clear\n"); + return 1; + } + group_start += wp_grp_size; + set_protect_cnt++; //check write protect type every 32 group - if (set_protect_cnt % 32 == 0) { - check_group_start = group_start - group_num * wp_grp_size; - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - } - - group_num = set_protect_cnt % 32; - check_group_start = group_start - group_num * wp_grp_size; - - if (group_num) { - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - - return 0; + if (set_protect_cnt % 32 == 0) { + check_group_start = group_start - group_num * wp_grp_size; + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + } + + group_num = set_protect_cnt % 32; + check_group_start = group_start - group_num * wp_grp_size; + + if (group_num) { + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + + return 0; } static int set_add_clear_wp(struct mmc *mmc, u64 start, u64 cnt) { - int err = 0; - u8 ext_csd[512] = {0}; - u8 group_num = 32; - u64 wp_grp_size, part_end; - u64 group_start; - u64 check_group_start; - u64 set_protect_cnt = 0; - u8 wp_type = WP_CLEAR_TYPE; - int blk_shift; - u64 mmc_boundary; - - err = mmc_get_ext_csd(mmc, ext_csd); - if (err) { - printf("get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n"); - return 1; - } - - wp_grp_size = write_protect_group_size(mmc, ext_csd); - - if ((start % wp_grp_size)) { - group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; - printf("Caution! The partition start address isn't' aligned" - "to group size\n" - "the start address is change from 0x%llx to 0x%llx\n", - start, group_start); - part_end = group_start + (cnt - 1) * wp_grp_size - 1; - printf("The write protect group number is 0x%llx, rather than 0x%lld\n", - cnt - 1, cnt); - } else { - group_start = start; - part_end = group_start + cnt * wp_grp_size - 1; - } - - blk_shift = ffs(mmc->read_bl_len) - 1; - mmc_boundary = mmc->capacity>>blk_shift; - - if ((part_end + 1) > mmc_boundary) { - printf("Error: the operation cross the boundary of mmc\n"); - return 1; - } - - while ((group_start + wp_grp_size - 1) <= part_end) { - err = clear_write_prot_per_group(mmc, group_start); - if (err) { - printf("Error: The write protect can't be clear\n"); - return 1; - } - group_start += wp_grp_size; - set_protect_cnt++; + int err = 0; + u8 ext_csd[512] = {0}; + u8 group_num = 32; + u64 wp_grp_size, part_end; + u64 group_start; + u64 check_group_start; + u64 set_protect_cnt = 0; + u8 wp_type = WP_CLEAR_TYPE; + int blk_shift; + u64 mmc_boundary; + + err = mmc_get_ext_csd(mmc, ext_csd); + if (err) { + printf("get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n"); + return 1; + } + + wp_grp_size = write_protect_group_size(mmc, ext_csd); + + if ((start % wp_grp_size)) { + group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; + printf("Caution! The partition start address isn't' aligned" + "to group size\n" + "the start address is change from 0x%llx to 0x%llx\n", + start, group_start); + part_end = group_start + (cnt - 1) * wp_grp_size - 1; + printf("The write protect group number is 0x%llx, rather than 0x%lld\n", + cnt - 1, cnt); + } else { + group_start = start; + part_end = group_start + cnt * wp_grp_size - 1; + } + + blk_shift = ffs(mmc->read_bl_len) - 1; + mmc_boundary = mmc->capacity>>blk_shift; + + if ((part_end + 1) > mmc_boundary) { + printf("Error: the operation cross the boundary of mmc\n"); + return 1; + } + + while ((group_start + wp_grp_size - 1) <= part_end) { + err = clear_write_prot_per_group(mmc, group_start); + if (err) { + printf("Error: The write protect can't be clear\n"); + return 1; + } + group_start += wp_grp_size; + set_protect_cnt++; //check write protect type every 32 group - if (set_protect_cnt % 32 == 0) { - check_group_start = group_start - group_num * wp_grp_size; - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - } - - group_num = set_protect_cnt % 32; - check_group_start = group_start - group_num * wp_grp_size; - - if (group_num) { - err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); - if (err) - return 1; - } - - return 0; + if (set_protect_cnt % 32 == 0) { + check_group_start = group_start - group_num * wp_grp_size; + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + } + + group_num = set_protect_cnt % 32; + check_group_start = group_start - group_num * wp_grp_size; + + if (group_num) { + err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num); + if (err) + return 1; + } + + return 0; } static int do_amlmmc_clear_wp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; - struct mmc *mmc; - int dev = 1; - char *name = NULL; - u64 start, cnt; - - if (argc < 3 || argc > 4) - return ret; - - if (argc == 3) { - name = argv[2]; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Error: Cannot find dev.\n"); - return CMD_RET_USAGE; - } - } else { - start = simple_strtoull(argv[2], NULL, 16); - cnt = simple_strtoull(argv[3], NULL, 10); - } - - mmc = find_mmc_device(dev); - if (!mmc) - return 1; - - if (IS_SD(mmc)) { - mmc = find_mmc_device(~dev); - if (IS_SD(mmc)) { - printf("SD card can not be write protect\n"); - return 1; - } - } - - mmc_init(mmc); - if (!mmc) - return 1; - - if (argc == 3) - ret = set_part_clear_wp(mmc, name); - else - ret = set_add_clear_wp(mmc, start, cnt); - - return ret; + int ret = CMD_RET_USAGE; + struct mmc *mmc; + int dev = 1; + char *name = NULL; + u64 start, cnt; + + if (argc < 3 || argc > 4) + return ret; + + if (argc == 3) { + name = argv[2]; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Error: Cannot find dev.\n"); + return CMD_RET_USAGE; + } + } else { + start = simple_strtoull(argv[2], NULL, 16); + cnt = simple_strtoull(argv[3], NULL, 10); + } + + mmc = find_mmc_device(dev); + if (!mmc) + return 1; + + if (IS_SD(mmc)) { + mmc = find_mmc_device(~dev); + if (IS_SD(mmc)) { + printf("SD card can not be write protect\n"); + return 1; + } + } + + mmc_init(mmc); + if (!mmc) + return 1; + + if (argc == 3) + ret = set_part_clear_wp(mmc, name); + else + ret = set_add_clear_wp(mmc, start, cnt); + + return ret; } static int send_write_prot_status_group(struct mmc *mmc, u64 blk) { - struct mmc_cmd cmd; - struct mmc_data data; - int err; - void *addr = NULL; - int i = 0; - addr = malloc(4*sizeof(u8)); - - if (addr == NULL) { - printf("Failed: malloc failed\n"); - return 1; - } - - cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT; - cmd.cmdarg = blk; - cmd.resp_type = MMC_RSP_R1; - - data.dest = addr; - data.blocks = 1; - data.blocksize = 4; - data.flags = MMC_DATA_READ; - - err = mmc_send_cmd(mmc, &cmd, &data); - if (err) - goto err_out; - - printf("The write protect type for the 32 groups after 0x%llx is:\n0x", - blk); - for (i = 0 ; i < 4; i++) - printf("%02x", ((u8 *)addr)[i]); - printf("\n"); - - free(addr); - return 0; + struct mmc_cmd cmd; + struct mmc_data data; + int err; + void *addr = NULL; + int i = 0; + addr = malloc(4*sizeof(u8)); + + if (addr == NULL) { + printf("Failed: malloc failed\n"); + return 1; + } + + cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT; + cmd.cmdarg = blk; + cmd.resp_type = MMC_RSP_R1; + + data.dest = addr; + data.blocks = 1; + data.blocksize = 4; + data.flags = MMC_DATA_READ; + + err = mmc_send_cmd(mmc, &cmd, &data); + if (err) + goto err_out; + + printf("The write protect type for the 32 groups after 0x%llx is:\n0x", + blk); + for (i = 0 ; i < 4; i++) + printf("%02x", ((u8 *)addr)[i]); + printf("\n"); + + free(addr); + return 0; err_out: - free(addr); - return 1; + free(addr); + return 1; } static int send_part_wp_status(struct mmc *mmc, char *name) { - int err = 0; - u8 ext_csd[512] = {0}; - u64 wp_grp_size, start, part_end; - u64 group_start; - - err = mmc_get_ext_csd(mmc, ext_csd); - if (err) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - err = compute_write_protect_range(mmc, name, ext_csd, - &wp_grp_size, &start, &part_end); - if (err) - return 1; - - group_start = start; - - while ((group_start + wp_grp_size - 1) <= part_end) { - err = send_write_prot_status_group(mmc, group_start); - if (err) - return 1; - group_start += 32 * wp_grp_size; - } - - return 0; + int err = 0; + u8 ext_csd[512] = {0}; + u64 wp_grp_size, start, part_end; + u64 group_start; + + err = mmc_get_ext_csd(mmc, ext_csd); + if (err) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + err = compute_write_protect_range(mmc, name, ext_csd, + &wp_grp_size, &start, &part_end); + if (err) + return 1; + + group_start = start; + + while ((group_start + wp_grp_size - 1) <= part_end) { + err = send_write_prot_status_group(mmc, group_start); + if (err) + return 1; + group_start += 32 * wp_grp_size; + } + + return 0; } static int send_add_wp_status(struct mmc *mmc, u64 start, u64 cnt) { - int err = 0; - u8 ext_csd[512] = {0}; - u64 wp_grp_size, part_end; - u64 group_start; - int blk_shift; - u64 mmc_boundary; - err = mmc_get_ext_csd(mmc, ext_csd); - if (err) { - printf("Failed: get ext_csd failed\n"); - return 1; - } - - if (!is_write_protect_valid(ext_csd)) { - printf("Failed: CLASS_6_CTRL isn't '0' " - "write protect process is invalid\n"); - return 1; - } - - wp_grp_size = write_protect_group_size(mmc, ext_csd); - - if ((start % wp_grp_size)) { - group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; - printf("Caution! The partition start address isn't' aligned" - "to group size\n" - "the start address is change from 0x%llx to 0x%llx\n", - start, group_start); - part_end = group_start + (cnt - 1) * wp_grp_size - 1; - printf("The write protect group number is 0x%llx, rather than 0x%lld\n", - cnt - 1, cnt); - } else { - group_start = start; - part_end = group_start + cnt * wp_grp_size - 1; - } - - blk_shift = ffs(mmc->read_bl_len) - 1; - mmc_boundary = mmc->capacity>>blk_shift; - - if ((part_end + 1) > mmc_boundary) { - printf("Error: the operation cross the boundary of mmc\n"); - return 1; - } - - while ((group_start + wp_grp_size - 1) <= part_end) { - err = send_write_prot_status_group(mmc, group_start); - if (err) - return 1; - group_start += 32 * wp_grp_size; - } - - return 0; + int err = 0; + u8 ext_csd[512] = {0}; + u64 wp_grp_size, part_end; + u64 group_start; + int blk_shift; + u64 mmc_boundary; + err = mmc_get_ext_csd(mmc, ext_csd); + if (err) { + printf("Failed: get ext_csd failed\n"); + return 1; + } + + if (!is_write_protect_valid(ext_csd)) { + printf("Failed: CLASS_6_CTRL isn't '0' " + "write protect process is invalid\n"); + return 1; + } + + wp_grp_size = write_protect_group_size(mmc, ext_csd); + + if ((start % wp_grp_size)) { + group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size; + printf("Caution! The partition start address isn't' aligned" + "to group size\n" + "the start address is change from 0x%llx to 0x%llx\n", + start, group_start); + part_end = group_start + (cnt - 1) * wp_grp_size - 1; + printf("The write protect group number is 0x%llx, rather than 0x%lld\n", + cnt - 1, cnt); + } else { + group_start = start; + part_end = group_start + cnt * wp_grp_size - 1; + } + + blk_shift = ffs(mmc->read_bl_len) - 1; + mmc_boundary = mmc->capacity>>blk_shift; + + if ((part_end + 1) > mmc_boundary) { + printf("Error: the operation cross the boundary of mmc\n"); + return 1; + } + + while ((group_start + wp_grp_size - 1) <= part_end) { + err = send_write_prot_status_group(mmc, group_start); + if (err) + return 1; + group_start += 32 * wp_grp_size; + } + + return 0; } static int do_amlmmc_send_wp_status(cmd_tbl_t *cmdtp, - int flag, int argc, char *const argv[]) -{ - int ret = CMD_RET_USAGE; - struct mmc *mmc; - int dev = 1; - char *name = NULL; - u64 start, cnt; - - if (argc < 3 || argc > 4) - return ret; - - if (argc == 3) { - name = argv[2]; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Error: Cannot find dev.\n"); - return 1; - } - } else { - start = simple_strtoull(argv[2], NULL, 16); - cnt = simple_strtoull(argv[3], NULL, 0); - } - - mmc = find_mmc_device(dev); - - if (IS_SD(mmc)) { - mmc = find_mmc_device(~dev); - if (IS_SD(mmc)) { - printf("SD card can not be write protect\n"); - return 1; - } - } - - if (!mmc) - return 1; - - mmc_init(mmc); - if (!mmc) - return 1; - - if (argc == 3) - ret = send_part_wp_status(mmc, name); - else - ret = send_add_wp_status(mmc, start, cnt); - - if (ret) { - printf("Failed: send partition write protect status failed\n"); - } - - return ret; + int flag, int argc, char *const argv[]) +{ + int ret = CMD_RET_USAGE; + struct mmc *mmc; + int dev = 1; + char *name = NULL; + u64 start, cnt; + + if (argc < 3 || argc > 4) + return ret; + + if (argc == 3) { + name = argv[2]; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Error: Cannot find dev.\n"); + return 1; + } + } else { + start = simple_strtoull(argv[2], NULL, 16); + cnt = simple_strtoull(argv[3], NULL, 0); + } + + mmc = find_mmc_device(dev); + + if (IS_SD(mmc)) { + mmc = find_mmc_device(~dev); + if (IS_SD(mmc)) { + printf("SD card can not be write protect\n"); + return 1; + } + } + + if (!mmc) + return 1; + + mmc_init(mmc); + if (!mmc) + return 1; + + if (argc == 3) + ret = send_part_wp_status(mmc, name); + else + ret = send_add_wp_status(mmc, start, cnt); + + if (ret) { + printf("Failed: send partition write protect status failed\n"); + } + + return ret; } static int do_amlmmc_send_wp_type(cmd_tbl_t *cmdtp, - int flag, int argc, char *const argv[]) -{ - int ret = CMD_RET_USAGE; - struct mmc *mmc; - int dev = 1; - char *name = NULL; - u64 start, cnt; - - if (argc < 3 || argc > 4) - return ret; - - if (argc == 3) { - name = argv[2]; - dev = find_dev_num_by_partition_name(name); - if (dev < 0) { - printf("Error: Cannot find dev.\n"); - return 1; - } - } else { - start = simple_strtoull(argv[2], NULL, 16); - cnt = simple_strtoull(argv[3], NULL, 0); - } - - mmc = find_mmc_device(dev); - - if (!mmc) - return 1; - - if (IS_SD(mmc)) { - mmc = find_mmc_device(~dev); - if (IS_SD(mmc)) { - printf("SD card can not be write protect\n"); - return 1; - } - } - - mmc_init(mmc); - if (!mmc) - return 1; - if (argc == 3) - ret = send_part_wp_type(mmc, name); - else - ret = send_add_wp_type(mmc, start, cnt); - - if (ret) { - printf("Failed: send parittion write protect type failed\n"); - } - - return ret; + int flag, int argc, char *const argv[]) +{ + int ret = CMD_RET_USAGE; + struct mmc *mmc; + int dev = 1; + char *name = NULL; + u64 start, cnt; + + if (argc < 3 || argc > 4) + return ret; + + if (argc == 3) { + name = argv[2]; + dev = find_dev_num_by_partition_name(name); + if (dev < 0) { + printf("Error: Cannot find dev.\n"); + return 1; + } + } else { + start = simple_strtoull(argv[2], NULL, 16); + cnt = simple_strtoull(argv[3], NULL, 0); + } + + mmc = find_mmc_device(dev); + + if (!mmc) + return 1; + + if (IS_SD(mmc)) { + mmc = find_mmc_device(~dev); + if (IS_SD(mmc)) { + printf("SD card can not be write protect\n"); + return 1; + } + } + + mmc_init(mmc); + if (!mmc) + return 1; + if (argc == 3) + ret = send_part_wp_type(mmc, name); + else + ret = send_add_wp_type(mmc, start, cnt); + + if (ret) { + printf("Failed: send parittion write protect type failed\n"); + } + + return ret; } static int set_driver_strength(struct mmc *mmc, int strength) { - int ret = 0; - u8 ext_csd[512] = {0}; - u8 strength_type = 0; - u8 driver_strength; - u8 hs_timing = 0; - ret = mmc_get_ext_csd(mmc, ext_csd); - if (ret) { - printf("get ext_csd failed\n"); - return ret; - } - strength_type = 1 << strength; - driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH]; - if (0 == (strength_type & driver_strength)) { - printf("Failed: This device didn't support strength type %d\n", strength); - return 1; - } - - hs_timing = ext_csd[EXT_CSD_HS_TIMING]; - if ((hs_timing >> 4) > 0) { - printf("Failed: The driver strength has been set already, \ - please reset the device\n"); - return 1; - } - - hs_timing = hs_timing | (strength << 4); - - ret = mmc_set_ext_csd(mmc, EXT_CSD_HS_TIMING, hs_timing); - if (ret) { - printf("set ext_csd hs_timing field failed\n"); - return ret; - } - ret = mmc_get_ext_csd(mmc, ext_csd); - if (ret) { - printf("get ext_csd failed\n"); - return ret; - } - printf("The ext_csd[HS_TIMING] has been set to 0x%x\n", - ext_csd[EXT_CSD_HS_TIMING]); - return ret; + int ret = 0; + u8 ext_csd[512] = {0}; + u8 strength_type = 0; + u8 driver_strength; + u8 hs_timing = 0; + ret = mmc_get_ext_csd(mmc, ext_csd); + if (ret) { + printf("get ext_csd failed\n"); + return ret; + } + strength_type = 1 << strength; + driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH]; + if (0 == (strength_type & driver_strength)) { + printf("Failed: This device didn't support strength type %d\n", strength); + return 1; + } + + hs_timing = ext_csd[EXT_CSD_HS_TIMING]; + if ((hs_timing >> 4) > 0) { + printf("Failed: The driver strength has been set already, \ + please reset the device\n"); + return 1; + } + + hs_timing = hs_timing | (strength << 4); + + ret = mmc_set_ext_csd(mmc, EXT_CSD_HS_TIMING, hs_timing); + if (ret) { + printf("set ext_csd hs_timing field failed\n"); + return ret; + } + ret = mmc_get_ext_csd(mmc, ext_csd); + if (ret) { + printf("get ext_csd failed\n"); + return ret; + } + printf("The ext_csd[HS_TIMING] has been set to 0x%x\n", + ext_csd[EXT_CSD_HS_TIMING]); + return ret; } static int get_driver_strength(struct mmc *mmc) { - int ret = 0; - u8 ext_csd[512] = {0}; - u8 support_ds_type = 0; - u8 cur_driver_strength; - u8 hs_timing = 0; - ret = mmc_get_ext_csd(mmc, ext_csd); - if (ret) { - printf("get ext_csd failed\n"); - return ret; - } - - support_ds_type = ext_csd[EXT_CSD_DRIVER_STRENGTH]; - - hs_timing = ext_csd[EXT_CSD_HS_TIMING]; - cur_driver_strength = hs_timing >> 4; - - printf("current strength type is: "); - int strength_type = 0; - while (support_ds_type) { - if (support_ds_type & 1) { - if (cur_driver_strength == strength_type) - printf("[%d] ", strength_type); - else - printf("%d ", strength_type); - } - strength_type++; - support_ds_type = support_ds_type >> 1; - } - printf("\n"); - return ret; + int ret = 0; + u8 ext_csd[512] = {0}; + u8 support_ds_type = 0; + u8 cur_driver_strength; + u8 hs_timing = 0; + ret = mmc_get_ext_csd(mmc, ext_csd); + if (ret) { + printf("get ext_csd failed\n"); + return ret; + } + + support_ds_type = ext_csd[EXT_CSD_DRIVER_STRENGTH]; + + hs_timing = ext_csd[EXT_CSD_HS_TIMING]; + cur_driver_strength = hs_timing >> 4; + + printf("current strength type is: "); + int strength_type = 0; + while (support_ds_type) { + if (support_ds_type & 1) { + if (cur_driver_strength == strength_type) + printf("[%d] ", strength_type); + else + printf("%d ", strength_type); + } + strength_type++; + support_ds_type = support_ds_type >> 1; + } + printf("\n"); + return ret; } static int amlmmc_set_driver_strength(int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; - int dev, strength; - struct mmc *mmc; - - if (argc != 4) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - strength = simple_strtoul(argv[3], NULL, 10); - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - if (!mmc) - return 1; - - ret = set_driver_strength(mmc, strength); - - return ret; + int ret = CMD_RET_USAGE; + int dev, strength; + struct mmc *mmc; + + if (argc != 4) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + strength = simple_strtoul(argv[3], NULL, 10); + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + if (!mmc) + return 1; + + ret = set_driver_strength(mmc, strength); + + return ret; } static int amlmmc_get_driver_strength(int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; - int dev; - struct mmc *mmc; - - if (argc != 3) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - if (!mmc) - return 1; - - ret = get_driver_strength(mmc); - - return ret; + int ret = CMD_RET_USAGE; + int dev; + struct mmc *mmc; + + if (argc != 3) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + if (!mmc) + return 1; + + ret = get_driver_strength(mmc); + + return ret; } static int do_amlmmc_driver_strength(cmd_tbl_t *cmdtp, - int flag, int argc, char *const argv[]) + int flag, int argc, char *const argv[]) { - int ret = CMD_RET_USAGE; + int ret = CMD_RET_USAGE; - if (argc == 3) - ret = amlmmc_get_driver_strength(argc,argv); - else if (argc == 4) - ret = amlmmc_set_driver_strength(argc,argv); + if (argc == 3) + ret = amlmmc_get_driver_strength(argc,argv); + else if (argc == 4) + ret = amlmmc_set_driver_strength(argc,argv); - return ret; + return ret; } #ifdef MMC_HS200_MODE static int do_amlmmc_reset_delay(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - int dev; + struct mmc *mmc; + int dev; - struct aml_card_sd_info *aml_priv; - struct sd_emmc_global_regs *sd_emmc_regs; + struct aml_card_sd_info *aml_priv; + struct sd_emmc_global_regs *sd_emmc_regs; - if (argc != 3) - return CMD_RET_USAGE; + if (argc != 3) + return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - mmc_init(mmc); - if (!mmc) - return 1; + dev = simple_strtoul(argv[2], NULL, 10); + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + mmc_init(mmc); + if (!mmc) + return 1; - aml_priv = mmc->priv; - sd_emmc_regs = aml_priv->sd_emmc_reg; + aml_priv = mmc->priv; + sd_emmc_regs = aml_priv->sd_emmc_reg; - sd_emmc_regs->gdelay = 0; - sd_emmc_regs->gdelay1 = 0; + sd_emmc_regs->gdelay = 0; + sd_emmc_regs->gdelay1 = 0; - return CMD_RET_SUCCESS; + return CMD_RET_SUCCESS; } static int do_amlmmc_clktest(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - int dev; - - if (argc != 3) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - if (!mmc) - return 1; - - aml_sd_emmc_clktest(mmc); - return CMD_RET_SUCCESS; + struct mmc *mmc; + int dev; + + if (argc != 3) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + if (!mmc) + return 1; + + aml_sd_emmc_clktest(mmc); + return CMD_RET_SUCCESS; } static int do_amlmmc_set_rxdelay(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - int dev; - u32 delay1, delay2; + struct mmc *mmc; + int dev; + u32 delay1, delay2; - if (argc != 5) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - delay1 = simple_strtoul(argv[3], NULL, 16); - delay2 = simple_strtoul(argv[4], NULL, 16); + if (argc != 5) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); + delay1 = simple_strtoul(argv[3], NULL, 16); + delay2 = simple_strtoul(argv[4], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } - mmc_init(mmc); - if (!mmc) - return 1; + mmc_init(mmc); + if (!mmc) + return 1; - struct aml_card_sd_info *aml_priv = mmc->priv; - struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; + struct aml_card_sd_info *aml_priv = mmc->priv; + struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; - sd_emmc_regs->gdelay = delay1; - sd_emmc_regs->gdelay1 = delay2; + sd_emmc_regs->gdelay = delay1; + sd_emmc_regs->gdelay1 = delay2; - update_all_line_eyetest(mmc); + update_all_line_eyetest(mmc); - return CMD_RET_SUCCESS; + return CMD_RET_SUCCESS; } static int do_amlmmc_set_txdelay(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - u32 delay; - u32 mask; - int dev; - - if (argc != 4) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - delay = simple_strtoul(argv[3], NULL, 16); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - if (!mmc) - return 1; - - if (delay < 0 || delay > 63) { - printf("error: tx delay is out of range\n"); - return CMD_RET_USAGE; - } - - struct aml_card_sd_info *aml_priv = mmc->priv; - struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; - - mask = ~(0x3f<<16); - sd_emmc_regs->gclock = sd_emmc_regs->gclock & mask; - sd_emmc_regs->gclock |= delay << 16; - - update_all_line_eyetest(mmc); - return CMD_RET_SUCCESS; + struct mmc *mmc; + u32 delay; + u32 mask; + int dev; + + if (argc != 4) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); + delay = simple_strtoul(argv[3], NULL, 16); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + if (!mmc) + return 1; + + if (delay < 0 || delay > 63) { + printf("error: tx delay is out of range\n"); + return CMD_RET_USAGE; + } + + struct aml_card_sd_info *aml_priv = mmc->priv; + struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; + + mask = ~(0x3f<<16); + sd_emmc_regs->gclock = sd_emmc_regs->gclock & mask; + sd_emmc_regs->gclock |= delay << 16; + + update_all_line_eyetest(mmc); + return CMD_RET_SUCCESS; } static void set_vddee_voltage(unsigned int target_voltage) { - unsigned int to; + unsigned int to; - for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { - if (pwm_voltage_table_ee[to][1] >= target_voltage) { - break; - } - } + for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { + if (pwm_voltage_table_ee[to][1] >= target_voltage) { + break; + } + } - if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { - to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; - } + if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { + to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; + } - SD_EMMC_VDDEE_REG = pwm_voltage_table_ee[to][0]; + SD_EMMC_VDDEE_REG = pwm_voltage_table_ee[to][0]; } static int send_vddee_voltage(unsigned int target_voltage) { - unsigned int to; - int vddee; + unsigned int to; + int vddee; - for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { - if (pwm_voltage_table_ee[to][0] <= target_voltage) { - break; - } - } + for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) { + if (pwm_voltage_table_ee[to][0] <= target_voltage) { + break; + } + } - if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { - to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; - } + if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) { + to = ARRAY_SIZE(pwm_voltage_table_ee) - 1; + } - vddee = pwm_voltage_table_ee[to][1]; + vddee = pwm_voltage_table_ee[to][1]; - return vddee; + return vddee; } static int do_amlmmc_set_vddee(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - unsigned int vddee; - struct mmc *mmc; - int dev; + unsigned int vddee; + struct mmc *mmc; + int dev; - if (argc != 4) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - vddee = simple_strtoul(argv[3], NULL, 10); + if (argc != 4) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); + vddee = simple_strtoul(argv[3], NULL, 10); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } - mmc_init(mmc); - if (!mmc) - return 1; + mmc_init(mmc); + if (!mmc) + return 1; - set_vddee_voltage(vddee); - return CMD_RET_SUCCESS; + set_vddee_voltage(vddee); + return CMD_RET_SUCCESS; } static int do_amlmmc_show_vddee(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - int vddee; - unsigned int vddee_reg; - struct mmc *mmc; - int dev; + int vddee; + unsigned int vddee_reg; + struct mmc *mmc; + int dev; - if (argc != 3) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); + if (argc != 3) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } - mmc_init(mmc); - if (!mmc) - return 1; + mmc_init(mmc); + if (!mmc) + return 1; - vddee_reg = SD_EMMC_VDDEE_REG; + vddee_reg = SD_EMMC_VDDEE_REG; - vddee = send_vddee_voltage(vddee_reg); + vddee = send_vddee_voltage(vddee_reg); - printf("meson-mmc: emmc: vddee is %d mv\n", vddee); + printf("meson-mmc: emmc: vddee is %d mv\n", vddee); - return CMD_RET_SUCCESS; + return CMD_RET_SUCCESS; } static int do_amlmmc_refix(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - int err; - struct mmc *mmc; - int dev; + int err; + struct mmc *mmc; + int dev; - if (argc != 3) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); + if (argc != 3) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } - mmc_init(mmc); - if (!mmc) - return 1; + mmc_init(mmc); + if (!mmc) + return 1; - err = aml_emmc_refix(mmc); - if (err) - printf("refix failed\n"); - return err; + err = aml_emmc_refix(mmc); + if (err) + printf("refix failed\n"); + return err; } static int do_amlmmc_move_all_delay(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - u32 delay1, delay2; - u8 count; - int dev; + struct mmc *mmc; + u32 delay1, delay2; + u8 count; + int dev; - if (argc != 4) - return CMD_RET_USAGE; - dev = simple_strtoul(argv[2], NULL, 10); - count = simple_strtoul(argv[3], NULL, 16); - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } + if (argc != 4) + return CMD_RET_USAGE; + dev = simple_strtoul(argv[2], NULL, 10); + count = simple_strtoul(argv[3], NULL, 16); + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } - mmc = find_mmc_device(dev); + mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } - mmc_init(mmc); - if (!mmc) - return 1; + mmc_init(mmc); + if (!mmc) + return 1; - struct aml_card_sd_info *aml_priv = mmc->priv; - struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; + struct aml_card_sd_info *aml_priv = mmc->priv; + struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; - delay1 = sd_emmc_regs->gdelay; - delay2 = sd_emmc_regs->gdelay1; + delay1 = sd_emmc_regs->gdelay; + delay2 = sd_emmc_regs->gdelay1; - delay1 += (count<<0)|(count<<6)|(count<<12)|(count<<18)|(count<<24); - delay2 += (count<<0)|(count<<6)|(count<<12); + delay1 += (count<<0)|(count<<6)|(count<<12)|(count<<18)|(count<<24); + delay2 += (count<<0)|(count<<6)|(count<<12); - sd_emmc_regs->gdelay = delay1; - sd_emmc_regs->gdelay1 = delay2; + sd_emmc_regs->gdelay = delay1; + sd_emmc_regs->gdelay1 = delay2; - update_all_line_eyetest(mmc); - return CMD_RET_SUCCESS; + update_all_line_eyetest(mmc); + return CMD_RET_SUCCESS; } static int do_amlmmc_move_sig_delay(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - struct mmc *mmc; - u32 delay1, delay2; - u8 line, count; - int dev; - - if (argc != 5) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - line = simple_strtoul(argv[3], NULL, 10); - count = simple_strtoul(argv[4], NULL, 10); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - if (!mmc) - return 1; - - if (line > 9 || line < 0) { - printf("error: data line out of range\n"); - return CMD_RET_USAGE; - } - - struct aml_card_sd_info *aml_priv = mmc->priv; - struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; - - delay1 = sd_emmc_regs->gdelay; - delay2 = sd_emmc_regs->gdelay1; - - if (line < 5) { - delay1 += (count<<(6*line)); - sd_emmc_regs->gdelay = delay1; - } else { - delay2 += (count<<(6 * (line - 5))); - sd_emmc_regs->gdelay1 = delay2; - } - - update_all_line_eyetest(mmc); - return CMD_RET_SUCCESS; + struct mmc *mmc; + u32 delay1, delay2; + u8 line, count; + int dev; + + if (argc != 5) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + line = simple_strtoul(argv[3], NULL, 10); + count = simple_strtoul(argv[4], NULL, 10); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + if (!mmc) + return 1; + + if (line > 9 || line < 0) { + printf("error: data line out of range\n"); + return CMD_RET_USAGE; + } + + struct aml_card_sd_info *aml_priv = mmc->priv; + struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; + + delay1 = sd_emmc_regs->gdelay; + delay2 = sd_emmc_regs->gdelay1; + + if (line < 5) { + delay1 += (count<<(6*line)); + sd_emmc_regs->gdelay = delay1; + } else { + delay2 += (count<<(6 * (line - 5))); + sd_emmc_regs->gdelay1 = delay2; + } + + update_all_line_eyetest(mmc); + return CMD_RET_SUCCESS; } static int do_amlmmc_line_eyetest(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) -{ - struct mmc *mmc; - u32 delay1, delay2; - u8 line, count; - int dev; - u32 mask = 0x3f; - - if (argc != 4) - return CMD_RET_USAGE; - - dev = simple_strtoul(argv[2], NULL, 10); - line = simple_strtoul(argv[3], NULL, 10); - - if (dev < 0) { - printf("Cannot find dev.\n"); - return 1; - } - - mmc = find_mmc_device(dev); - - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - mmc_init(mmc); - if (!mmc) - return 1; - - if (line > 9 || line < 0) { - printf("error: data line out of range\n"); - return CMD_RET_USAGE; - } - - struct aml_card_sd_info *aml_priv = mmc->priv; - struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; - - delay1 = sd_emmc_regs->gdelay; - delay2 = sd_emmc_regs->gdelay1; - - if (line < 5) - delay1 &= ~(mask << (6 * line)); - else - delay2 &= ~(mask << (6 * (line - 5))); - - for (count = 0; count < 64; count++) { - if (line < 5) { - delay1 &= ~(mask << (6 * line)); - delay1 |= (count << (6 * line)); - sd_emmc_regs->gdelay = delay1; - } else { - delay2 &= ~(mask << (6 * (line - 5))); - delay2 |= (count << (6 * line)); - sd_emmc_regs->gdelay1 = delay2; - } - emmc_eyetest_log(mmc, line); - } - return CMD_RET_SUCCESS; + int argc, char * const argv[]) +{ + struct mmc *mmc; + u32 delay1, delay2; + u8 line, count; + int dev; + u32 mask = 0x3f; + + if (argc != 4) + return CMD_RET_USAGE; + + dev = simple_strtoul(argv[2], NULL, 10); + line = simple_strtoul(argv[3], NULL, 10); + + if (dev < 0) { + printf("Cannot find dev.\n"); + return 1; + } + + mmc = find_mmc_device(dev); + + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + mmc_init(mmc); + if (!mmc) + return 1; + + if (line > 9 || line < 0) { + printf("error: data line out of range\n"); + return CMD_RET_USAGE; + } + + struct aml_card_sd_info *aml_priv = mmc->priv; + struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg; + + delay1 = sd_emmc_regs->gdelay; + delay2 = sd_emmc_regs->gdelay1; + + if (line < 5) + delay1 &= ~(mask << (6 * line)); + else + delay2 &= ~(mask << (6 * (line - 5))); + + for (count = 0; count < 64; count++) { + if (line < 5) { + delay1 &= ~(mask << (6 * line)); + delay1 |= (count << (6 * line)); + sd_emmc_regs->gdelay = delay1; + } else { + delay2 &= ~(mask << (6 * (line - 5))); + delay2 |= (count << (6 * line)); + sd_emmc_regs->gdelay1 = delay2; + } + emmc_eyetest_log(mmc, line); + } + return CMD_RET_SUCCESS; } #endif static cmd_tbl_t cmd_amlmmc[] = { - U_BOOT_CMD_MKENT(read, 6, 0, do_amlmmc_read, "", ""), - U_BOOT_CMD_MKENT(write, 6, 0, do_amlmmc_write, "", ""), - U_BOOT_CMD_MKENT(erase, 5, 0, do_amlmmc_erase, "", ""), - U_BOOT_CMD_MKENT(rescan, 3, 0, do_amlmmc_rescan, "", ""), - U_BOOT_CMD_MKENT(part, 3, 0, do_amlmmc_part, "", ""), - U_BOOT_CMD_MKENT(list, 2, 0, do_amlmmc_list, "", ""), - U_BOOT_CMD_MKENT(switch, 4, 0, do_amlmmc_switch, "", ""), - U_BOOT_CMD_MKENT(status, 3, 0, do_amlmmc_status, "", ""), - U_BOOT_CMD_MKENT(ext_csd, 5, 0, do_amlmmc_ext_csd, "", ""), - U_BOOT_CMD_MKENT(response, 3, 0, do_amlmmc_response, "", ""), - U_BOOT_CMD_MKENT(controller, 3, 0, do_amlmmc_controller, "", ""), - U_BOOT_CMD_MKENT(size, 4, 0, do_amlmmc_size, "", ""), - U_BOOT_CMD_MKENT(env, 2, 0, do_amlmmc_env, "", ""), - U_BOOT_CMD_MKENT(write_protect, 5, 0, do_amlmmc_write_protect, "", ""), - U_BOOT_CMD_MKENT(send_wp_status, 4, 0, do_amlmmc_send_wp_status, "", ""), - U_BOOT_CMD_MKENT(send_wp_type, 4, 0, do_amlmmc_send_wp_type, "", ""), - U_BOOT_CMD_MKENT(clear_wp, 4, 0, do_amlmmc_clear_wp, "", ""), - U_BOOT_CMD_MKENT(ds, 4, 0, do_amlmmc_driver_strength, "", ""), + U_BOOT_CMD_MKENT(read, 6, 0, do_amlmmc_read, "", ""), + U_BOOT_CMD_MKENT(write, 6, 0, do_amlmmc_write, "", ""), + U_BOOT_CMD_MKENT(erase, 5, 0, do_amlmmc_erase, "", ""), + U_BOOT_CMD_MKENT(rescan, 3, 0, do_amlmmc_rescan, "", ""), + U_BOOT_CMD_MKENT(part, 3, 0, do_amlmmc_part, "", ""), + U_BOOT_CMD_MKENT(list, 2, 0, do_amlmmc_list, "", ""), + U_BOOT_CMD_MKENT(switch, 4, 0, do_amlmmc_switch, "", ""), + U_BOOT_CMD_MKENT(status, 3, 0, do_amlmmc_status, "", ""), + U_BOOT_CMD_MKENT(ext_csd, 5, 0, do_amlmmc_ext_csd, "", ""), + U_BOOT_CMD_MKENT(response, 3, 0, do_amlmmc_response, "", ""), + U_BOOT_CMD_MKENT(controller, 3, 0, do_amlmmc_controller, "", ""), + U_BOOT_CMD_MKENT(size, 4, 0, do_amlmmc_size, "", ""), + U_BOOT_CMD_MKENT(env, 2, 0, do_amlmmc_env, "", ""), + U_BOOT_CMD_MKENT(write_protect, 5, 0, do_amlmmc_write_protect, "", ""), + U_BOOT_CMD_MKENT(send_wp_status, 4, 0, do_amlmmc_send_wp_status, "", ""), + U_BOOT_CMD_MKENT(send_wp_type, 4, 0, do_amlmmc_send_wp_type, "", ""), + U_BOOT_CMD_MKENT(clear_wp, 4, 0, do_amlmmc_clear_wp, "", ""), + U_BOOT_CMD_MKENT(ds, 4, 0, do_amlmmc_driver_strength, "", ""), #ifdef CONFIG_SECURITYKEY - U_BOOT_CMD_MKENT(key, 2, 0, do_amlmmc_key, "", ""), + U_BOOT_CMD_MKENT(key, 2, 0, do_amlmmc_key, "", ""), #endif #ifdef MMC_HS200_MODE - U_BOOT_CMD_MKENT(clktest, 3, 0, do_amlmmc_clktest, "", ""), - U_BOOT_CMD_MKENT(refix, 3, 0, do_amlmmc_refix, "", ""), - U_BOOT_CMD_MKENT(move_all, 4, 0, do_amlmmc_move_all_delay, "", ""), - U_BOOT_CMD_MKENT(move_single, 5, 0, do_amlmmc_move_sig_delay, "", ""), - U_BOOT_CMD_MKENT(set_rxdly, 5, 0, do_amlmmc_set_rxdelay, "", ""), - U_BOOT_CMD_MKENT(set_txdly, 4, 0, do_amlmmc_set_txdelay, "", ""), - U_BOOT_CMD_MKENT(set_vddee, 4, 0, do_amlmmc_set_vddee, "", ""), - U_BOOT_CMD_MKENT(show_vddee, 3, 0, do_amlmmc_show_vddee, "", ""), - U_BOOT_CMD_MKENT(reset_dly, 3, 0, do_amlmmc_reset_delay, "", ""), - U_BOOT_CMD_MKENT(line_eyetest, 4, 0, do_amlmmc_line_eyetest, "", ""), + U_BOOT_CMD_MKENT(clktest, 3, 0, do_amlmmc_clktest, "", ""), + U_BOOT_CMD_MKENT(refix, 3, 0, do_amlmmc_refix, "", ""), + U_BOOT_CMD_MKENT(move_all, 4, 0, do_amlmmc_move_all_delay, "", ""), + U_BOOT_CMD_MKENT(move_single, 5, 0, do_amlmmc_move_sig_delay, "", ""), + U_BOOT_CMD_MKENT(set_rxdly, 5, 0, do_amlmmc_set_rxdelay, "", ""), + U_BOOT_CMD_MKENT(set_txdly, 4, 0, do_amlmmc_set_txdelay, "", ""), + U_BOOT_CMD_MKENT(set_vddee, 4, 0, do_amlmmc_set_vddee, "", ""), + U_BOOT_CMD_MKENT(show_vddee, 3, 0, do_amlmmc_show_vddee, "", ""), + U_BOOT_CMD_MKENT(reset_dly, 3, 0, do_amlmmc_reset_delay, "", ""), + U_BOOT_CMD_MKENT(line_eyetest, 4, 0, do_amlmmc_line_eyetest, "", ""), #endif }; static int do_amlmmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - cmd_tbl_t *cp; + cmd_tbl_t *cp; - cp = find_cmd_tbl(argv[1], cmd_amlmmc, ARRAY_SIZE(cmd_amlmmc)); + cp = find_cmd_tbl(argv[1], cmd_amlmmc, ARRAY_SIZE(cmd_amlmmc)); - if (cp == NULL || argc > cp->maxargs) - return CMD_RET_USAGE; + if (cp == NULL || argc > cp->maxargs) + return CMD_RET_USAGE; - if (flag == CMD_FLAG_REPEAT && !cp->repeatable) - return CMD_RET_SUCCESS; + if (flag == CMD_FLAG_REPEAT && !cp->repeatable) + return CMD_RET_SUCCESS; - return cp->cmd(cmdtp, flag, argc, argv); + return cp->cmd(cmdtp, flag, argc, argv); } U_BOOT_CMD( - amlmmc, 6, 1, do_amlmmcops, - "AMLMMC sub system", - "read <partition_name> ram_addr addr_byte# cnt_byte\n" - "amlmmc write <partition_name> ram_addr addr_byte# cnt_byte\n" - "amlmmc erase <partition_name> addr_byte# cnt_byte\n" - "amlmmc erase <partition_name>/<device num>\n" - "amlmmc rescan <device_num>\n" - "amlmmc part <device_num> - show partition infomation of mmc\n" - "amlmmc list - lists available devices\n" - "amlmmc env - display env partition offset\n" - "amlmmc switch <device_num> <part name> - part name : boot0, boot1, user\n" - "amlmmc status <device_num> - read sd/emmc device status\n" - "amlmmc ext_csd <device_num> <byte> - read sd/emmc device EXT_CSD [byte]\n" - "amlmmc ext_csd <device_num> <byte> <value> - write sd/emmc device EXT_CSD [byte] value\n" - "amlmmc response <device_num> - read sd/emmc last command response\n" - "amlmmc controller <device_num> - read sd/emmc controller register\n" - "amlmmc write_protect <partition_name> <write_protect_type>\n" - " - set write protect on partition through power_on or temporary\n" - "amlmmc write_protect <addr_base16> <cnt_base10> <write_protect_type>\n" - " - set write protect on specified address through power_on or temporary\n" - "amlmmc send_wp_status <partition_name> send protect status of partition\n" - "amlmmc send_wp_status <addr_base16> <cnt_base10> send protect status on specified address\n" - "amlmmc send_wp_type <partition_name> send protect type of partition\n" - "amlmmc send_wp_type <addr_base16> <cnt_base10> send protect type on specified address\n" - "amlmmc clear_wp <partition_name> clear write protect of partition\n" - "amlmmc clear_wp <addr_base16> <cnt_base10> clear write protect on specified addresst\n" - "amlmmc ds <dev_num> <val> set driver strength\n" + amlmmc, 6, 1, do_amlmmcops, + "AMLMMC sub system", + "read <partition_name> ram_addr addr_byte# cnt_byte\n" + "amlmmc write <partition_name> ram_addr addr_byte# cnt_byte\n" + "amlmmc erase <partition_name> addr_byte# cnt_byte\n" + "amlmmc erase <partition_name>/<device num>\n" + "amlmmc rescan <device_num>\n" + "amlmmc part <device_num> - show partition infomation of mmc\n" + "amlmmc list - lists available devices\n" + "amlmmc env - display env partition offset\n" + "amlmmc switch <device_num> <part name> - part name : boot0, boot1, user\n" + "amlmmc status <device_num> - read sd/emmc device status\n" + "amlmmc ext_csd <device_num> <byte> - read sd/emmc device EXT_CSD [byte]\n" + "amlmmc ext_csd <device_num> <byte> <value> - write sd/emmc device EXT_CSD [byte] value\n" + "amlmmc response <device_num> - read sd/emmc last command response\n" + "amlmmc controller <device_num> - read sd/emmc controller register\n" + "amlmmc write_protect <partition_name> <write_protect_type>\n" + " - set write protect on partition through power_on or temporary\n" + "amlmmc write_protect <addr_base16> <cnt_base10> <write_protect_type>\n" + " - set write protect on specified address through power_on or temporary\n" + "amlmmc send_wp_status <partition_name> send protect status of partition\n" + "amlmmc send_wp_status <addr_base16> <cnt_base10> send protect status on specified address\n" + "amlmmc send_wp_type <partition_name> send protect type of partition\n" + "amlmmc send_wp_type <addr_base16> <cnt_base10> send protect type on specified address\n" + "amlmmc clear_wp <partition_name> clear write protect of partition\n" + "amlmmc clear_wp <addr_base16> <cnt_base10> clear write protect on specified addresst\n" + "amlmmc ds <dev_num> <val> set driver strength\n" #ifdef CONFIG_SECURITYKEY - "amlmmc key - disprotect key partition\n" + "amlmmc key - disprotect key partition\n" #endif #ifdef MMC_HS200_MODE - "amlmmc clktest <dev> - display info of delaycell and count\n" - "amlmmc reset_dly <dev> - reset all delay register\n" - "amlmmc set_rxdly <dev> <0xdelay1> <0xdelay2> - manually set rx delay value\n" - "amlmmc set_txdly <dev> <0xdelay> - manually set tx delay\n" - "amlmmc refix <dev> - fix adj\n" - "amlmmc move_all <dev> <count> - move all data delay line <count> steps\n" - "amlmmc move_single <dev> <line> <count> - move <line> <count> steps\n" - "amlmmc set_vddee <dev> <value> - set vddee\n" - "amlmmc show_vddee <dev> -show current vddee\n" - "amlmmc line_eyetest <dev> <line> single line eyetest\n" + "amlmmc clktest <dev> - display info of delaycell and count\n" + "amlmmc reset_dly <dev> - reset all delay register\n" + "amlmmc set_rxdly <dev> <0xdelay1> <0xdelay2> - manually set rx delay value\n" + "amlmmc set_txdly <dev> <0xdelay> - manually set tx delay\n" + "amlmmc refix <dev> - fix adj\n" + "amlmmc move_all <dev> <count> - move all data delay line <count> steps\n" + "amlmmc move_single <dev> <line> <count> - move <line> <count> steps\n" + "amlmmc set_vddee <dev> <value> - set vddee\n" + "amlmmc show_vddee <dev> -show current vddee\n" + "amlmmc line_eyetest <dev> <line> single line eyetest\n" #endif ); -/* dtb read&write operation with backup updates */ static u32 _calc_dtb_checksum(struct aml_dtb_rsv * dtb) { - int i = 0; - int size = sizeof(struct aml_dtb_rsv) - sizeof(u32); - u32 * buffer; - u32 checksum = 0; + int i = 0; + int size = sizeof(struct aml_dtb_rsv) - sizeof(u32); + u32 * buffer; + u32 checksum = 0; - if ((u64)dtb % 4 != 0) { - BUG(); - } + if ((u64)dtb % 4 != 0) { + BUG(); + } - size = size >> 2; - buffer = (u32*) dtb; - while (i < size) - checksum += buffer[i++]; + size = size >> 2; + buffer = (u32*) dtb; + while (i < size) + checksum += buffer[i++]; - return checksum; + return checksum; } static int _verify_dtb_checksum(struct aml_dtb_rsv * dtb) { - u32 checksum; + u32 checksum; - checksum = _calc_dtb_checksum(dtb); - dtb_info("calc %x, store %x\n", checksum, dtb->checksum); + checksum = _calc_dtb_checksum(dtb); + dtb_info("calc %x, store %x\n", checksum, dtb->checksum); - return !(checksum == dtb->checksum); + return !(checksum == dtb->checksum); } static int _dtb_read(struct mmc *mmc, u64 blk, u64 cnt, void * addr) { - int dev = EMMC_DTB_DEV; - u64 n; - n = mmc->block_dev.block_read(dev, blk, cnt, addr); - if (n != cnt) { - dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", - __func__, dev, blk, cnt); - } - - return (n != cnt); + int dev = EMMC_DTB_DEV; + u64 n; + n = mmc->block_dev.block_read(dev, blk, cnt, addr); + if (n != cnt) { + dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", + __func__, dev, blk, cnt); + } + + return (n != cnt); } static int _dtb_write(struct mmc *mmc, u64 blk, u64 cnt, void * addr) { - int dev = EMMC_DTB_DEV; - u64 n; - n = mmc->block_dev.block_write(dev, blk, cnt, addr); - if (n != cnt) { - dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", - __func__, dev, blk, cnt); - } - - return (n != cnt); + int dev = EMMC_DTB_DEV; + u64 n; + n = mmc->block_dev.block_write(dev, blk, cnt, addr); + if (n != cnt) { + dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", + __func__, dev, blk, cnt); + } + + return (n != cnt); } static struct mmc *_dtb_init(void) { - struct mmc *mmc = find_mmc_device(EMMC_DTB_DEV); - if (!mmc) { - dtb_err("not find mmc\n"); - return NULL; - } - - if (mmc_init(mmc)) { - dtb_err("mmc init failed\n"); - return NULL; - } - return mmc; + struct mmc *mmc = find_mmc_device(EMMC_DTB_DEV); + if (!mmc) { + dtb_err("not find mmc\n"); + return NULL; + } + + if (mmc_init(mmc)) { + dtb_err("mmc init failed\n"); + return NULL; + } + return mmc; } static int dtb_read_shortcut(struct mmc * mmc, void *addr) { - u64 blk, cnt, dtb_glb_offset; - int dev = EMMC_DTB_DEV; - struct aml_dtb_info *info = &dtb_infos; - struct partitions * part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - dtb_glb_offset = part->offset + vpart->offset; - /* short cut */ - if (info->valid[0]) { - dtb_info("short cut in...\n"); - blk = dtb_glb_offset / mmc->read_bl_len; - cnt = vpart->size / mmc->read_bl_len; - if (_dtb_read(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - /*try dtb2 if it's valid */ - if (info->valid[1]) { - blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; - cnt = vpart->size / mmc->read_bl_len; - if (_dtb_read(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - return -1; - } - } - } - return 0; - } - return -2; + u64 blk, cnt, dtb_glb_offset; + int dev = EMMC_DTB_DEV; + struct aml_dtb_info *info = &dtb_infos; + struct partitions * part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + dtb_glb_offset = part->offset + vpart->offset; + /* short cut */ + if (info->valid[0]) { + dtb_info("short cut in...\n"); + blk = dtb_glb_offset / mmc->read_bl_len; + cnt = vpart->size / mmc->read_bl_len; + if (_dtb_read(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + /*try dtb2 if it's valid */ + if (info->valid[1]) { + blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; + cnt = vpart->size / mmc->read_bl_len; + if (_dtb_read(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + return -1; + } + } + } + return 0; + } + return -2; } static int update_dtb_info(struct mmc *mmc, void *addr) { - int ret = 0, dev = EMMC_DTB_DEV; - u64 blk, cnt, dtb_glb_offset; - struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; - struct aml_dtb_info *info = &dtb_infos; - int cpy = 1, valid = 0; - struct partitions * part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - dtb_glb_offset = part->offset + vpart->offset; - - while (cpy >= 0) { - blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len; - cnt = vpart->size / mmc->read_bl_len; - ret = _dtb_read(mmc, blk, cnt, addr); - if (ret) { - dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - } else { - ret = _verify_dtb_checksum(dtb); - /* check magic avoid whole 0 issue */ - if (!ret && (dtb->magic != 0)) { - info->stamp[cpy] = dtb->timestamp; - info->valid[cpy] = 1; - } - else - dtb_wrn("cpy %d is not valid\n", cpy); - } - valid += info->valid[cpy]; - cpy --; - } - return valid; + int ret = 0, dev = EMMC_DTB_DEV; + u64 blk, cnt, dtb_glb_offset; + struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; + struct aml_dtb_info *info = &dtb_infos; + int cpy = 1, valid = 0; + struct partitions * part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + dtb_glb_offset = part->offset + vpart->offset; + + while (cpy >= 0) { + blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len; + cnt = vpart->size / mmc->read_bl_len; + ret = _dtb_read(mmc, blk, cnt, addr); + if (ret) { + dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + } else { + ret = _verify_dtb_checksum(dtb); + /* check magic avoid whole 0 issue */ + if (!ret && (dtb->magic != 0)) { + info->stamp[cpy] = dtb->timestamp; + info->valid[cpy] = 1; + } + else + dtb_wrn("cpy %d is not valid\n", cpy); + } + valid += info->valid[cpy]; + cpy --; + } + return valid; } static int update_invalid_dtb(struct mmc *mmc, void *addr) { - int ret = 0, dev = EMMC_DTB_DEV; - u64 blk, cnt, dtb_glb_offset; - struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; - struct aml_dtb_info *info = &dtb_infos; - struct partitions * part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - dtb_glb_offset = part->offset + vpart->offset; - cnt = vpart->size / mmc->read_bl_len; - - if (info->valid[1]) { - blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; - if (_dtb_read(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -2; - } - /* fixme, update the invalid one - dtb1 */ - blk = (dtb_glb_offset) / mmc->read_bl_len; - if (_dtb_write(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -4; - } - info->valid[0] = 1; - info->stamp[0] = dtb->timestamp; - ret = 0; - } else { - dtb_info("update dtb2"); - blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; - if (_dtb_write(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -2; - } - info->valid[1] = 1; - info->stamp[1] = dtb->timestamp; - } - return ret; + int ret = 0, dev = EMMC_DTB_DEV; + u64 blk, cnt, dtb_glb_offset; + struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; + struct aml_dtb_info *info = &dtb_infos; + struct partitions * part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + dtb_glb_offset = part->offset + vpart->offset; + cnt = vpart->size / mmc->read_bl_len; + + if (info->valid[1]) { + blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; + if (_dtb_read(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -2; + } + /* fixme, update the invalid one - dtb1 */ + blk = (dtb_glb_offset) / mmc->read_bl_len; + if (_dtb_write(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -4; + } + info->valid[0] = 1; + info->stamp[0] = dtb->timestamp; + ret = 0; + } else { + dtb_info("update dtb2"); + blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; + if (_dtb_write(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -2; + } + info->valid[1] = 1; + info->stamp[1] = dtb->timestamp; + } + return ret; } int update_old_dtb(struct mmc *mmc, void *addr) { - int ret = 0, dev = EMMC_DTB_DEV; - u64 blk, cnt, dtb_glb_offset; - struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; - struct aml_dtb_info *info = &dtb_infos; - struct partitions * part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - dtb_glb_offset = part->offset + vpart->offset; - cnt = vpart->size / mmc->read_bl_len; - if (stamp_after(info->stamp[1], info->stamp[0])) { - blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; - if (_dtb_read(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -3; - } - /*update dtb1*/ - blk = dtb_glb_offset / mmc->read_bl_len; - if (_dtb_write(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -3; - } - info->stamp[0] = dtb->timestamp; - ret = 0; - } else if (stamp_after(info->stamp[0], info->stamp[1])) { - /*update dtb2*/ - blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; - if (_dtb_write(mmc, blk, cnt, addr)) { - dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - ret = -3; - } - info->stamp[1] = dtb->timestamp; - } else { - dtb_info("do nothing\n"); - } - return ret; + int ret = 0, dev = EMMC_DTB_DEV; + u64 blk, cnt, dtb_glb_offset; + struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; + struct aml_dtb_info *info = &dtb_infos; + struct partitions * part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + dtb_glb_offset = part->offset + vpart->offset; + cnt = vpart->size / mmc->read_bl_len; + if (stamp_after(info->stamp[1], info->stamp[0])) { + blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; + if (_dtb_read(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -3; + } + /*update dtb1*/ + blk = dtb_glb_offset / mmc->read_bl_len; + if (_dtb_write(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -3; + } + info->stamp[0] = dtb->timestamp; + ret = 0; + } else if (stamp_after(info->stamp[0], info->stamp[1])) { + /*update dtb2*/ + blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len; + if (_dtb_write(mmc, blk, cnt, addr)) { + dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + ret = -3; + } + info->stamp[1] = dtb->timestamp; + } else { + dtb_info("do nothing\n"); + } + return ret; } int dtb_read(void *addr) { - int ret = 0; - int valid = 0; - struct mmc *mmc; - - mmc = _dtb_init(); - if (mmc == NULL) - return -10; - - if (dtb_read_shortcut(mmc, addr) == 0) - return ret; - - valid = update_dtb_info(mmc, addr); - dtb_info("total valid %d\n", valid); - /* check valid */ - switch (valid) { - /* none is valid, using the 1st one for compatibility*/ - case 0: - ret = -1; - goto _out; - break; - /* only 1 is valid, using the valid one */ - case 1: - update_invalid_dtb(mmc, addr); - break; - /* both are valid, pickup new one. */ - case 2: - update_old_dtb(mmc, addr); - break; - default: - dtb_err("impossble valid values.\n"); - BUG(); - break; - } + int ret = 0; + int valid = 0; + struct mmc *mmc; + + mmc = _dtb_init(); + if (mmc == NULL) + return -10; + + if (dtb_read_shortcut(mmc, addr) == 0) + return ret; + + valid = update_dtb_info(mmc, addr); + dtb_info("total valid %d\n", valid); + /* check valid */ + switch (valid) { + /* none is valid, using the 1st one for compatibility*/ + case 0: + ret = -1; + goto _out; + break; + /* only 1 is valid, using the valid one */ + case 1: + update_invalid_dtb(mmc, addr); + break; + /* both are valid, pickup new one. */ + case 2: + update_old_dtb(mmc, addr); + break; + default: + dtb_err("impossble valid values.\n"); + BUG(); + break; + } _out: - return ret; + return ret; } int dtb_write(void *addr) { - int ret = 0; - struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; - struct aml_dtb_info *info = &dtb_infos; - u64 blk, cnt, dtb_glb_offset; - int cpy, valid; - struct mmc * mmc; - struct partitions * part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - dtb_glb_offset = part->offset + vpart->offset; - - mmc = _dtb_init(); - if (NULL == mmc) - return -10; - - /* stamp */ - valid = info->valid[0] + info->valid[1]; - dtb_info("valid %d\n", valid); - if (0 == valid) - dtb->timestamp = 0; - else if (1 == valid) { - dtb->timestamp = 1 + info->stamp[info->valid[0]?0:1]; - } else { - /* both are valid */ - if (info->stamp[0] != info->stamp[1]) { - dtb_wrn("timestamp are not same %d:%d\n", - info->stamp[0], info->stamp[1]); - dtb->timestamp = 1 + stamp_after(info->stamp[1], info->stamp[0])? - info->stamp[1]:info->stamp[0]; - } else - dtb->timestamp = 1 + info->stamp[0]; - } - /*setting version and magic*/ - dtb->version = 1; /* base version */ - dtb->magic = 0x00447e41; /*A~D\0*/ - dtb->checksum = _calc_dtb_checksum(dtb); - dtb_info("new stamp %d, checksum 0x%x, version %d, magic %s\n", - dtb->timestamp, dtb->checksum, dtb->version, (char *)&dtb->magic); - - for (cpy = 0; cpy < DTB_COPIES; cpy++) { - blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len; - cnt = vpart->size / mmc->read_bl_len; - ret |= _dtb_write(mmc, blk, cnt, addr); - info->valid[cpy] = 1; - info->stamp[cpy] = dtb->timestamp; - } - - return ret; + int ret = 0; + struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr; + struct aml_dtb_info *info = &dtb_infos; + u64 blk, cnt, dtb_glb_offset; + int cpy, valid; + struct mmc * mmc; + struct partitions * part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + dtb_glb_offset = part->offset + vpart->offset; + + mmc = _dtb_init(); + if (NULL == mmc) + return -10; + + /* stamp */ + valid = info->valid[0] + info->valid[1]; + dtb_info("valid %d\n", valid); + if (0 == valid) + dtb->timestamp = 0; + else if (1 == valid) { + dtb->timestamp = 1 + info->stamp[info->valid[0]?0:1]; + } else { + /* both are valid */ + if (info->stamp[0] != info->stamp[1]) { + dtb_wrn("timestamp are not same %d:%d\n", + info->stamp[0], info->stamp[1]); + dtb->timestamp = 1 + stamp_after(info->stamp[1], info->stamp[0])? + info->stamp[1]:info->stamp[0]; + } else + dtb->timestamp = 1 + info->stamp[0]; + } + /*setting version and magic*/ + dtb->version = 1; /* base version */ + dtb->magic = 0x00447e41; /*A~D\0*/ + dtb->checksum = _calc_dtb_checksum(dtb); + dtb_info("new stamp %d, checksum 0x%x, version %d, magic %s\n", + dtb->timestamp, dtb->checksum, dtb->version, (char *)&dtb->magic); + + for (cpy = 0; cpy < DTB_COPIES; cpy++) { + blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len; + cnt = vpart->size / mmc->read_bl_len; + ret |= _dtb_write(mmc, blk, cnt, addr); + info->valid[cpy] = 1; + info->stamp[cpy] = dtb->timestamp; + } + + return ret; } extern int check_valid_dts(unsigned char *buffer); int renew_partition_tbl(unsigned char *buffer) { - int ret = 0; - unsigned char *temp = NULL; - - if (!buffer) - return 1; - temp = malloc (AML_DTB_IMG_MAX_SZ); - if (!temp) - return 1; - memcpy(temp, buffer, AML_DTB_IMG_MAX_SZ); - /* todo, check new dts imcoming.... */ - ret = check_valid_dts(temp); - free(temp); - - /* only the dts new is valid */ - if (!ret) { - free_partitions(); - get_partition_from_dts(buffer); - if (0 == mmc_device_init(_dtb_init())) { - printf("partition table success\n"); - ret = 0; - goto _out; - } - printf("partition table error\n"); - ret = 1; - } + int ret = 0; + unsigned char *temp = NULL; + + if (!buffer) + return 1; + temp = malloc (AML_DTB_IMG_MAX_SZ); + if (!temp) + return 1; + memcpy(temp, buffer, AML_DTB_IMG_MAX_SZ); + /* todo, check new dts imcoming.... */ + ret = check_valid_dts(temp); + free(temp); + + /* only the dts new is valid */ + if (!ret) { + free_partitions(); + get_partition_from_dts(buffer); + if (0 == mmc_device_init(_dtb_init())) { + printf("partition table success\n"); + ret = 0; + goto _out; + } + printf("partition table error\n"); + ret = 1; + } _out: - return ret; + return ret; } int do_amlmmc_dtb_key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev, ret = 0; - void *addr = NULL; - u64 cnt = 0, n = 0, blk = 0; - //u64 size; - struct partitions *part = NULL; - struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - - switch (argc) { - case 3: - if (strcmp(argv[1], "erase") == 0) { - if (strcmp(argv[2], "dtb") == 0) { - printf("start erase dtb......\n"); - dev = EMMC_DTB_DEV; - struct mmc *mmc = find_mmc_device(dev); - if (!mmc) { - printf("not find mmc\n"); - return 1; - } - blk = (part->offset + vpart->offset) / mmc->read_bl_len; - cnt = (vpart->size * 2) / mmc->read_bl_len; - if (cnt != 0) - n = mmc->block_dev.block_erase(dev, blk, cnt); - printf("dev # %d, %s, several blocks erased %s\n", - dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; - }else if (strcmp(argv[2], "key") == 0){ - printf("start erase key......\n"); - dev = 1; - struct mmc *mmc = find_mmc_device(dev); - if (!mmc) { - printf("not find mmc\n"); - return 1; - } - n = mmc_key_erase(); - printf("dev # %d, %s, several blocks erased %s\n", - dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; - } - } else if (strcmp(argv[1], "cali_pattern") == 0) { - - if (strcmp(argv[2], "write") == 0) { - dev = EMMC_DTB_DEV; - struct mmc *mmc = find_mmc_device(dev); - if (!mmc) { - printf("not find mmc\n"); - return 1; - } - vpart = aml_get_virtual_partition_by_name(MMC_PATTERN_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - addr = (void *)malloc(vpart->size); - if (addr == NULL) { - printf("cali_pattern malloc fail\n"); - return 1; - } - mmc_write_cali_mattern(addr); - blk = (part->offset + vpart->offset) / mmc->read_bl_len; - cnt = vpart->size / mmc->read_bl_len; - if (cnt != 0) - n = mmc->block_dev.block_write(dev, blk, cnt, addr); - printf("dev # %d, %s, several calibration pattern blocks write %s\n", - dev, (flag == 0) ? " ":(argv[2]),(n == cnt) ? "OK" : "ERROR"); - free(addr); - return (n == cnt) ? 0 : 1; - } - } - case 4: - addr = (void *)simple_strtoul(argv[2], NULL, 16); - if (strcmp(argv[1], "dtb_read") == 0) { - /* fixme, */ - ret = dtb_read(addr); - return 0; - - } else if (strcmp(argv[1], "dtb_write") == 0) { - /* fixme, should we check the return value? */ - ret = dtb_write(addr); - ret |= renew_partition_tbl(addr); - return ret; - } - return 0; - default: - break; - } - return 1; + int dev, ret = 0; + void *addr = NULL; + u64 cnt = 0, n = 0, blk = 0; + //u64 size; + struct partitions *part = NULL; + struct virtual_partition *vpart = NULL; + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + + switch (argc) { + case 3: + if (strcmp(argv[1], "erase") == 0) { + if (strcmp(argv[2], "dtb") == 0) { + printf("start erase dtb......\n"); + dev = EMMC_DTB_DEV; + struct mmc *mmc = find_mmc_device(dev); + if (!mmc) { + printf("not find mmc\n"); + return 1; + } + blk = (part->offset + vpart->offset) / mmc->read_bl_len; + cnt = (vpart->size * 2) / mmc->read_bl_len; + if (cnt != 0) + n = mmc->block_dev.block_erase(dev, blk, cnt); + printf("dev # %d, %s, several blocks erased %s\n", + dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); + return (n == 0) ? 0 : 1; + }else if (strcmp(argv[2], "key") == 0){ + printf("start erase key......\n"); + dev = 1; + struct mmc *mmc = find_mmc_device(dev); + if (!mmc) { + printf("not find mmc\n"); + return 1; + } + n = mmc_key_erase(); + printf("dev # %d, %s, several blocks erased %s\n", + dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); + return (n == 0) ? 0 : 1; + } + } else if (strcmp(argv[1], "cali_pattern") == 0) { + + if (strcmp(argv[2], "write") == 0) { + dev = EMMC_DTB_DEV; + struct mmc *mmc = find_mmc_device(dev); + if (!mmc) { + printf("not find mmc\n"); + return 1; + } + vpart = aml_get_virtual_partition_by_name(MMC_PATTERN_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + addr = (void *)malloc(vpart->size); + if (addr == NULL) { + printf("cali_pattern malloc fail\n"); + return 1; + } + mmc_write_cali_mattern(addr); + blk = (part->offset + vpart->offset) / mmc->read_bl_len; + cnt = vpart->size / mmc->read_bl_len; + if (cnt != 0) + n = mmc->block_dev.block_write(dev, blk, cnt, addr); + printf("dev # %d, %s, several calibration pattern blocks write %s\n", + dev, (flag == 0) ? " ":(argv[2]),(n == cnt) ? "OK" : "ERROR"); + free(addr); + return (n == cnt) ? 0 : 1; + } + } + case 4: + addr = (void *)simple_strtoul(argv[2], NULL, 16); + if (strcmp(argv[1], "dtb_read") == 0) { + /* fixme, */ + ret = dtb_read(addr); + return 0; + + } else if (strcmp(argv[1], "dtb_write") == 0) { + /* fixme, should we check the return value? */ + ret = dtb_write(addr); + ret |= renew_partition_tbl(addr); + return ret; + } + return 0; + default: + break; + } + return 1; } /* update partition table in reserved partition. */ __weak int emmc_update_ept(unsigned char *buffer) { - int ret = 0; + int ret = 0; #ifndef DTB_BIND_KERNEL - dtb_write(buffer); + dtb_write(buffer); #endif - ret = renew_partition_tbl(buffer); - return ret; + ret = renew_partition_tbl(buffer); + return ret; } /* fixme, should use renew_partition_tbl here! */ __weak int emmc_update_mbr(unsigned char *buffer) { - int ret = 0; - cpu_id_t cpu_id = get_cpu_id(); - - if (cpu_id.family_id < MESON_CPU_MAJOR_ID_GXL) { - ret = -1; - printf("MBR not support, try dtb\n"); - goto _out; - } + int ret = 0; + cpu_id_t cpu_id = get_cpu_id(); + + if (cpu_id.family_id < MESON_CPU_MAJOR_ID_GXL) { + ret = -1; + printf("MBR not support, try dtb\n"); + goto _out; + } #ifndef DTB_BIND_KERNEL - dtb_write(buffer); + dtb_write(buffer); #endif - ret = get_partition_from_dts(buffer); - if (ret) { - printf("Fail to get partition talbe from dts\n"); - goto _out; - } - ret = mmc_device_init(_dtb_init()); - printf("%s: update mbr %s\n", __func__, ret?"Fail":"Success"); + ret = get_partition_from_dts(buffer); + if (ret) { + printf("Fail to get partition talbe from dts\n"); + goto _out; + } + ret = mmc_device_init(_dtb_init()); + printf("%s: update mbr %s\n", __func__, ret?"Fail":"Success"); _out: - return ret; + return ret; } int do_emmc_erase(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev; - u64 cnt = 0, n = 0, blk = 0; - //u64 size; - struct partitions *part = NULL; - struct virtual_partition *vpart = NULL; - struct mmc *mmc; - if (argc != 3) - return CMD_RET_USAGE; - - vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - if (strcmp(argv[2], "dtb") == 0) { - printf("start erase dtb......\n"); - dev = EMMC_DTB_DEV; - mmc = find_mmc_device(dev); - if (!mmc) { - printf("not find mmc\n"); - return 1; - } - blk = (part->offset + vpart->offset) / mmc->read_bl_len; - cnt = (vpart->size * 2) / mmc->read_bl_len; - if (cnt != 0) - n = mmc->block_dev.block_erase(dev, blk, cnt); - printf("dev # %d, %s, several blocks erased %s\n", - dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; - } else if (strcmp(argv[2], "key") == 0) { - printf("start erase key......\n"); - dev = 1; - mmc = find_mmc_device(dev); - if (!mmc) { - printf("not find mmc\n"); - return 1; - } - n = mmc_key_erase(); - printf("dev # %d, %s, several blocks erased %s\n", - dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); - return (n == 0) ? 0 : 1; - } - return 1; + int dev; + u64 cnt = 0, n = 0, blk = 0; + //u64 size; + struct partitions *part = NULL; + struct virtual_partition *vpart = NULL; + struct mmc *mmc; + if (argc != 3) + return CMD_RET_USAGE; + + vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + if (strcmp(argv[2], "dtb") == 0) { + printf("start erase dtb......\n"); + dev = EMMC_DTB_DEV; + mmc = find_mmc_device(dev); + if (!mmc) { + printf("not find mmc\n"); + return 1; + } + blk = (part->offset + vpart->offset) / mmc->read_bl_len; + cnt = (vpart->size * 2) / mmc->read_bl_len; + if (cnt != 0) + n = mmc->block_dev.block_erase(dev, blk, cnt); + printf("dev # %d, %s, several blocks erased %s\n", + dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); + return (n == 0) ? 0 : 1; + } else if (strcmp(argv[2], "key") == 0) { + printf("start erase key......\n"); + dev = 1; + mmc = find_mmc_device(dev); + if (!mmc) { + printf("not find mmc\n"); + return 1; + } + n = mmc_key_erase(); + printf("dev # %d, %s, several blocks erased %s\n", + dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR"); + return (n == 0) ? 0 : 1; + } + return 1; } int do_emmc_dtb_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - void *addr = NULL; + int ret = 0; + void *addr = NULL; - if (argc != 4) - return CMD_RET_USAGE; + if (argc != 4) + return CMD_RET_USAGE; - addr = (void *)simple_strtoul(argv[2], NULL, 16); - ret = dtb_read(addr); - return ret; + addr = (void *)simple_strtoul(argv[2], NULL, 16); + ret = dtb_read(addr); + return ret; } int do_emmc_dtb_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - void *addr = NULL; + int ret = 0; + void *addr = NULL; - if (argc != 4) - return CMD_RET_USAGE; + if (argc != 4) + return CMD_RET_USAGE; - addr = (void *)simple_strtoul(argv[2], NULL, 16); - ret = dtb_write(addr); - ret |= renew_partition_tbl(addr); - return ret; + addr = (void *)simple_strtoul(argv[2], NULL, 16); + ret = dtb_write(addr); + ret |= renew_partition_tbl(addr); + return ret; } static int _fastboot_context_read(struct mmc *mmc, u64 blk, - u64 cnt, void *addr) + u64 cnt, void *addr) { - int dev = EMMC_FASTBOOT_CONTEXT_DEV; - u64 n; + int dev = EMMC_FASTBOOT_CONTEXT_DEV; + u64 n; - n = mmc->block_dev.block_read(dev, blk, cnt, addr); - if (n != cnt) { - fb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", - __func__, dev, blk, cnt); - } + n = mmc->block_dev.block_read(dev, blk, cnt, addr); + if (n != cnt) { + fb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n", + __func__, dev, blk, cnt); + } - return n != cnt; + return n != cnt; } int fastboot_context_read(void *buf, size_t size) { - uint32_t crc_result; - struct mmc *mmc; - struct FastbootContext *fb_cont; - int fb_size = sizeof(struct FastbootContext); - u64 blk, cnt, fb_glb_offset; - int dev = EMMC_FASTBOOT_CONTEXT_DEV; - struct partitions *part = NULL; - struct virtual_partition *vpart = NULL; - - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - if (mmc_init(mmc)) { - printf("%s() %d: emmc init failed\n", __func__, __LINE__); - return 1; - } - - vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - fb_glb_offset = part->offset + vpart->offset; - - blk = fb_glb_offset / mmc->read_bl_len; - cnt = size / mmc->read_bl_len; - - if (_fastboot_context_read(mmc, blk, cnt, buf)) - return 1; - - fb_cont = (struct FastbootContext *)buf; - crc_result = crc32(0, buf, fb_size - 4); - - if (crc_result != fb_cont->crc32) { - printf("%s %d: crc checksum ERROR!\n", __func__, __LINE__); - return 1; - } - return 0; + uint32_t crc_result; + struct mmc *mmc; + struct FastbootContext *fb_cont; + int fb_size = sizeof(struct FastbootContext); + u64 blk, cnt, fb_glb_offset; + int dev = EMMC_FASTBOOT_CONTEXT_DEV; + struct partitions *part = NULL; + struct virtual_partition *vpart = NULL; + + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + if (mmc_init(mmc)) { + printf("%s() %d: emmc init failed\n", __func__, __LINE__); + return 1; + } + + vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + fb_glb_offset = part->offset + vpart->offset; + + blk = fb_glb_offset / mmc->read_bl_len; + cnt = size / mmc->read_bl_len; + + if (_fastboot_context_read(mmc, blk, cnt, buf)) + return 1; + + fb_cont = (struct FastbootContext *)buf; + crc_result = crc32(0, buf, fb_size - 4); + + if (crc_result != fb_cont->crc32) { + printf("%s %d: crc checksum ERROR!\n", __func__, __LINE__); + return 1; + } + return 0; } int do_emmc_fb_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - void *addr = NULL; - u64 size; + int ret = 0; + void *addr = NULL; + u64 size; - if (argc != 4) - return CMD_RET_USAGE; + if (argc != 4) + return CMD_RET_USAGE; - addr = (void *)simple_strtoul(argv[2], NULL, 16); - size = simple_strtoull(argv[3], NULL, 16); - ret = fastboot_context_read(addr, size); - return ret; + addr = (void *)simple_strtoul(argv[2], NULL, 16); + size = simple_strtoull(argv[3], NULL, 16); + ret = fastboot_context_read(addr, size); + return ret; } static int _fastboot_context_write(struct mmc *mmc, u64 blk, - u64 cnt, void *addr) + u64 cnt, void *addr) { - int dev = EMMC_FASTBOOT_CONTEXT_DEV; - int n; + int dev = EMMC_FASTBOOT_CONTEXT_DEV; + int n; - n = mmc->block_dev.block_write(dev, blk, cnt, addr); + n = mmc->block_dev.block_write(dev, blk, cnt, addr); - if (n != cnt) { - fb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", - __func__, dev, blk, cnt); - } + if (n != cnt) { + fb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n", + __func__, dev, blk, cnt); + } - return n != cnt; + return n != cnt; } int fastboot_context_write(void *buf, size_t size) { - int ret = 0; - struct FastbootContext *fb_cont = (struct FastbootContext *)buf; - u64 blk, cnt, fb_glb_offset; - struct mmc *mmc; - struct partitions *part = NULL; - struct virtual_partition *vpart = NULL; - int dev = EMMC_FASTBOOT_CONTEXT_DEV; - int fb_size = sizeof(struct FastbootContext); - - mmc = find_mmc_device(dev); - if (!mmc) { - puts("no mmc devices available\n"); - return 1; - } - - ret = mmc_init(mmc); - if (ret) { - printf("%s() %d: emmc init failed\n", __func__, __LINE__); - return 1; - } - - vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - fb_glb_offset = part->offset + vpart->offset; - fb_cont->crc32 = crc32(0, buf, fb_size - 4); - blk = fb_glb_offset / mmc->read_bl_len; - cnt = size / mmc->read_bl_len; - ret = _fastboot_context_write(mmc, blk, cnt, buf); - - return ret; + int ret = 0; + struct FastbootContext *fb_cont = (struct FastbootContext *)buf; + u64 blk, cnt, fb_glb_offset; + struct mmc *mmc; + struct partitions *part = NULL; + struct virtual_partition *vpart = NULL; + int dev = EMMC_FASTBOOT_CONTEXT_DEV; + int fb_size = sizeof(struct FastbootContext); + + mmc = find_mmc_device(dev); + if (!mmc) { + puts("no mmc devices available\n"); + return 1; + } + + ret = mmc_init(mmc); + if (ret) { + printf("%s() %d: emmc init failed\n", __func__, __LINE__); + return 1; + } + + vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); + fb_glb_offset = part->offset + vpart->offset; + fb_cont->crc32 = crc32(0, buf, fb_size - 4); + blk = fb_glb_offset / mmc->read_bl_len; + cnt = size / mmc->read_bl_len; + ret = _fastboot_context_write(mmc, blk, cnt, buf); + + return ret; } int do_emmc_fb_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - void *addr = NULL; - u64 size; + int ret = 0; + void *addr = NULL; + u64 size; - if (argc != 4) - return CMD_RET_USAGE; + if (argc != 4) + return CMD_RET_USAGE; - addr = (void *)simple_strtoul(argv[2], NULL, 16); - size = simple_strtoull(argv[3], NULL, 16); - ret = fastboot_context_write(addr, size); - return ret; + addr = (void *)simple_strtoul(argv[2], NULL, 16); + size = simple_strtoull(argv[3], NULL, 16); + ret = fastboot_context_write(addr, size); + return ret; } static cmd_tbl_t cmd_emmc[] = { - U_BOOT_CMD_MKENT(dtb_read, 4, 0, do_emmc_dtb_read, "", ""), - U_BOOT_CMD_MKENT(dtb_write, 4, 0, do_emmc_dtb_write, "", ""), - U_BOOT_CMD_MKENT(erase, 3, 0, do_emmc_erase, "", ""), - U_BOOT_CMD_MKENT(fastboot_read, 4, 0, do_emmc_fb_read, "", ""), - U_BOOT_CMD_MKENT(fastboot_write, 4, 0, do_emmc_fb_write, "", ""), + U_BOOT_CMD_MKENT(dtb_read, 4, 0, do_emmc_dtb_read, "", ""), + U_BOOT_CMD_MKENT(dtb_write, 4, 0, do_emmc_dtb_write, "", ""), + U_BOOT_CMD_MKENT(erase, 3, 0, do_emmc_erase, "", ""), + U_BOOT_CMD_MKENT(fastboot_read, 4, 0, do_emmc_fb_read, "", ""), + U_BOOT_CMD_MKENT(fastboot_write, 4, 0, do_emmc_fb_write, "", ""), }; static int do_emmc_dtb_key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - cmd_tbl_t *cp; + cmd_tbl_t *cp; - cp = find_cmd_tbl(argv[1], cmd_emmc, ARRAY_SIZE(cmd_emmc)); + cp = find_cmd_tbl(argv[1], cmd_emmc, ARRAY_SIZE(cmd_emmc)); - if (cp == NULL || argc > cp->maxargs) - return CMD_RET_USAGE; - if (flag == CMD_FLAG_REPEAT && !cp->repeatable) - return CMD_RET_SUCCESS; - return cp->cmd(cmdtp, flag, argc, argv); + if (cp == NULL || argc > cp->maxargs) + return CMD_RET_USAGE; + if (flag == CMD_FLAG_REPEAT && !cp->repeatable) + return CMD_RET_SUCCESS; + return cp->cmd(cmdtp, flag, argc, argv); } U_BOOT_CMD( - emmc, 4, 1, do_emmc_dtb_key, - "EMMC sub system", - "dtb_read addr size\n" - "emmc dtb_write addr size\n" - "emmc erase dtb\n" - "emmc erase key\n" - "emmc fastboot_read addr size\n" - "emmc fastboot_write addr size\n"); + emmc, 4, 1, do_emmc_dtb_key, + "EMMC sub system", + "dtb_read addr size\n" + "emmc dtb_write addr size\n" + "emmc erase dtb\n" + "emmc erase key\n" + "emmc fastboot_read addr size\n" + "emmc fastboot_write addr size\n"); diff --git a/common/store_interface.c b/common/store_interface.c index eb8508f5d2..5e0f75397c 100644 --- a/common/store_interface.c +++ b/common/store_interface.c @@ -20,12 +20,13 @@ #include <asm/arch/cpu_config.h> #if defined(CONFIG_AML_NAND) || defined (CONFIG_AML_MTD) -/* key opeartions of nand */ extern int amlnf_init(unsigned flag); extern void nand_init(void); extern int amlnf_key_write(u8 *buf, int len, uint32_t *actual_lenth); extern int amlnf_key_read(u8 * buf, int len, uint32_t *actual_lenth); -/* dtb operations of nand */ +extern int amlnf_ddr_parameter_read(u8 *buf, int len); +extern int amlnf_ddr_parameter_write(u8 *buf, int len); +extern int amlnf_ddr_parameter_erase(void); #endif #if defined(CONFIG_DISCRETE_BOOTLOADER) @@ -49,6 +50,10 @@ extern int mmc_key_erase(void); extern int find_dev_num_by_partition_name (char *name); extern unsigned emmc_cur_partition; +extern int mmc_ddr_parameter_read(unsigned char *buf, unsigned int size); +extern int mmc_ddr_parameter_write(unsigned char *buf, unsigned int size); +extern int mmc_ddr_parameter_erase(void); + #define debugP(fmt...) //printf("Dbg[store]L%d:", __LINE__),printf(fmt) #define MsgP(fmt...) printf("[store]"fmt) #define ErrP(fmt...) printf("[store]Err:%s,L%d:", __func__, __LINE__),printf(fmt) @@ -194,11 +199,11 @@ static int emmc_init(void) static int get_device_boot_flag(void) { int ret=0; - if (1) {//nand and emmc + if (1) {//nand and emmc //try eMMC init device_boot_flag = EMMC_BOOT_FLAG; ret = emmc_init(); - if (!ret) { + if (!ret) { printf("XXXXXXX======enter EMMC boot======XXXXXX\n"); return 0; } @@ -212,7 +217,7 @@ static int get_device_boot_flag(void) nand_init(); #endif ret = (device_boot_flag == NAND_BOOT_FLAG) ? 0 : __LINE__; - if (!ret) { + if (!ret) { printf("XXXXXXX======enter NAND boot======XXXXXX\n"); return 0; } @@ -228,8 +233,8 @@ static int get_device_boot_flag(void) static int get_off_size(int argc, char *argv[], loff_t *off, loff_t *size) { - if (argc >= 1) { - if (!(str2longlong(argv[0], (unsigned long long*)off))) { + if (argc >= 1) { + if (!(str2longlong(argv[0], (unsigned long long*)off))) { store_msg("'%s' is not a number\n", argv[0]); return -1; } @@ -238,8 +243,8 @@ static int get_off_size(int argc, char *argv[], loff_t *off, loff_t *size) *size = 0; } - if (argc >= 2) { - if (!(str2longlong(argv[1], (unsigned long long *)size))) { + if (argc >= 2) { + if (!(str2longlong(argv[1], (unsigned long long *)size))) { store_msg("'%s' is not a number\n", argv[1]); return -1; } @@ -255,100 +260,100 @@ static int get_off_size(int argc, char *argv[], loff_t *off, loff_t *size) //store dtb read/write buff size static int do_store_dtb_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - char _cmdBuf[128]; - char* ops = argv[2]; - const unsigned maxDtbSz = 256 * 1024; - unsigned actualDtbSz = 0; - char* devCmd = NULL; - char* dtbLoadaddr = argv[3]; - - if (argc < 4) return CMD_RET_USAGE; - - const int is_write = !strcmp("write", ops); - if (!is_write) { - ret = !strcmp("read", ops) || !strcmp("iread", ops);//must be 0 - if (!ret) return CMD_RET_USAGE; - } - - actualDtbSz = maxDtbSz; - if (argc > 4) { - const unsigned bufSz = simple_strtoul(argv[4], NULL, 0); - if (bufSz > maxDtbSz) { - ErrP("bufSz (%s) > max 0x%x\n", argv[4], maxDtbSz); - return CMD_RET_FAILURE; - } - } - - ops = is_write ? "dtb_write" : "dtb_read"; - - switch (device_boot_flag) - { - case NAND_BOOT_FLAG: - case SPI_NAND_FLAG: - { - devCmd = "amlnf"; - } - break; - - case EMMC_BOOT_FLAG: - case SPI_EMMC_FLAG: - { - devCmd = "emmc"; - } - break; - - default: - ErrP("device_boot_flag=0x%x err\n", device_boot_flag); - return CMD_RET_FAILURE; - } - - sprintf(_cmdBuf, "%s %s %s 0x%x", devCmd, ops, dtbLoadaddr, actualDtbSz); - MsgP("To run cmd[%s]\n", _cmdBuf); - ret = run_command(_cmdBuf, 0); - - unsigned long dtImgAddr = simple_strtoul(dtbLoadaddr, NULL, 16); - // - //ONLY need decrypting when 'store dtb read' - if (!strcmp("read", argv[2])) - { - flush_cache(dtImgAddr, AML_DTB_IMG_MAX_SZ); - ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, dtImgAddr, AML_DTB_IMG_MAX_SZ, 0); - if (ret) { - MsgP("decrypt dtb: Sig Check %d\n",ret); - return ret; - } - } - - if (!is_write && strcmp("iread", argv[2])) - { - ulong nCheckOffset; - nCheckOffset = aml_sec_boot_check(AML_D_Q_IMG_SIG_HDR_SIZE,GXB_IMG_LOAD_ADDR,GXB_EFUSE_PATTERN_SIZE,GXB_IMG_DEC_ALL); + int ret = 0; + char _cmdBuf[128]; + char* ops = argv[2]; + const unsigned maxDtbSz = 256 * 1024; + unsigned actualDtbSz = 0; + char* devCmd = NULL; + char* dtbLoadaddr = argv[3]; + + if (argc < 4) return CMD_RET_USAGE; + + const int is_write = !strcmp("write", ops); + if (!is_write) { + ret = !strcmp("read", ops) || !strcmp("iread", ops);//must be 0 + if (!ret) return CMD_RET_USAGE; + } + + actualDtbSz = maxDtbSz; + if (argc > 4) { + const unsigned bufSz = simple_strtoul(argv[4], NULL, 0); + if (bufSz > maxDtbSz) { + ErrP("bufSz (%s) > max 0x%x\n", argv[4], maxDtbSz); + return CMD_RET_FAILURE; + } + } + + ops = is_write ? "dtb_write" : "dtb_read"; + + switch (device_boot_flag) + { + case NAND_BOOT_FLAG: + case SPI_NAND_FLAG: + { + devCmd = "amlnf"; + } + break; + + case EMMC_BOOT_FLAG: + case SPI_EMMC_FLAG: + { + devCmd = "emmc"; + } + break; + + default: + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return CMD_RET_FAILURE; + } + + sprintf(_cmdBuf, "%s %s %s 0x%x", devCmd, ops, dtbLoadaddr, actualDtbSz); + MsgP("To run cmd[%s]\n", _cmdBuf); + ret = run_command(_cmdBuf, 0); + + unsigned long dtImgAddr = simple_strtoul(dtbLoadaddr, NULL, 16); + // + //ONLY need decrypting when 'store dtb read' + if (!strcmp("read", argv[2])) + { + flush_cache(dtImgAddr, AML_DTB_IMG_MAX_SZ); + ret = aml_sec_boot_check(AML_D_P_IMG_DECRYPT, dtImgAddr, AML_DTB_IMG_MAX_SZ, 0); + if (ret) { + MsgP("decrypt dtb: Sig Check %d\n",ret); + return ret; + } + } + + if (!is_write && strcmp("iread", argv[2])) + { + ulong nCheckOffset; + nCheckOffset = aml_sec_boot_check(AML_D_Q_IMG_SIG_HDR_SIZE,GXB_IMG_LOAD_ADDR,GXB_EFUSE_PATTERN_SIZE,GXB_IMG_DEC_ALL); if (AML_D_Q_IMG_SIG_HDR_SIZE == (nCheckOffset & 0xFFFF)) - nCheckOffset = (nCheckOffset >> 16) & 0xFFFF; - else - nCheckOffset = 0; + nCheckOffset = (nCheckOffset >> 16) & 0xFFFF; + else + nCheckOffset = 0; if (nCheckOffset) - memmove((char *)dtImgAddr, (char*)dtImgAddr + nCheckOffset, AML_DTB_IMG_MAX_SZ); - } + memmove((char *)dtImgAddr, (char*)dtImgAddr + nCheckOffset, AML_DTB_IMG_MAX_SZ); + } #ifdef CONFIG_MULTI_DTB - if (!is_write && strcmp("iread", argv[2])) - { - extern unsigned long get_multi_dt_entry(unsigned long fdt_addr); - - unsigned long fdtAddr = get_multi_dt_entry(dtImgAddr); - ret = fdt_check_header((char*)fdtAddr); - if (ret) { - ErrP("Fail in fdt check header\n"); - return CMD_RET_FAILURE; - } - unsigned fdtsz = fdt_totalsize((char*)fdtAddr); - memmove((char*)dtImgAddr, (char*)fdtAddr, fdtsz); - } + if (!is_write && strcmp("iread", argv[2])) + { + extern unsigned long get_multi_dt_entry(unsigned long fdt_addr); + + unsigned long fdtAddr = get_multi_dt_entry(dtImgAddr); + ret = fdt_check_header((char*)fdtAddr); + if (ret) { + ErrP("Fail in fdt check header\n"); + return CMD_RET_FAILURE; + } + unsigned fdtsz = fdt_totalsize((char*)fdtAddr); + memmove((char*)dtImgAddr, (char*)fdtAddr, fdtsz); + } #endif// #ifdef CONFIG_MULTI_DTB - return ret; + return ret; } /* @@ -358,75 +363,128 @@ static int do_store_dtb_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const extern int emmc_update_mbr(unsigned char *buffer); static int do_store_mbr_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - unsigned char *buffer; - cpu_id_t cpu_id = get_cpu_id(); - - if ((cpu_id.family_id < MESON_CPU_MAJOR_ID_GXL) - || (device_boot_flag != EMMC_BOOT_FLAG)) { - ret = -1; - ErrP("MBR not support, try [store dtb write Addr]\n"); - goto _out; - } - - if (argc < 3) return CMD_RET_USAGE; - - buffer = (unsigned char *)simple_strtoul(argv[2], NULL, 16); - ret = emmc_update_mbr(buffer); - if (ret) { - ErrP("fail to update mbr\n"); - goto _out; - } + int ret = 0; + unsigned char *buffer; + cpu_id_t cpu_id = get_cpu_id(); + + if ((cpu_id.family_id < MESON_CPU_MAJOR_ID_GXL) + || (device_boot_flag != EMMC_BOOT_FLAG)) { + ret = -1; + ErrP("MBR not support, try [store dtb write Addr]\n"); + goto _out; + } + + if (argc < 3) return CMD_RET_USAGE; + + buffer = (unsigned char *)simple_strtoul(argv[2], NULL, 16); + ret = emmc_update_mbr(buffer); + if (ret) { + ErrP("fail to update mbr\n"); + goto _out; + } _out: - return ret; + return ret; } +#define IS_STORAGE_EMMC_BOOT(device) (((device) == EMMC_BOOT_FLAG) \ + || ((device) == SPI_EMMC_FLAG)) +#define STORAGE_BOOT_UNKNOWN(device) (((device) != EMMC_BOOT_FLAG) \ + && ((device) != SPI_EMMC_FLAG) \ + && ((device) != NAND_BOOT_FLAG) \ + && ((device) != SPI_NAND_FLAG)) -int store_key_read(uint8_t * buffer, uint32_t length, uint32_t *actual_lenth) +int store_ddr_parameter_read(uint8_t *buffer, + uint32_t length) { - int ret = 0; - switch (device_boot_flag) - { - case NAND_BOOT_FLAG: - case SPI_NAND_FLAG: - #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - ret = amlnf_key_read(buffer, (int) length, actual_lenth); - #endif - break; - case EMMC_BOOT_FLAG: - case SPI_EMMC_FLAG: - ret = mmc_key_read(buffer, (int) length, actual_lenth); - break; - default: - ErrP("device_boot_flag=0x%x err\n", device_boot_flag); - return CMD_RET_FAILURE; - } - return ret; + int ret = 0; + + if (STORAGE_BOOT_UNKNOWN(device_boot_flag)) { + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return -ENODEV; + } + + if (IS_STORAGE_EMMC_BOOT(device_boot_flag)) + ret = mmc_ddr_parameter_read(buffer, (int)length); +#if defined(CONFIG_AML_MTD) + else + ret = amlnf_ddr_parameter_read(buffer, (int)length); +#endif + return ret; } -int store_key_write(uint8_t * buffer, uint32_t length, uint32_t *actual_lenth) +int store_ddr_parameter_write(uint8_t *buffer, uint32_t length) { - int ret = 0; + int ret = 0; - switch (device_boot_flag) - { - case NAND_BOOT_FLAG: - case SPI_NAND_FLAG: - #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - ret = amlnf_key_write(buffer, (int) length, actual_lenth); - #endif - break; - - case EMMC_BOOT_FLAG: - case SPI_EMMC_FLAG: - ret = mmc_key_write(buffer, (int) length, actual_lenth); - break; - default: - ErrP("device_boot_flag=0x%x err\n", device_boot_flag); - return CMD_RET_FAILURE; - } - return ret; + if (STORAGE_BOOT_UNKNOWN(device_boot_flag)) { + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return -ENODEV; + } + + if (IS_STORAGE_EMMC_BOOT(device_boot_flag)) + ret = mmc_ddr_parameter_write(buffer, (int)length); +#if defined(CONFIG_AML_MTD) + else + ret = amlnf_ddr_parameter_write(buffer, (int)length); +#endif + return ret; +} + +int store_ddr_parameter_erase(void) +{ + int ret = 0; + + if (STORAGE_BOOT_UNKNOWN(device_boot_flag)) { + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return -ENODEV; + } + + if (IS_STORAGE_EMMC_BOOT(device_boot_flag)) + ret = mmc_ddr_parameter_erase(); +#if defined(CONFIG_AML_MTD) + else + ret = amlnf_ddr_parameter_erase(); +#endif + return ret; +} + +int store_key_read(uint8_t *buffer, + uint32_t length, uint32_t *actual_lenth) +{ + int ret = 0; + + if (STORAGE_BOOT_UNKNOWN(device_boot_flag)) { + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return -ENODEV; + } + + if (IS_STORAGE_EMMC_BOOT(device_boot_flag)) + ret = mmc_key_read(buffer, (int)length, actual_lenth); +#if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) + else + ret = amlnf_key_read(buffer, (int)length, actual_lenth); +#endif + return ret; +} + +int store_key_write(uint8_t *buffer, + uint32_t length, uint32_t *actual_lenth) +{ + int ret = 0; + + if (STORAGE_BOOT_UNKNOWN(device_boot_flag)) { + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return -ENODEV; + } + + if (IS_STORAGE_EMMC_BOOT(device_boot_flag)) + ret = mmc_key_write(buffer, (int)length, actual_lenth); +#if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) + else + ret = amlnf_key_write(buffer, (int)length, actual_lenth); +#endif + return ret; } static int do_store_key_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) @@ -438,18 +496,18 @@ static int do_store_key_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const unsigned actualDtbSz = 0; char* devCmd = NULL; - if (argc < 4) return CMD_RET_USAGE; + if (argc < 4) return CMD_RET_USAGE; const int is_write = !strcmp("write", ops); - if (!is_write) { + if (!is_write) { ret = strcmp("read", ops);//must be 0 - if (ret) return CMD_RET_USAGE; + if (ret) return CMD_RET_USAGE; } actualDtbSz = maxKyeSz; - if (argc > 4) { + if (argc > 4) { const unsigned bufSz = simple_strtoul(argv[4], NULL, 0); - if (bufSz > maxKyeSz) { + if (bufSz > maxKyeSz) { ErrP("bufSz (%s) > max 0x%x\n", argv[4], maxKyeSz); return CMD_RET_FAILURE; } @@ -457,25 +515,18 @@ static int do_store_key_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const ops = is_write ? "key_write" : "key_read"; - switch (device_boot_flag) - { - case NAND_BOOT_FLAG: - case SPI_NAND_FLAG: - { - devCmd = "amlnf"; - } - break; - - case EMMC_BOOT_FLAG: - case SPI_EMMC_FLAG: - { - devCmd = "emmc"; - } - break; - - default: - ErrP("device_boot_flag=0x%x err\n", device_boot_flag); - return CMD_RET_FAILURE; + switch (device_boot_flag) { + case NAND_BOOT_FLAG: + case SPI_NAND_FLAG: + devCmd = "amlnf"; + break; + case EMMC_BOOT_FLAG: + case SPI_EMMC_FLAG: + devCmd = "emmc"; + break; + default: + ErrP("device_boot_flag=0x%x err\n", device_boot_flag); + return CMD_RET_FAILURE; } sprintf(_cmdBuf, "%s %s %s 0x%x", devCmd, ops, argv[3], actualDtbSz); @@ -485,6 +536,44 @@ static int do_store_key_ops(cmd_tbl_t * cmdtp, int flag, int argc, char * const return ret; } +static int do_store_ddr_parameter_ops(cmd_tbl_t * cmdtp, + int flag, int argc, char * const argv[]) +{ + unsigned long addr; + int ret = 0; + char* ops = argv[2]; + const unsigned maxDdrPSz = 2 * 1024; + unsigned int actualDtbSz = 0; + + if (!strcmp("erase", ops) && (argc == 3)) { + ret = store_ddr_parameter_erase(); + return ret; + } + + if (argc < 4) return CMD_RET_USAGE; + + const int is_write = !strcmp("write", ops); + if (!is_write) { + ret = strcmp("read", ops);//must be 0 + if (ret) return CMD_RET_USAGE; + } + actualDtbSz = maxDdrPSz; + if (argc > 4) { + const unsigned bufSz = simple_strtoul(argv[4], NULL, 0); + if (bufSz > maxDdrPSz) { + ErrP("bufSz (%s) > max 0x%x\n", argv[4], maxDdrPSz); + return CMD_RET_FAILURE; + } + } + addr = (ulong)simple_strtoul(argv[3], NULL, 16); + if (is_write) + store_ddr_parameter_write((uint8_t *)addr, actualDtbSz); + else + store_ddr_parameter_read((uint8_t *)addr, actualDtbSz); + + return ret; +} + static int do_store_init(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i, init_flag=0, ret = 0; @@ -495,20 +584,20 @@ static int do_store_init(cmd_tbl_t * cmdtp, int flag, int argc, char * const arg store_dbg("init_flag %d",init_flag); //Forcing updateing device_boot_flag every time 'store init' - if (device_boot_flag == _AML_DEVICE_BOOT_FLAG_DEFAULT || 1) { + if (device_boot_flag == _AML_DEVICE_BOOT_FLAG_DEFAULT || 1) { i = get_device_boot_flag(); - if (i) { + if (i) { MsgP("ERR:FAILED in get_device_boot_flag\n"); return __LINE__; } } - switch (device_boot_flag) + switch (device_boot_flag) { #if defined(CONFIG_AML_NAND) case NAND_BOOT_FLAG: { - if ((init_flag >=STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <=STORE_BOOT_SCRUB_ALL)) { + if ((init_flag >=STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <=STORE_BOOT_SCRUB_ALL)) { sprintf(str, "amlnf init %d ",init_flag); run_command(str, 0); } @@ -517,512 +606,512 @@ static int do_store_init(cmd_tbl_t * cmdtp, int flag, int argc, char * const arg printf("command: %s <- %d\n", str, init_flag); device_boot_flag = NAND_BOOT_FLAG; ret = run_command(str, 0); - if (ret != 0) { + if (ret != 0) { return -1; - } - return ret; - } - break; + } + return ret; + } + break; #endif// #if defined(CONFIG_AML_NAND) #ifdef CONFIG_AML_MTD - case NAND_BOOT_FLAG: - { - ret = run_command("nand init", 0); + case NAND_BOOT_FLAG: + { + ret = run_command("nand init", 0); if (init_flag >= STORE_BOOT_ERASE_PROTECT_CACHE) { - ret |= run_command("amlnf rom_erase",0); - ret |= run_command("nand device 1", 0); - ret |= run_command("nand erase.chip", 0); - } - } - return ret; + ret |= run_command("amlnf rom_erase",0); + ret |= run_command("nand device 1", 0); + ret |= run_command("nand erase.chip", 0); + } + } + return ret; #endif// #ifdef CONFIG_AML_MTD - case EMMC_BOOT_FLAG: - { - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); - device_boot_flag = EMMC_BOOT_FLAG; - sprintf(str, "mmc dev %d", CONFIG_SYS_MMC_ENV_DEV); - run_command(str,0); - ret = run_command("mmcinfo", 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache - ret = run_command("amlmmc erase non_cache", 0); - }else if(init_flag >= STORE_BOOT_ERASE_ALL){ // erase all except reserved area - if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { - MsgP("amlmmc key\n"); - run_command("amlmmc key", 0); - } - sprintf(str, "amlmmc erase %d", CONFIG_SYS_MMC_ENV_DEV); - MsgP("amlmmc erase %d", CONFIG_SYS_MMC_ENV_DEV); - ret = run_command(str, 0); - } - - return ret; - } - break; - case SPI_EMMC_FLAG: - case SPI_NAND_FLAG: - { - /* - if (device_boot_flag == -1) - { - ret = run_command("sf probe 2", 0); - if (ret) { - store_msg(" cmd %s failed \n",cmd); - return -1; - } - if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { - sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); - ret = run_command(str,0); - } - sprintf(str, "amlnf init %d ",init_flag); - store_dbg("command: %s", str); - ret = run_command(str, 0); - if (ret < 0) //fail to init NAND flash - { - store_msg("nand cmd %s failed \n",cmd); - device_boot_flag = SPI_EMMC_FLAG; - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - ret = run_command("mmcinfo 1", 0); - if (ret != 0) { - store_msg("mmc cmd %s failed \n",cmd); - return -2; - } - if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache - store_msg("mmc erase non_cache \n"); - ret = run_command("mmc erase non_cache", 0); - }else if(init_flag >= STORE_BOOT_ERASE_ALL){ // erase all except reserved area - if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { - MsgP("mmc key;\n"); - run_command("mmc key", 0); - } - MsgP("mmc erase 1 \n"); - ret = run_command("mmc erase 1", 0); - } - return 0; - } - else if((ret == NAND_INIT_FAILED)&&(init_flag == STORE_BOOT_ERASE_ALL)){ - sprintf(str, "amlnf init %d ",4); - ret = run_command(str, 0); - } - device_boot_flag = SPI_NAND_FLAG; - return 0; - } - */ - if (device_boot_flag == SPI_NAND_FLAG) { - store_dbg("spi+nand , %s %d ",__func__,__LINE__); + case EMMC_BOOT_FLAG: + { + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + device_boot_flag = EMMC_BOOT_FLAG; + sprintf(str, "mmc dev %d", CONFIG_SYS_MMC_ENV_DEV); + run_command(str,0); + ret = run_command("mmcinfo", 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache + ret = run_command("amlmmc erase non_cache", 0); + }else if(init_flag >= STORE_BOOT_ERASE_ALL){ // erase all except reserved area + if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { + MsgP("amlmmc key\n"); + run_command("amlmmc key", 0); + } + sprintf(str, "amlmmc erase %d", CONFIG_SYS_MMC_ENV_DEV); + MsgP("amlmmc erase %d", CONFIG_SYS_MMC_ENV_DEV); + ret = run_command(str, 0); + } + + return ret; + } + break; + case SPI_EMMC_FLAG: + case SPI_NAND_FLAG: + { + /* + if (device_boot_flag == -1) + { + ret = run_command("sf probe 2", 0); + if (ret) { + store_msg(" cmd %s failed \n",cmd); + return -1; + } + if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { + sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); + ret = run_command(str,0); + } + sprintf(str, "amlnf init %d ",init_flag); + store_dbg("command: %s", str); + ret = run_command(str, 0); + if (ret < 0) //fail to init NAND flash + { + store_msg("nand cmd %s failed \n",cmd); + device_boot_flag = SPI_EMMC_FLAG; + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + ret = run_command("mmcinfo 1", 0); + if (ret != 0) { + store_msg("mmc cmd %s failed \n",cmd); + return -2; + } + if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache + store_msg("mmc erase non_cache \n"); + ret = run_command("mmc erase non_cache", 0); + }else if(init_flag >= STORE_BOOT_ERASE_ALL){ // erase all except reserved area + if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { + MsgP("mmc key;\n"); + run_command("mmc key", 0); + } + MsgP("mmc erase 1 \n"); + ret = run_command("mmc erase 1", 0); + } + return 0; + } + else if((ret == NAND_INIT_FAILED)&&(init_flag == STORE_BOOT_ERASE_ALL)){ + sprintf(str, "amlnf init %d ",4); + ret = run_command(str, 0); + } + device_boot_flag = SPI_NAND_FLAG; + return 0; + } + */ + if (device_boot_flag == SPI_NAND_FLAG) { + store_dbg("spi+nand , %s %d ",__func__,__LINE__); #if defined(CONFIG_AML_NAND) - if ((init_flag >=STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <=STORE_BOOT_SCRUB_ALL)) { - sprintf(str, "amlnf init %d ",init_flag); - run_command(str, 0); - } - sprintf(str, "amlnf init %d ",1); - store_dbg("command: %s", str); - ret = run_command(str, 0); + if ((init_flag >=STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <=STORE_BOOT_SCRUB_ALL)) { + sprintf(str, "amlnf init %d ",init_flag); + run_command(str, 0); + } + sprintf(str, "amlnf init %d ",1); + store_dbg("command: %s", str); + ret = run_command(str, 0); #else - ret = NAND_INIT_FAILED; + ret = NAND_INIT_FAILED; #endif #if 0 - if ((ret == NAND_INIT_FAILED) && (init_flag == STORE_BOOT_ERASE_ALL)) { - sprintf(str, "amlnf init %d ",4); - ret = run_command(str, 0); - } + if ((ret == NAND_INIT_FAILED) && (init_flag == STORE_BOOT_ERASE_ALL)) { + sprintf(str, "amlnf init %d ",4); + ret = run_command(str, 0); + } #else - if (ret == NAND_INIT_FAILED) { - return -1; - } + if (ret == NAND_INIT_FAILED) { + return -1; + } #endif - if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { - ret = run_command("sf probe 2", 0); - sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); - ret = run_command(str,0); - } - } - if (device_boot_flag == SPI_EMMC_FLAG) { - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - ret = run_command("mmcinfo 1", 0); - - if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache - store_msg("amlmmc erase non_cache \n"); - ret = run_command("amlmmc erase non_cache", 0); - }else if(init_flag == STORE_BOOT_ERASE_ALL){ // erase all except reserved area - if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { - run_command("mmc key", 0); - } - MsgP("amlmmc erase 1 \n"); - ret = run_command("amlmmc erase 1", 0); - } - if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { - ret = run_command("sf probe 2", 0); - sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); - ret = run_command(str,0); - } - } - - if (ret != 0) { - store_msg("cmd %s failed \n",cmd); - return -1; - } - - return ret; - } - default: - store_dbg("CARD BOOT, %s %d",__func__,__LINE__); - return CMD_RET_FAILURE; - } - - return 0; + if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { + ret = run_command("sf probe 2", 0); + sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); + ret = run_command(str,0); + } + } + if (device_boot_flag == SPI_EMMC_FLAG) { + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + ret = run_command("mmcinfo 1", 0); + + if (init_flag == STORE_BOOT_ERASE_PROTECT_CACHE) { // OTA upgrade protect cache + store_msg("amlmmc erase non_cache \n"); + ret = run_command("amlmmc erase non_cache", 0); + }else if(init_flag == STORE_BOOT_ERASE_ALL){ // erase all except reserved area + if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { + run_command("mmc key", 0); + } + MsgP("amlmmc erase 1 \n"); + ret = run_command("amlmmc erase 1", 0); + } + if ((init_flag > STORE_BOOT_ERASE_PROTECT_CACHE) && (init_flag <= STORE_BOOT_SCRUB_ALL)) { + ret = run_command("sf probe 2", 0); + sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); + ret = run_command(str,0); + } + } + + if (ret != 0) { + store_msg("cmd %s failed \n",cmd); + return -1; + } + + return ret; + } + default: + store_dbg("CARD BOOT, %s %d",__func__,__LINE__); + return CMD_RET_FAILURE; + } + + return 0; } static int do_store_exit(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_AML_NAND) - if (device_boot_flag == NAND_BOOT_FLAG) { - int ret = run_command("amlnf exit", 0); - if (ret != 0) { - MsgP("amlnf exit failed"); - return -1; - } - } + if (device_boot_flag == NAND_BOOT_FLAG) { + int ret = run_command("amlnf exit", 0); + if (ret != 0) { + MsgP("amlnf exit failed"); + return -1; + } + } #endif - return 0; + return 0; } static int do_store_disprotect(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - char *area; - - area = argv[2]; - if (strcmp(area, "key") == 0) { - MsgP("disprotect key\n"); - info_disprotect |= DISPROTECT_KEY; - _info_disprotect_back_before_mmcinfo1 |= DISPROTECT_KEY; - } - if (strcmp(area, "fbbt") == 0) { - store_msg("disprotect fbbt"); - info_disprotect |= DISPROTECT_FBBT; - } - if (strcmp(area, "hynix") == 0) { - store_msg("disprotect hynix"); - info_disprotect |= DISPROTECT_HYNIX; - } - - return 0; + char *area; + + area = argv[2]; + if (strcmp(area, "key") == 0) { + MsgP("disprotect key\n"); + info_disprotect |= DISPROTECT_KEY; + _info_disprotect_back_before_mmcinfo1 |= DISPROTECT_KEY; + } + if (strcmp(area, "fbbt") == 0) { + store_msg("disprotect fbbt"); + info_disprotect |= DISPROTECT_FBBT; + } + if (strcmp(area, "hynix") == 0) { + store_msg("disprotect hynix"); + info_disprotect |= DISPROTECT_HYNIX; + } + + return 0; } static int do_store_size(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - uint64_t addr; - char *cmd = NULL, *s = NULL; - char str[128]; + int ret = 0; + uint64_t addr; + char *cmd = NULL, *s = NULL; + char str[128]; - if (argc < 4) return CMD_RET_USAGE; + if (argc < 4) return CMD_RET_USAGE; - s = argv[2]; - addr = (ulong)simple_strtoul(argv[3], NULL, 16); - if ( !addr ) { - ErrP("addr(%s) is invalid\n", argv[3]); - return CMD_RET_FAILURE; - } + s = argv[2]; + addr = (ulong)simple_strtoul(argv[3], NULL, 16); + if ( !addr ) { + ErrP("addr(%s) is invalid\n", argv[3]); + return CMD_RET_FAILURE; + } - if (device_boot_flag == NAND_BOOT_FLAG) { + if (device_boot_flag == NAND_BOOT_FLAG) { #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf size %s %llx",s,addr); - store_dbg("command: %s", str); - ret = run_command(str, 0); + sprintf(str, "amlnf size %s %llx",s,addr); + store_dbg("command: %s", str); + ret = run_command(str, 0); #elif defined(CONFIG_AML_MTD) - {//get mtd part logic size (i.e, not including the bad blocks) - nand_info_t * mtdPartInf = NULL; - loff_t off = 0; - uint64_t partSzLgc = 0; - const char* partName = s; - - mtdPartInf = get_mtd_device_nm(partName); - if (IS_ERR(mtdPartInf)) { - ErrP("device(%s) is err\n", partName); - return CMD_RET_FAILURE; - } - const unsigned eraseSz = mtdPartInf->erasesize; - const uint64_t partSzPhy = mtdPartInf->size; - - partSzLgc = partSzPhy; - for (; off < partSzPhy; off += eraseSz) { - if (nand_block_isbad(mtdPartInf, off)) { - partSzLgc -= eraseSz; - } - } - uint64_t* pAddr = (uint64_t*)addr; - *pAddr = partSzLgc; - } + {//get mtd part logic size (i.e, not including the bad blocks) + nand_info_t * mtdPartInf = NULL; + loff_t off = 0; + uint64_t partSzLgc = 0; + const char* partName = s; + + mtdPartInf = get_mtd_device_nm(partName); + if (IS_ERR(mtdPartInf)) { + ErrP("device(%s) is err\n", partName); + return CMD_RET_FAILURE; + } + const unsigned eraseSz = mtdPartInf->erasesize; + const uint64_t partSzPhy = mtdPartInf->size; + + partSzLgc = partSzPhy; + for (; off < partSzPhy; off += eraseSz) { + if (nand_block_isbad(mtdPartInf, off)) { + partSzLgc -= eraseSz; + } + } + uint64_t* pAddr = (uint64_t*)addr; + *pAddr = partSzLgc; + } #else - ret = -1; + ret = -1; #endif// #if defined(CONFIG_AML_NAND) - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_NAND_FLAG){ - #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf size %s %llx",s,addr); - store_dbg("command: %s", str); - ret = run_command(str, 0); - #else - ret = -1; - #endif - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_EMMC_FLAG){ - store_dbg("MMC , %s %d ",__func__,__LINE__); - sprintf(str, "amlmmc size %s %llx",s,addr); - store_dbg("command: %s", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG){ - store_dbg("MMC , %s %d ",__func__,__LINE__); - sprintf(str, "amlmmc size %s %llx",s,addr); - store_dbg("command: %s", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==CARD_BOOT_FLAG){ - store_dbg("CARD BOOT , %s %d ",__func__,__LINE__); - return CMD_RET_FAILURE; - } - - return CMD_RET_FAILURE; + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_NAND_FLAG){ + #if defined(CONFIG_AML_NAND) + sprintf(str, "amlnf size %s %llx",s,addr); + store_dbg("command: %s", str); + ret = run_command(str, 0); + #else + ret = -1; + #endif + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_EMMC_FLAG){ + store_dbg("MMC , %s %d ",__func__,__LINE__); + sprintf(str, "amlmmc size %s %llx",s,addr); + store_dbg("command: %s", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG){ + store_dbg("MMC , %s %d ",__func__,__LINE__); + sprintf(str, "amlmmc size %s %llx",s,addr); + store_dbg("command: %s", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==CARD_BOOT_FLAG){ + store_dbg("CARD BOOT , %s %d ",__func__,__LINE__); + return CMD_RET_FAILURE; + } + + return CMD_RET_FAILURE; } static int do_store_erase(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int i, ret = 0; - loff_t size=0; - char *cmd = NULL, *area; - char str[128]; - loff_t off; - - if (argc < 3) return CMD_RET_USAGE; - - off = off; - area = argv[2]; - cmd = argv[2]; - - if (strcmp(area, "boot") == 0) { - off = argc > 3 ? simple_strtoul(argv[3], NULL, 16) : 0; - size = argc > 4 ? simple_strtoul(argv[4], NULL, 16) : 0x60000; - if (device_boot_flag == NAND_BOOT_FLAG) { - #if defined(CONFIG_AML_NAND) - store_dbg("NAND BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); - - ret = run_command("amlnf deverase boot 0",0); - #elif defined(CONFIG_AML_MTD) - ret = run_command("amlnf rom_erase",0); - #else - ret = -1; - #endif - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - return ret; - }else if((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ - store_dbg("SPI BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); - - ret = run_command("sf probe 2",0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - sprintf(str, "sf erase 0 0x%x", CONFIG_ENV_IN_SPI_OFFSET);//store erase boot shoould NOT erase ENV in flash! - ret = run_command(str,0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - }else if(device_boot_flag == EMMC_BOOT_FLAG){ - store_dbg("MMC BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); - - sprintf(str, "amlmmc erase bootloader"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed",cmd); - return -1; - } + int i, ret = 0; + loff_t size=0; + char *cmd = NULL, *area; + char str[128]; + loff_t off; + + if (argc < 3) return CMD_RET_USAGE; + + off = off; + area = argv[2]; + cmd = argv[2]; + + if (strcmp(area, "boot") == 0) { + off = argc > 3 ? simple_strtoul(argv[3], NULL, 16) : 0; + size = argc > 4 ? simple_strtoul(argv[4], NULL, 16) : 0x60000; + if (device_boot_flag == NAND_BOOT_FLAG) { + #if defined(CONFIG_AML_NAND) + store_dbg("NAND BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); + + ret = run_command("amlnf deverase boot 0",0); + #elif defined(CONFIG_AML_MTD) + ret = run_command("amlnf rom_erase",0); + #else + ret = -1; + #endif + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + return ret; + }else if((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ + store_dbg("SPI BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); + + ret = run_command("sf probe 2",0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + sprintf(str, "sf erase 0 0x%x", CONFIG_ENV_IN_SPI_OFFSET);//store erase boot shoould NOT erase ENV in flash! + ret = run_command(str,0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + }else if(device_boot_flag == EMMC_BOOT_FLAG){ + store_dbg("MMC BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); + + sprintf(str, "amlmmc erase bootloader"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed",cmd); + return -1; + } #ifdef MMC_BOOT_PARTITION_SUPPORT - printf("%s() %d\n", __func__, __LINE__); - - for (i=0; i<2; i++) { - printf("%s() %d, i = %d\n", __func__, __LINE__, i); - //switch to boot partition here - sprintf(str, "amlmmc switch 1 boot%d", i); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret == -1) { - //store_msg("mmc cmd %s failed \n",cmd); - return 0; - } - else if(ret != 0){ - store_msg("amlmmc cmd %s failed",cmd); - //return -1; - goto E_SWITCH_BACK; - } - - //erase boot partition - sprintf(str, "amlmmc erase bootloader"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed",cmd); - //return -1; - goto E_SWITCH_BACK; - } - } + printf("%s() %d\n", __func__, __LINE__); + + for (i=0; i<2; i++) { + printf("%s() %d, i = %d\n", __func__, __LINE__, i); + //switch to boot partition here + sprintf(str, "amlmmc switch 1 boot%d", i); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret == -1) { + //store_msg("mmc cmd %s failed \n",cmd); + return 0; + } + else if(ret != 0){ + store_msg("amlmmc cmd %s failed",cmd); + //return -1; + goto E_SWITCH_BACK; + } + + //erase boot partition + sprintf(str, "amlmmc erase bootloader"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed",cmd); + //return -1; + goto E_SWITCH_BACK; + } + } E_SWITCH_BACK: - //switch back to urs partition - sprintf(str, "amlmmc switch 1 user"); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } + //switch back to urs partition + sprintf(str, "amlmmc switch 1 user"); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } #endif - return ret; - }else{ - store_dbg("CARD BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); - return 0; - } - } - else if (strcmp(area, "data") == 0){ - if (device_boot_flag == NAND_BOOT_FLAG) { - store_dbg("NAND BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); - #if defined(CONFIG_AML_NAND) - ret = run_command("amlnf deverase data 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - ret = run_command("amlnf deverase code 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - ret = run_command("amlnf deverase cache 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - #elif defined(CONFIG_AML_MTD) - ret = run_command("nand device 1", 0); - ret |= run_command("nand erase.chip", 0); - #endif - return ret; - } - else if(device_boot_flag == SPI_NAND_FLAG){ - store_dbg("spi+nand , %s %d ",__func__,__LINE__); - #if defined(CONFIG_AML_NAND) - ret = run_command("amlnf deverase data 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - - ret = run_command("amlnf deverase code 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - ret = run_command("amlnf deverase cache 0",0); - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - #endif - return ret; - } - else if(device_boot_flag == SPI_EMMC_FLAG){ - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - off = size =0; - ret = run_command("mmc erase 1",0); // whole - if (ret != 0) { - store_msg("mmc cmd %s failed ",cmd); - return -1; - } - - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG){ - store_dbg("MMC BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); - off = size =0; - ret = run_command("amlmmc erase 1",0); //whole - if (ret != 0) { - store_msg("amlmmc cmd %s failed ",cmd); - return -1; - } - return ret; - }else{ - store_dbg("CARD BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); - return 0; - } - } - else if (strcmp(area, "key") == 0){ - if (device_boot_flag == EMMC_BOOT_FLAG) { - sprintf(str, "emmc erase key"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("emmc cmd %s failed",cmd); - return CMD_RET_USAGE; - } - } else if (device_boot_flag == NAND_BOOT_FLAG) { - #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - sprintf(str, "amlnf key_erase"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("emmc cmd %s failed",cmd); - return CMD_RET_USAGE; - } - #endif - } - } - else if (strcmp(area, "dtb") == 0) { - if (device_boot_flag == EMMC_BOOT_FLAG) { - sprintf(str, "emmc erase dtb"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("emmc cmd %s failed",cmd); - return CMD_RET_USAGE; - } - } else if (device_boot_flag == NAND_BOOT_FLAG) { - #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - sprintf(str, "amlnf dtb_erase"); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("emmc cmd %s failed",cmd); - return CMD_RET_USAGE; - } - #endif - } + return ret; + }else{ + store_dbg("CARD BOOT,erase uboot : %s %d off =%llx ,size=%llx",__func__,__LINE__,off,size); + return 0; + } + } + else if (strcmp(area, "data") == 0){ + if (device_boot_flag == NAND_BOOT_FLAG) { + store_dbg("NAND BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); + #if defined(CONFIG_AML_NAND) + ret = run_command("amlnf deverase data 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + ret = run_command("amlnf deverase code 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + ret = run_command("amlnf deverase cache 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + #elif defined(CONFIG_AML_MTD) + ret = run_command("nand device 1", 0); + ret |= run_command("nand erase.chip", 0); + #endif + return ret; + } + else if(device_boot_flag == SPI_NAND_FLAG){ + store_dbg("spi+nand , %s %d ",__func__,__LINE__); + #if defined(CONFIG_AML_NAND) + ret = run_command("amlnf deverase data 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + + ret = run_command("amlnf deverase code 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + ret = run_command("amlnf deverase cache 0",0); + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + #endif + return ret; + } + else if(device_boot_flag == SPI_EMMC_FLAG){ + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + off = size =0; + ret = run_command("mmc erase 1",0); // whole + if (ret != 0) { + store_msg("mmc cmd %s failed ",cmd); + return -1; + } + + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG){ + store_dbg("MMC BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); + off = size =0; + ret = run_command("amlmmc erase 1",0); //whole + if (ret != 0) { + store_msg("amlmmc cmd %s failed ",cmd); + return -1; + } + return ret; + }else{ + store_dbg("CARD BOOT,erase data : %s %d off =%llx ,size=%llx",__func__,__LINE__, off, size); + return 0; + } + } + else if (strcmp(area, "key") == 0){ + if (device_boot_flag == EMMC_BOOT_FLAG) { + sprintf(str, "emmc erase key"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("emmc cmd %s failed",cmd); + return CMD_RET_USAGE; + } + } else if (device_boot_flag == NAND_BOOT_FLAG) { + #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) + sprintf(str, "amlnf key_erase"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("emmc cmd %s failed",cmd); + return CMD_RET_USAGE; + } + #endif + } + } + else if (strcmp(area, "dtb") == 0) { + if (device_boot_flag == EMMC_BOOT_FLAG) { + sprintf(str, "emmc erase dtb"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("emmc cmd %s failed",cmd); + return CMD_RET_USAGE; + } + } else if (device_boot_flag == NAND_BOOT_FLAG) { + #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) + sprintf(str, "amlnf dtb_erase"); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("emmc cmd %s failed",cmd); + return CMD_RET_USAGE; + } + #endif + } } else if (strcmp(area, "partition") == 0) { if (device_boot_flag == EMMC_BOOT_FLAG) { int blk_shift; @@ -1068,7 +1157,7 @@ E_SWITCH_BACK: } else if (NAND_BOOT_FLAG == device_boot_flag){ #ifdef CONFIG_AML_MTD - if ( 4 > argc ) return CMD_RET_USAGE; + if ( 4 > argc ) return CMD_RET_USAGE; sprintf(str, "nand erase.part %s", argv[3]); return run_command(str, 0); #else @@ -1079,774 +1168,727 @@ E_SWITCH_BACK: } else return CMD_RET_USAGE; - return 0; + return 0; } static int do_store_scrub(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - int ret = 0; - loff_t off=0; - char *cmd = NULL; - char str[128]; - - off = (ulong)simple_strtoul(argv[2], NULL, 16); - sprintf(str, "amlnf scrub %d", (int)off); - if (device_boot_flag == NAND_BOOT_FLAG) { - #if defined(CONFIG_AML_NAND) - ret = run_command(str, 0); - #elif defined(CONFIG_AML_MTD) - printf("%s() fixme, to do...\n", __func__); - #else - ret = -1; - #endif - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - } - else if(device_boot_flag == SPI_NAND_FLAG){ - store_dbg("spi+nand , %s %d ",__func__,__LINE__); - #if defined(CONFIG_AML_NAND) - ret = run_command(str, 0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - #endif - - ret = run_command("sf probe 2", 0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); - ret = run_command(str,0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_EMMC_FLAG){ - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - ret = run_command("amlmmc erase whole",0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG){ - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); - device_boot_flag = EMMC_BOOT_FLAG; - run_command("mmc dev 1", 0); - ret = run_command("mmcinfo", 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { - MsgP("mmc key\n"); - run_command("mmc key", 0); - } - MsgP("amlmmc erase 1"); - ret = run_command("amlmmc erase 1", 0); - } - - return ret; + int ret = 0; + loff_t off=0; + char *cmd = NULL; + char str[128]; + + off = (ulong)simple_strtoul(argv[2], NULL, 16); + sprintf(str, "amlnf scrub %d", (int)off); + if (device_boot_flag == NAND_BOOT_FLAG) { + #if defined(CONFIG_AML_NAND) + ret = run_command(str, 0); + #elif defined(CONFIG_AML_MTD) + printf("%s() fixme, to do...\n", __func__); + #else + ret = -1; + #endif + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + } + else if(device_boot_flag == SPI_NAND_FLAG){ + store_dbg("spi+nand , %s %d ",__func__,__LINE__); + #if defined(CONFIG_AML_NAND) + ret = run_command(str, 0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + #endif + + ret = run_command("sf probe 2", 0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + sprintf(str, "sf erase 0 0x%x", _SPI_FLASH_ERASE_SZ); + ret = run_command(str,0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_EMMC_FLAG){ + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + ret = run_command("amlmmc erase whole",0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG){ + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + device_boot_flag = EMMC_BOOT_FLAG; + run_command("mmc dev 1", 0); + ret = run_command("mmcinfo", 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + if (_info_disprotect_back_before_mmcinfo1 & DISPROTECT_KEY) { + MsgP("mmc key\n"); + run_command("mmc key", 0); + } + MsgP("amlmmc erase 1"); + ret = run_command("amlmmc erase 1", 0); + } + + return ret; } static int do_store_rom_protect(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { #if defined(CONFIG_AML_NAND) - char *cmd = NULL; - char str[128]; - char *area = argv[2]; + char *cmd = NULL; + char str[128]; + char *area = argv[2]; #endif - if (argc < 3)return CMD_RET_USAGE; + if (argc < 3)return CMD_RET_USAGE; - if (device_boot_flag == NAND_BOOT_FLAG) { + if (device_boot_flag == NAND_BOOT_FLAG) { #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf rom_protect %s", area); - store_dbg("command: %s", str); - int ret = run_command(str, 0); + sprintf(str, "amlnf rom_protect %s", area); + store_dbg("command: %s", str); + int ret = run_command(str, 0); if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } + store_msg("nand cmd %s failed",cmd); + return -1; + } #elif defined(CONFIG_AML_MTD) - printf("%s() fixme, to do...\n", __func__); + printf("%s() fixme, to do...\n", __func__); #else - return -1; + return -1; #endif - } + } - return CMD_RET_SUCCESS; + return CMD_RET_SUCCESS; } static int do_store_rom_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - uint64_t addr; - loff_t off=0, size=0; - char *cmd = NULL; - char str[128]; - int ret = 0; - int i = 0; - cpu_id_t cpu_id = get_cpu_id(); - - if (argc < 5) return CMD_RET_USAGE; + uint64_t addr; + loff_t off=0, size=0; + char *cmd = NULL; + char str[128]; + int ret = 0; + if (argc < 5) return CMD_RET_USAGE; - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - if (get_off_size(argc - 3, (char **)(argv + 3), &off, &size) != 0) return CMD_RET_FAILURE; + addr = (ulong)simple_strtoul(argv[2], NULL, 16); + if (get_off_size(argc - 3, (char **)(argv + 3), &off, &size) != 0) return CMD_RET_FAILURE; - if (device_boot_flag == NAND_BOOT_FLAG) { + if (device_boot_flag == NAND_BOOT_FLAG) { #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) #ifndef CONFIG_DISCRETE_BOOTLOADER - sprintf(str, "amlnf rom_write 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s", str); - ret = run_command(str, 0); + sprintf(str, "amlnf rom_write 0x%llx 0x%llx 0x%llx", addr, off, size); + store_dbg("command: %s", str); + ret = run_command(str, 0); #else /* *store rom_write addr offset size <iCopy> //Used to update the whole bootloader, i.e, update 'bl2 + tpl' at the same time @iCopy is optional, - if used, must < min(tplCpyNum, Bl2CpyNum), and update only the specified copy - if not used, update all the copies of bl2 and tpl + if used, must < min(tplCpyNum, Bl2CpyNum), and update only the specified copy + if not used, update all the copies of bl2 and tpl */ - const int Bl2Size = BL2_SIZE; - const int Bl2CpyNum = CONFIG_BL2_COPY_NUM; //TODO: decided by efuse, no macro - const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; - const int tplCpyNum = CONFIG_TPL_COPY_NUM; - const int bootloaderMaxSz = Bl2Size + tplCapSize; - const int tplWriteSz = size - Bl2Size; - loff_t copyOff = 0; - const int iCopy2Update = argc > 5 ? simple_strtoul(argv[5], NULL, 0) : -1; - const int TPL_MIN_SZ = (1U << 16); - const int updateTpl = TPL_MIN_SZ < tplWriteSz; - - if ( bootloaderMaxSz < size ) { - ErrP("bootloader sz 0x%llx too large,max sz 0x%x\n", size, bootloaderMaxSz ); - return CMD_RET_FAILURE; - } - if ( !updateTpl ) { - MsgP("Warnning:tplWriteSz 0x%x too small, update bl2 only but not update tpl\n", tplWriteSz); - } - if (iCopy2Update >= tplCpyNum || iCopy2Update >= Bl2CpyNum) { - ErrP("iCopy2Update[%s] invalid, must < min(%d, %d)\n", argv[5], tplCpyNum, Bl2CpyNum); - return CMD_RET_FAILURE; - } - for (i = 0; i < Bl2CpyNum; ++i) - { - if (iCopy2Update >= 0 && iCopy2Update != i) continue; - - sprintf(str, "amlnf rom_erase %d", i); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at erase bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - - //copyOff = i * Bl2Size; - sprintf(str, "amlnf bl2_write 0x%llx %d 0x%x", addr, i, Bl2Size); - debugP("runCmd[%s]\n", str); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - } - addr += Bl2Size; - for ( i = 0; i < tplCpyNum && updateTpl; ++i ) - { - if (iCopy2Update >= 0 && iCopy2Update != i) continue; - - sprintf(str, "amlnf fip_erase %d", i); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at erase tpl[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - - copyOff = i * tplCapSize; - sprintf(str, "amlnf fip_write 0x%llx %llx 0x%x", addr, copyOff, tplWriteSz); - debugP("runCmd[%s]\n", str); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - } + const int Bl2Size = BL2_SIZE; + const int Bl2CpyNum = CONFIG_BL2_COPY_NUM; //TODO: decided by efuse, no macro + const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; + const int tplCpyNum = CONFIG_TPL_COPY_NUM; + const int bootloaderMaxSz = Bl2Size + tplCapSize; + const int tplWriteSz = size - Bl2Size; + loff_t copyOff = 0; + const int iCopy2Update = argc > 5 ? simple_strtoul(argv[5], NULL, 0) : -1; + const int TPL_MIN_SZ = (1U << 16); + const int updateTpl = TPL_MIN_SZ < tplWriteSz; + int i = 0; + + if ( bootloaderMaxSz < size ) { + ErrP("bootloader sz 0x%llx too large,max sz 0x%x\n", size, bootloaderMaxSz ); + return CMD_RET_FAILURE; + } + if ( !updateTpl ) { + MsgP("Warnning:tplWriteSz 0x%x too small, update bl2 only but not update tpl\n", tplWriteSz); + } + if (iCopy2Update >= tplCpyNum || iCopy2Update >= Bl2CpyNum) { + ErrP("iCopy2Update[%s] invalid, must < min(%d, %d)\n", argv[5], tplCpyNum, Bl2CpyNum); + return CMD_RET_FAILURE; + } + for (i = 0; i < Bl2CpyNum; ++i) + { + if (iCopy2Update >= 0 && iCopy2Update != i) continue; + + sprintf(str, "amlnf rom_erase %d", i); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at erase bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + + //copyOff = i * Bl2Size; + sprintf(str, "amlnf bl2_write 0x%llx %d 0x%x", addr, i, Bl2Size); + debugP("runCmd[%s]\n", str); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + } + addr += Bl2Size; + for ( i = 0; i < tplCpyNum && updateTpl; ++i ) + { + if (iCopy2Update >= 0 && iCopy2Update != i) continue; + + sprintf(str, "amlnf fip_erase %d", i); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at erase tpl[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + + copyOff = i * tplCapSize; + sprintf(str, "amlnf fip_write 0x%llx %llx 0x%x", addr, copyOff, tplWriteSz); + debugP("runCmd[%s]\n", str); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + } #if CONFIG_TPL_VAL_NUM_MIN - _bootloaderOrgCrc[0] = crc32(0, (unsigned char*)(addr - Bl2Size), Bl2Size); - _bootloaderOrgCrc[1] = crc32(0, (unsigned char*)addr, tplWriteSz); + _bootloaderOrgCrc[0] = crc32(0, (unsigned char*)(addr - Bl2Size), Bl2Size); + _bootloaderOrgCrc[1] = crc32(0, (unsigned char*)addr, tplWriteSz); #endif// #if CONFIG_TPL_VAL_NUM_MIN #endif//#ifndef CONFIG_DISCRETE_BOOTLOADER #else - ret = -1; + ret = -1; #endif - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - } - else if ((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ - ret = run_command("sf probe 2",0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - sprintf(str, "sf erase 0x%llx 0x%llx ", off, size); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - sprintf(str, "sf write 0x%llx 0x%llx 0x%llx ",addr, off, size); - store_dbg("command: %s", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG){ - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + } + else if ((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ + ret = run_command("sf probe 2",0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + sprintf(str, "sf erase 0x%llx 0x%llx ", off, size); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + sprintf(str, "sf write 0x%llx 0x%llx 0x%llx ",addr, off, size); + store_dbg("command: %s", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG){ + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); #ifndef CONFIG_AML_SECU_BOOT_V2 #ifdef MMC_UBOOT_CLEAR_MBR - //modify the 55 AA info for emmc uboot - unsigned char *tmp_buf= (unsigned char *)addr; - _mbrFlag[0] = tmp_buf[510]; - _mbrFlag[1] = tmp_buf[511]; - tmp_buf[510]=0; - tmp_buf[511]=0; + //modify the 55 AA info for emmc uboot + unsigned char *tmp_buf= (unsigned char *)addr; + _mbrFlag[0] = tmp_buf[510]; + _mbrFlag[1] = tmp_buf[511]; + tmp_buf[510]=0; + tmp_buf[511]=0; #endif #endif// #if defined(CONFIG_AML_SECU_BOOT_V2) - if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) - off += 512; - sprintf(str, "amlmmc write bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } -#ifdef MMC_BOOT_PARTITION_SUPPORT - - for (i=0; i<2; i++) { - //switch to boot partition here - sprintf(str, "amlmmc switch 1 boot%d", i); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret == -1) { - //store_msg("mmc cmd %s failed \n",cmd); - ret = 0; - return ret; - } - else if(ret != 0){ - store_msg("amlmmc cmd %s failed",cmd); - //return -1; - goto W_SWITCH_BACK; - } - - //write uboot to boot partition - sprintf(str, "amlmmc write bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - //return -1; - goto W_SWITCH_BACK; - } - } - -W_SWITCH_BACK: - //switch back to urs partition - sprintf(str, "amlmmc switch 1 user"); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - -#endif - return ret; - } else { - store_dbg("CARD BOOT, %s %d",__func__,__LINE__); - return 0; - } + sprintf(str, "amlmmc write bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + } else { + store_dbg("CARD BOOT, %s %d",__func__,__LINE__); + return 0; + } } static int do_store_rom_read(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - uint64_t addr; - loff_t off=0, size=0; - char *cmd = NULL; - char str[128]; - int ret = 0; - int i = 0; - cpu_id_t cpu_id = get_cpu_id(); + uint64_t addr; + loff_t off=0, size=0; + char *cmd = NULL; + char str[128]; + int ret = 0; + int i = 0; + cpu_id_t cpu_id = get_cpu_id(); - if (argc < 5) return CMD_RET_USAGE; + if (argc < 5) return CMD_RET_USAGE; - addr = (ulong)simple_strtoul(argv[2], NULL, 16); - if (get_off_size(argc - 3, (char **)(argv + 3), &off, &size) != 0) return CMD_RET_FAILURE; + addr = (ulong)simple_strtoul(argv[2], NULL, 16); + if (get_off_size(argc - 3, (char **)(argv + 3), &off, &size) != 0) return CMD_RET_FAILURE; - if (device_boot_flag == NAND_BOOT_FLAG) { + if (device_boot_flag == NAND_BOOT_FLAG) { #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) #ifndef CONFIG_DISCRETE_BOOTLOADER - sprintf(str, "amlnf rom_read 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s", str); - ret = run_command(str, 0); + sprintf(str, "amlnf rom_read 0x%llx 0x%llx 0x%llx", addr, off, size); + store_dbg("command: %s", str); + ret = run_command(str, 0); #else /* *store rom_read addr offset size <iCopy> //Used to read the whole bootloader, i.e, update 'bl2 + tpl' at the same time @iCopy is optional, - if used, must < min(tplCpyNum, Bl2CpyNum), and read only the specified copy - if not used, check if all the copies of 'bl2 + tpl' are same content + if used, must < min(tplCpyNum, Bl2CpyNum), and read only the specified copy + if not used, check if all the copies of 'bl2 + tpl' are same content */ - const int Bl2Size = BL2_SIZE; - const int Bl2CpyNum = CONFIG_BL2_COPY_NUM; //TODO: decided by efuse, no macro - const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; - const int tplCpyNum = CONFIG_TPL_COPY_NUM; - const int bootloaderMaxSz = Bl2Size + tplCapSize; - const int tplRealSz = size - Bl2Size; - loff_t copyOff = 0; - int iCopy2Update = argc > 5 ? simple_strtoul(argv[5], NULL, 0) : -1; - char* tmpBuf = NULL; - int okCrcNum = 0; - const int verifyMode = (off == (1ULL << 62) - 1) && (iCopy2Update < 0); //verify mode - if (!verifyMode && iCopy2Update < 0) iCopy2Update = 0; //default read copy 0 if no verify mode - - if ( bootloaderMaxSz < size || tplRealSz < 0 ) { - ErrP("bootloader sz 0x%llx invalid, max sz %d\n", size, bootloaderMaxSz ); - return CMD_RET_FAILURE; - } - if (iCopy2Update >= tplCpyNum || iCopy2Update >= Bl2CpyNum) { - ErrP("iCopy2Update[%s] invalid, must < min(%d, %d)\n", argv[5], tplCpyNum, Bl2CpyNum); - return CMD_RET_FAILURE; - } - - tmpBuf = (char*)malloc(size); - if ( !tmpBuf ) { - ErrP("Failed maloc 0x%llx bytes\n", size); - return CMD_RET_FAILURE; - } - memset(tmpBuf, 0, size); - - char* readBuf = tmpBuf; - const uint32_t orgBl2Crc = _bootloaderOrgCrc[0]; - for (i = 0; i < Bl2CpyNum; ++i) - { - if (iCopy2Update >= 0 && iCopy2Update != i) continue; - - sprintf(str, "amlnf bl2_read 0x%p %x 0x%x", readBuf, i, Bl2Size); - debugP("runCmd[%s]\n", str); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } + const int Bl2Size = BL2_SIZE; + const int Bl2CpyNum = CONFIG_BL2_COPY_NUM; //TODO: decided by efuse, no macro + const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; + const int tplCpyNum = CONFIG_TPL_COPY_NUM; + const int bootloaderMaxSz = Bl2Size + tplCapSize; + const int tplRealSz = size - Bl2Size; + loff_t copyOff = 0; + int iCopy2Update = argc > 5 ? simple_strtoul(argv[5], NULL, 0) : -1; + char* tmpBuf = NULL; + int okCrcNum = 0; + const int verifyMode = (off == (1ULL << 62) - 1) && (iCopy2Update < 0); //verify mode + if (!verifyMode && iCopy2Update < 0) iCopy2Update = 0; //default read copy 0 if no verify mode + + if ( bootloaderMaxSz < size || tplRealSz < 0 ) { + ErrP("bootloader sz 0x%llx invalid, max sz %d\n", size, bootloaderMaxSz ); + return CMD_RET_FAILURE; + } + if (iCopy2Update >= tplCpyNum || iCopy2Update >= Bl2CpyNum) { + ErrP("iCopy2Update[%s] invalid, must < min(%d, %d)\n", argv[5], tplCpyNum, Bl2CpyNum); + return CMD_RET_FAILURE; + } + + tmpBuf = (char*)malloc(size); + if ( !tmpBuf ) { + ErrP("Failed maloc 0x%llx bytes\n", size); + return CMD_RET_FAILURE; + } + memset(tmpBuf, 0, size); + + char* readBuf = tmpBuf; + const uint32_t orgBl2Crc = _bootloaderOrgCrc[0]; + for (i = 0; i < Bl2CpyNum; ++i) + { + if (iCopy2Update >= 0 && iCopy2Update != i) continue; + + sprintf(str, "amlnf bl2_read 0x%p %x 0x%x", readBuf, i, Bl2Size); + debugP("runCmd[%s]\n", str); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } #if CONFIG_BL2_VAL_NUM_MIN - if (verifyMode) //copy index not specified, need read all copies - { - const uint32_t readCrc = crc32(0, (unsigned char*)readBuf, Bl2Size); - if (readCrc == orgBl2Crc) { - okCrcNum += 1; - if ( okCrcNum >= CONFIG_BL2_VAL_NUM_MIN ) { - break; - } - } - } + if (verifyMode) //copy index not specified, need read all copies + { + const uint32_t readCrc = crc32(0, (unsigned char*)readBuf, Bl2Size); + if (readCrc == orgBl2Crc) { + okCrcNum += 1; + if ( okCrcNum >= CONFIG_BL2_VAL_NUM_MIN ) { + break; + } + } + } #endif//#if CONFIG_BL2_VAL_NUM_MIN - } + } #if CONFIG_BL2_VAL_NUM_MIN - if (okCrcNum < CONFIG_BL2_VAL_NUM_MIN && verifyMode) { - ErrP("okCrcNum(%d) < CONFIG_BL2_VAL_NUM_MIN(%d)\n", okCrcNum, CONFIG_BL2_VAL_NUM_MIN); - return CMD_RET_FAILURE; - } - okCrcNum = 0; + if (okCrcNum < CONFIG_BL2_VAL_NUM_MIN && verifyMode) { + ErrP("okCrcNum(%d) < CONFIG_BL2_VAL_NUM_MIN(%d)\n", okCrcNum, CONFIG_BL2_VAL_NUM_MIN); + return CMD_RET_FAILURE; + } + okCrcNum = 0; #endif//#if CONFIG_BL2_VAL_NUM_MIN - memcpy((char*)addr, readBuf, Bl2Size); - - if (tplRealSz > 0) // to support dump only bl2 - { - const uint32_t orgTplCrc = _bootloaderOrgCrc[1]; - for ( i = 0; i < tplCpyNum && !ret; ++i ) - { - if (iCopy2Update >= 0 && iCopy2Update != i) continue; - - copyOff = i * tplCapSize; - sprintf(str, "amlnf fip_read 0x%p %llx 0x%x", readBuf, copyOff, tplRealSz); - debugP("runCmd[%s]\n", str); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } + memcpy((char*)addr, readBuf, Bl2Size); + + if (tplRealSz > 0) // to support dump only bl2 + { + const uint32_t orgTplCrc = _bootloaderOrgCrc[1]; + for ( i = 0; i < tplCpyNum && !ret; ++i ) + { + if (iCopy2Update >= 0 && iCopy2Update != i) continue; + + copyOff = i * tplCapSize; + sprintf(str, "amlnf fip_read 0x%p %llx 0x%x", readBuf, copyOff, tplRealSz); + debugP("runCmd[%s]\n", str); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } #if CONFIG_TPL_VAL_NUM_MIN - if (verifyMode) //copy index not specified, need read all copies - { - const uint32_t readCrc = crc32(0, (unsigned char*)readBuf, tplRealSz); - if (orgTplCrc == readCrc) { - okCrcNum += 1; - if ( okCrcNum >= CONFIG_TPL_VAL_NUM_MIN ) { - break; - } - } - } + if (verifyMode) //copy index not specified, need read all copies + { + const uint32_t readCrc = crc32(0, (unsigned char*)readBuf, tplRealSz); + if (orgTplCrc == readCrc) { + okCrcNum += 1; + if ( okCrcNum >= CONFIG_TPL_VAL_NUM_MIN ) { + break; + } + } + } #endif//#if CONFIG_TPL_VAL_NUM_MIN - } + } #if CONFIG_TPL_VAL_NUM_MIN - if (okCrcNum < CONFIG_TPL_VAL_NUM_MIN && verifyMode) { - ErrP("okCrcNum(%d) < CONFIG_TPL_VAL_NUM_MIN(%d)\n", okCrcNum, CONFIG_TPL_VAL_NUM_MIN); - return CMD_RET_FAILURE; - } + if (okCrcNum < CONFIG_TPL_VAL_NUM_MIN && verifyMode) { + ErrP("okCrcNum(%d) < CONFIG_TPL_VAL_NUM_MIN(%d)\n", okCrcNum, CONFIG_TPL_VAL_NUM_MIN); + return CMD_RET_FAILURE; + } #endif//#if CONFIG_TPL_VAL_NUM_MIN - memcpy((char*)addr + Bl2Size, (unsigned char*)readBuf, tplRealSz); - } - free(tmpBuf); + memcpy((char*)addr + Bl2Size, (unsigned char*)readBuf, tplRealSz); + } + free(tmpBuf); #endif// #ifndef CONFIG_DISCRETE_BOOTLOADER #else - ret = -1; + ret = -1; #endif// #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - }else if ((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ - ret = run_command("sf probe 2",0); - if (ret != 0) { - return -1; - } - sprintf(str, "sf read 0x%llx 0x%llx 0x%llx ",addr, off, size); - store_dbg("command: %s", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("nand cmd %s failed",cmd); - return -1; - } - return ret; - }else if (device_boot_flag==EMMC_BOOT_FLAG){ - if ( cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) - off += 512; - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); - sprintf(str, "amlmmc read bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s\n", str); - //tmp_buf= (unsigned char *)addr; - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + }else if ((device_boot_flag==SPI_EMMC_FLAG)||(device_boot_flag==SPI_NAND_FLAG)){ + ret = run_command("sf probe 2",0); + if (ret != 0) { + return -1; + } + sprintf(str, "sf read 0x%llx 0x%llx 0x%llx ",addr, off, size); + store_dbg("command: %s", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("nand cmd %s failed",cmd); + return -1; + } + return ret; + }else if (device_boot_flag==EMMC_BOOT_FLAG){ + if ( cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) + off += 512; + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + sprintf(str, "amlmmc read bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); + store_dbg("command: %s\n", str); + //tmp_buf= (unsigned char *)addr; + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } #ifdef MMC_BOOT_PARTITION_SUPPORT - for (i=0; i<2; i++) { - //switch to boot partition here - sprintf(str, "amlmmc switch 1 boot%d", i); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret == -1) { - //store_msg("mmc cmd %s failed \n",cmd); - return 0; - } - else if(ret != 0){ - store_msg("amlmmc cmd %s failed",cmd); - goto R_SWITCH_BACK; - //return -1; - } - - //write uboot to boot partition - sprintf(str, "amlmmc read bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - //return -1; - goto R_SWITCH_BACK; - } - } + for (i=0; i<2; i++) { + //switch to boot partition here + sprintf(str, "amlmmc switch 1 boot%d", i); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret == -1) { + //store_msg("mmc cmd %s failed \n",cmd); + return 0; + } + else if(ret != 0){ + store_msg("amlmmc cmd %s failed",cmd); + goto R_SWITCH_BACK; + //return -1; + } + + //write uboot to boot partition + sprintf(str, "amlmmc read bootloader 0x%llx 0x%llx 0x%llx", addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + //return -1; + goto R_SWITCH_BACK; + } + } R_SWITCH_BACK: - //switch back to urs partition - sprintf(str, "amlmmc switch 1 user"); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } + //switch back to urs partition + sprintf(str, "amlmmc switch 1 user"); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } #endif #ifndef CONFIG_AML_SECU_BOOT_V2 #ifdef MMC_UBOOT_CLEAR_MBR - unsigned char *tmp_buf= (unsigned char *)addr; - tmp_buf[510]= _mbrFlag[0]; - tmp_buf[511]= _mbrFlag[1]; + unsigned char *tmp_buf= (unsigned char *)addr; + tmp_buf[510]= _mbrFlag[0]; + tmp_buf[511]= _mbrFlag[1]; #endif #endif// #ifndef CONFIG_AML_SECU_BOOT_V2 - return ret; - }else{ - store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); - return 0; - } + return ret; + }else{ + store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); + return 0; + } } static int do_store_read(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - uint64_t addr; - loff_t off=0, size=0; - char *cmd = NULL; - char str[128]; - int ret = 0; - char * s = argv[2]; + uint64_t addr; + loff_t off=0, size=0; + char *cmd = NULL; + char str[128]; + int ret = 0; + char * s = argv[2]; - if (argc < 6) return CMD_RET_USAGE; + if (argc < 6) return CMD_RET_USAGE; - addr = (ulong)simple_strtoul(argv[3], NULL, 16); + addr = (ulong)simple_strtoul(argv[3], NULL, 16); - if (get_off_size(argc - 4, (char **)(argv + 4), &off, &size) != 0) return CMD_RET_FAILURE; + if (get_off_size(argc - 4, (char **)(argv + 4), &off, &size) != 0) return CMD_RET_FAILURE; - store_dbg("addr = %llx off= 0x%llx size=0x%llx",addr,off,size); - if ((device_boot_flag == NAND_BOOT_FLAG)) { + store_dbg("addr = %llx off= 0x%llx size=0x%llx",addr,off,size); + if ((device_boot_flag == NAND_BOOT_FLAG)) { #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf read_byte %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); + sprintf(str, "amlnf read_byte %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); #elif defined(CONFIG_AML_MTD) - #if defined(CONFIG_DISCRETE_BOOTLOADER) - if ( !strcmp(CONFIG_TPL_PART_NAME, s) ) { - const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; - const int tplCpyNum = CONFIG_TPL_COPY_NUM; - const int iCopy2Update = argc > 6 ? simple_strtoul(argv[6], NULL, 0) : 0;//0 copy at default - - if (iCopy2Update >= tplCpyNum) { - ErrP("iCopy2Update[%s] invalid, must < max(%d)\n", argv[6], tplCpyNum); - return CMD_RET_FAILURE; - } - - loff_t copyOff = iCopy2Update * tplCapSize; - sprintf(str, "amlnf fip_read 0x%llx %llx 0x%llx", addr, copyOff, size); - } else - #endif // #if defined(CONFIG_DISCRETE_BOOTLOADER) - { - ret = mtd_find_phy_off_by_lgc_off(s, off, &off); - if (ret) { - ErrP("Fail in find phy addr by logic off (0x%llx),ret(%d)\n", off, ret); - return CMD_RET_FAILURE; - } - sprintf(str, "nand read %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); - } + #if defined(CONFIG_DISCRETE_BOOTLOADER) + if ( !strcmp(CONFIG_TPL_PART_NAME, s) ) { + const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; + const int tplCpyNum = CONFIG_TPL_COPY_NUM; + const int iCopy2Update = argc > 6 ? simple_strtoul(argv[6], NULL, 0) : 0;//0 copy at default + + if (iCopy2Update >= tplCpyNum) { + ErrP("iCopy2Update[%s] invalid, must < max(%d)\n", argv[6], tplCpyNum); + return CMD_RET_FAILURE; + } + + loff_t copyOff = iCopy2Update * tplCapSize; + sprintf(str, "amlnf fip_read 0x%llx %llx 0x%llx", addr, copyOff, size); + } else + #endif // #if defined(CONFIG_DISCRETE_BOOTLOADER) + { + ret = mtd_find_phy_off_by_lgc_off(s, off, &off); + if (ret) { + ErrP("Fail in find phy addr by logic off (0x%llx),ret(%d)\n", off, ret); + return CMD_RET_FAILURE; + } + sprintf(str, "nand read %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); + } #endif // #if defined(CONFIG_AML_NAND) #else - ret = -1; + ret = -1; #endif - ret = run_command(str, 0); - if (ret != 0) { - store_msg("nand cmd [%s] failed ",str); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_NAND_FLAG){ - #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf read_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - #else - ret = -1; - #endif - if (ret != 0) { - store_msg("nand cmd %s failed \n",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_EMMC_FLAG){ - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - sprintf(str, "amlmmc read %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG) { - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); - sprintf(str, "amlmmc read %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - return ret; - }else{ - store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); - - return 0; - } + ret = run_command(str, 0); + if (ret != 0) { + store_msg("nand cmd [%s] failed ",str); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_NAND_FLAG){ + #if defined(CONFIG_AML_NAND) + sprintf(str, "amlnf read_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + #else + ret = -1; + #endif + if (ret != 0) { + store_msg("nand cmd %s failed \n",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_EMMC_FLAG){ + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + sprintf(str, "amlmmc read %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG) { + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + sprintf(str, "amlmmc read %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + }else{ + store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); + + return 0; + } } static int do_store_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - uint64_t addr; - loff_t off=0, size=0; - char *cmd = NULL; - char str[128]; - int ret = 0; - char * s = argv[2]; + uint64_t addr; + loff_t off=0, size=0; + char *cmd = NULL; + char str[128]; + int ret = 0; + char * s = argv[2]; - if (argc < 6) return CMD_RET_USAGE; + if (argc < 6) return CMD_RET_USAGE; - addr = (ulong)simple_strtoul(argv[3], NULL, 16); - if (get_off_size(argc - 4, (char **)(argv + 4), &off, &size) != 0) return CMD_RET_FAILURE; + addr = (ulong)simple_strtoul(argv[3], NULL, 16); + if (get_off_size(argc - 4, (char **)(argv + 4), &off, &size) != 0) return CMD_RET_FAILURE; - if (device_boot_flag == NAND_BOOT_FLAG) { + if (device_boot_flag == NAND_BOOT_FLAG) { #if defined(CONFIG_AML_NAND) || defined(CONFIG_AML_MTD) - #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf write_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - ret = run_command(str, 0); - #elif defined(CONFIG_AML_MTD) - #if defined(CONFIG_DISCRETE_BOOTLOADER) - if ( !strcmp(CONFIG_TPL_PART_NAME, s) ) { - const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; - const int tplCpyNum = CONFIG_TPL_COPY_NUM; - const int iCopy2Update = argc > 6 ? simple_strtoul(argv[6], NULL, 0) : -1; //only update one copy - int i = 0; - - debugP("iCopy2Update=%d, tplCpyNum=%d\n", iCopy2Update, tplCpyNum); - if (iCopy2Update >= tplCpyNum) { - ErrP("iCopy2Update[%s] invalid, must < max(%d)\n", argv[6], tplCpyNum); - return CMD_RET_FAILURE; - } - - for ( i = 0; i < tplCpyNum; ++i ) - { - if (iCopy2Update >= 0 && iCopy2Update != i) continue; - - sprintf(str, "amlnf fip_erase %d", i); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at erase tpl[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - - loff_t copyOff = i * tplCapSize; - sprintf(str, "amlnf fip_write 0x%llx %llx 0x%llx", addr, copyOff, size); - debugP("runCmd[%s]\n", str); - ret = run_command(str, 0); - if (ret) { - ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); - return CMD_RET_FAILURE; - } - } - } else - #endif // #if defined(CONFIG_DISCRETE_BOOTLOADER) - { - ret = mtd_find_phy_off_by_lgc_off(s, off, &off); - if (ret) { - ErrP("Fail in find phy addr by logic off (0x%llx),ret(%d)\n", off, ret); - } - sprintf(str, "nand write %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); - ret = run_command(str, 0); - } + #if defined(CONFIG_AML_NAND) + sprintf(str, "amlnf write_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + ret = run_command(str, 0); + #elif defined(CONFIG_AML_MTD) + #if defined(CONFIG_DISCRETE_BOOTLOADER) + if ( !strcmp(CONFIG_TPL_PART_NAME, s) ) { + const int tplCapSize = CONFIG_TPL_SIZE_PER_COPY; + const int tplCpyNum = CONFIG_TPL_COPY_NUM; + const int iCopy2Update = argc > 6 ? simple_strtoul(argv[6], NULL, 0) : -1; //only update one copy + int i = 0; + + debugP("iCopy2Update=%d, tplCpyNum=%d\n", iCopy2Update, tplCpyNum); + if (iCopy2Update >= tplCpyNum) { + ErrP("iCopy2Update[%s] invalid, must < max(%d)\n", argv[6], tplCpyNum); + return CMD_RET_FAILURE; + } + + for ( i = 0; i < tplCpyNum; ++i ) + { + if (iCopy2Update >= 0 && iCopy2Update != i) continue; + + sprintf(str, "amlnf fip_erase %d", i); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at erase tpl[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + + loff_t copyOff = i * tplCapSize; + sprintf(str, "amlnf fip_write 0x%llx %llx 0x%llx", addr, copyOff, size); + debugP("runCmd[%s]\n", str); + ret = run_command(str, 0); + if (ret) { + ErrP("Failed at pgram bl2[%d],ret=%d\n", i, ret); + return CMD_RET_FAILURE; + } + } + } else + #endif // #if defined(CONFIG_DISCRETE_BOOTLOADER) + { + ret = mtd_find_phy_off_by_lgc_off(s, off, &off); + if (ret) { + ErrP("Fail in find phy addr by logic off (0x%llx),ret(%d)\n", off, ret); + } + sprintf(str, "nand write %s 0x%llx 0x%llx 0x%llx",s, addr, off, size); + ret = run_command(str, 0); + } #endif #else - ret = -1; + ret = -1; #endif - if (ret != 0) { - store_msg("nand cmd %s failed ",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_NAND_FLAG){ - store_dbg("spi+nand , %s %d ",__func__,__LINE__); - #if defined(CONFIG_AML_NAND) - sprintf(str, "amlnf write_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s", str); - ret = run_command(str, 0); - #else - ret = -1; - #endif - if (ret != 0) { - store_msg("nand cmd %s failed \n",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag == SPI_EMMC_FLAG){ - store_dbg("spi+mmc , %s %d ",__func__,__LINE__); - sprintf(str, "amlmmc write %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - return ret; - } - else if(device_boot_flag==EMMC_BOOT_FLAG){ - store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); - sprintf(str, "amlmmc write %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); - store_dbg("command: %s\n", str); - ret = run_command(str, 0); - if (ret != 0) { - store_msg("amlmmc cmd %s failed \n",cmd); - return -1; - } - return ret; - }else{ - store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); - return CMD_RET_FAILURE; - } - return ret; + if (ret != 0) { + store_msg("nand cmd %s failed ",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_NAND_FLAG){ + store_dbg("spi+nand , %s %d ",__func__,__LINE__); + #if defined(CONFIG_AML_NAND) + sprintf(str, "amlnf write_byte %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s", str); + ret = run_command(str, 0); + #else + ret = -1; + #endif + if (ret != 0) { + store_msg("nand cmd %s failed \n",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag == SPI_EMMC_FLAG){ + store_dbg("spi+mmc , %s %d ",__func__,__LINE__); + sprintf(str, "amlmmc write %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + } + else if(device_boot_flag==EMMC_BOOT_FLAG){ + store_dbg("MMC BOOT, %s %d \n",__func__,__LINE__); + sprintf(str, "amlmmc write %s 0x%llx 0x%llx 0x%llx", s, addr, off, size); + store_dbg("command: %s\n", str); + ret = run_command(str, 0); + if (ret != 0) { + store_msg("amlmmc cmd %s failed \n",cmd); + return -1; + } + return ret; + }else{ + store_dbg("CARD BOOT, %s %d ",__func__,__LINE__); + return CMD_RET_FAILURE; + } + return ret; } static cmd_tbl_t cmd_store_sub[] = { - U_BOOT_CMD_MKENT(init, 4, 0, do_store_init, "", ""), - U_BOOT_CMD_MKENT(exit, 3, 0, do_store_exit, "", ""), - U_BOOT_CMD_MKENT(disprotect, 3, 0, do_store_disprotect, "", ""), - U_BOOT_CMD_MKENT(rom_protect, 5, 0, do_store_rom_protect, "", ""), - U_BOOT_CMD_MKENT(size, 5, 0, do_store_size, "", ""), - U_BOOT_CMD_MKENT(scrub, 3, 0, do_store_scrub, "", ""), - U_BOOT_CMD_MKENT(erase, 5, 0, do_store_erase, "", ""), - U_BOOT_CMD_MKENT(read, 7, 0, do_store_read, "", ""), - U_BOOT_CMD_MKENT(write, 7, 0, do_store_write, "", ""), - U_BOOT_CMD_MKENT(rom_read, 5, 0, do_store_rom_read, "", ""), - U_BOOT_CMD_MKENT(rom_write, 5, 0, do_store_rom_write, "", ""), - U_BOOT_CMD_MKENT(dtb, 5, 0, do_store_dtb_ops, "", ""), - U_BOOT_CMD_MKENT(key, 5, 0, do_store_key_ops, "", ""), - U_BOOT_CMD_MKENT(mbr, 3, 0, do_store_mbr_ops, "", ""), + U_BOOT_CMD_MKENT(init, 4, 0, do_store_init, "", ""), + U_BOOT_CMD_MKENT(exit, 3, 0, do_store_exit, "", ""), + U_BOOT_CMD_MKENT(disprotect, 3, 0, do_store_disprotect, "", ""), + U_BOOT_CMD_MKENT(rom_protect, 5, 0, do_store_rom_protect, "", ""), + U_BOOT_CMD_MKENT(size, 5, 0, do_store_size, "", ""), + U_BOOT_CMD_MKENT(scrub, 3, 0, do_store_scrub, "", ""), + U_BOOT_CMD_MKENT(erase, 5, 0, do_store_erase, "", ""), + U_BOOT_CMD_MKENT(read, 7, 0, do_store_read, "", ""), + U_BOOT_CMD_MKENT(write, 7, 0, do_store_write, "", ""), + U_BOOT_CMD_MKENT(rom_read, 5, 0, do_store_rom_read, "", ""), + U_BOOT_CMD_MKENT(rom_write, 5, 0, do_store_rom_write, "", ""), + U_BOOT_CMD_MKENT(dtb, 5, 0, do_store_dtb_ops, "", ""), + U_BOOT_CMD_MKENT(key, 5, 0, do_store_key_ops, "", ""), + U_BOOT_CMD_MKENT(ddr_parameter, 5, 0, do_store_ddr_parameter_ops, "", ""), + U_BOOT_CMD_MKENT(mbr, 3, 0, do_store_mbr_ops, "", ""), }; static int do_store(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - cmd_tbl_t *c; + cmd_tbl_t *c; - if (argc < 2) return CMD_RET_USAGE; + if (argc < 2) return CMD_RET_USAGE; + c = find_cmd_tbl(argv[1], cmd_store_sub, ARRAY_SIZE(cmd_store_sub)); + if (c) + return c->cmd(cmdtp, flag, argc, argv); - c = find_cmd_tbl(argv[1], cmd_store_sub, ARRAY_SIZE(cmd_store_sub)); - - if (c) { - return c->cmd(cmdtp, flag, argc, argv); - } - - return CMD_RET_USAGE; + return CMD_RET_USAGE; } - U_BOOT_CMD(store, CONFIG_SYS_MAXARGS, 1, do_store, "STORE sub-system", "init flag\n" @@ -1872,6 +1914,8 @@ U_BOOT_CMD(store, CONFIG_SYS_MAXARGS, 1, do_store, " read/write dtb, size is optional \n" "store key read/write addr <size>\n" " read/write key, size is optional \n" + "store ddr_parameter read/write addr <size>\n" + " read/write ddr parameter, size is optional \n" "store mbr addr\n" " update mbr/partition table by dtb\n" ); diff --git a/drivers/mmc/aml_emmc_partition.c b/drivers/mmc/aml_emmc_partition.c index 29bb85ed40..bf95319bb1 100644 --- a/drivers/mmc/aml_emmc_partition.c +++ b/drivers/mmc/aml_emmc_partition.c @@ -115,22 +115,32 @@ struct partitions emmc_partition_table[] = { }; struct virtual_partition virtual_partition_table[] = { - /* partition for name idx, off & size will not be used! */ + /* partition for name idx, off & size will not be used! */ #if (CONFIG_PTBL_MBR) - VIRTUAL_PARTITION_ELEMENT(MMC_MBR_NAME, MMC_MBR_OFFSET, MMC_MBR_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_MBR_NAME, + MMC_MBR_OFFSET, MMC_MBR_SIZE), #endif - VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME0, 0, 0), - VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME1, 0, 0), - - /* virtual partition in reserved partition, take care off and size */ - VIRTUAL_PARTITION_ELEMENT(MMC_TABLE_NAME, MMC_TABLE_OFFSET, MMC_TABLE_SIZE), - VIRTUAL_PARTITION_ELEMENT(MMC_KEY_NAME, EMMCKEY_RESERVE_OFFSET, MMC_KEY_SIZE), - VIRTUAL_PARTITION_ELEMENT(MMC_PATTERN_NAME, CALI_PATTERN_OFFSET, CALI_PATTERN_SIZE), - VIRTUAL_PARTITION_ELEMENT(MMC_DTB_NAME, DTB_OFFSET, DTB_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME0, 0, 0), + VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME1, 0, 0), + + /* virtual partition in reserved partition, take care off and size */ + VIRTUAL_PARTITION_ELEMENT(MMC_TABLE_NAME, + MMC_TABLE_OFFSET, MMC_TABLE_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_KEY_NAME, + EMMCKEY_RESERVE_OFFSET, MMC_KEY_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_PATTERN_NAME, + CALI_PATTERN_OFFSET, CALI_PATTERN_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_DTB_NAME, + DTB_OFFSET, DTB_SIZE), VIRTUAL_PARTITION_ELEMENT(MMC_FASTBOOT_CONTEXT_NAME, - FASTBOOT_CONTEXT_OFFSET, FASTBOOT_CONTEXT_SIZE), - VIRTUAL_PARTITION_ELEMENT(MMC_MAGIC_NAME, MAGIC_OFFSET, MAGIC_SIZE), - VIRTUAL_PARTITION_ELEMENT(MMC_RANDOM_NAME, RANDOM_OFFSET, RANDOM_SIZE), + FASTBOOT_CONTEXT_OFFSET, + FASTBOOT_CONTEXT_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_MAGIC_NAME, + MAGIC_OFFSET, MAGIC_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_RANDOM_NAME, + RANDOM_OFFSET, RANDOM_SIZE), + VIRTUAL_PARTITION_ELEMENT(MMC_DDR_PARAMETER_NAME, + DDR_PARAMETER_OFFSET, DDR_PARAMETER_SIZE), }; int get_emmc_partition_arraysize(void) @@ -157,51 +167,43 @@ void __attribute__((unused)) _dump_part_tbl(struct partitions *p, int count) } static int _get_part_index_by_name(struct partitions *tbl, - int cnt, const char *name) + int cnt, const char *name) { - int i=0; - struct partitions *part = NULL; - - while (i < cnt) { - part = &tbl[i]; - if (!strcmp(name, part->name)) { - apt_info("find %s @ tbl[%d]\n", name, i); - break; - } - i++; - }; - if (i == cnt) { - i = -1; - apt_wrn("do not find match in table %s\n", name); - } - return i; -} + int i = 0; + struct partitions *part = NULL; + + while (i < cnt) { + part = &tbl[i]; + if (!strcmp(name, part->name)) { + apt_info("find %s @ tbl[%d]\n", name, i); + return i; + } + i++; + }; + return -1; +} static struct partitions *_find_partition_by_name(struct partitions *tbl, - int cnt, const char *name) + int cnt, const char *name) { int i = 0; struct partitions *part = NULL; while (i < cnt) { - part = &tbl[i]; if (!strcmp(name, part->name)) { apt_info("find %s @ tbl[%d]\n", name, i); - break; + return part; } i++; }; - if (i == cnt) { - part = NULL; - apt_wrn("do not find match in table %s\n", name); - } - return part; + + return NULL; } /* fixme, must called after offset was calculated. */ -static ulong _get_inherent_offset(const char *name) +ulong _get_inherent_offset(const char *name) { struct partitions *part; @@ -212,6 +214,7 @@ static ulong _get_inherent_offset(const char *name) else return part->offset; } + /* partition table (Emmc Partition Table) */ struct _iptbl *p_iptbl_ept = NULL; @@ -332,13 +335,13 @@ static int _calculate_offset(struct mmc *mmc, struct _iptbl *itbl, u32 bottom) #if (CONFIG_MPT_DEBUG) _dump_part_tbl(part, itbl->count); #endif - if (!strcmp(part->name, "bootloader")) { + if (!strcmp(part->name, MMC_BOOT_NAME)) { gap = MMC_BOOT_PARTITION_RESERVED; if (!is_mainstorage_emmc()) sprintf(part->name, "bootloadere"); } + for (i=1; i<itbl->count; i++) { - /**/ part[i].offset = part[i-1].offset + part[i-1].size + gap; /* check capicity overflow ?*/ if (((part[i].offset + part[i].size) > mmc->capacity) || @@ -1461,7 +1464,6 @@ struct virtual_partition *aml_get_virtual_partition_by_name(const char *name) struct virtual_partition *part = NULL; cnt = get_emmc_virtual_partition_arraysize(); while (i < cnt) { - part = &virtual_partition_table[i]; if (!strcmp(name, part->name)) { apt_info("find %10s @ tbl[%d]\n", name, i); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index d65d0340e7..aa7f9ea779 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -596,7 +596,6 @@ int mmc_hwpart_config(struct mmc *mmc, u32 tot_enh_size_mult = 0; u8 wr_rel_set; int i, pidx, err; - u64 size = 0; ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE) @@ -701,17 +700,15 @@ int mmc_hwpart_config(struct mmc *mmc, EXT_CSD_PARTITION_SETTING_COMPLETED) { printf("Card already partitioned\n"); puts("\tUser Enhanced Start: "); - print_size((u64)((size + ext_csd[EXT_CSD_ENH_START_ADDR]+ - (ext_csd[EXT_CSD_ENH_START_ADDR+1]<<8)+ - (ext_csd[EXT_CSD_ENH_START_ADDR+2]<<16)+ - ((u64)ext_csd[EXT_CSD_ENH_START_ADDR+3]<<24))<<9), "\n"); - + u64 temp, j; + for (j = 0, temp = 0; j < 4; j++) + temp |= ext_csd[EXT_CSD_ENH_START_ADDR + j] << (8 * j); + print_size(temp << 9, "\n"); puts("\tUser Enhanced Size: "); - print_size((u64)((size + ext_csd[EXT_CSD_ENH_SIZE_MULT]+ - (ext_csd[EXT_CSD_ENH_SIZE_MULT+1]<<8)+ - (ext_csd[EXT_CSD_ENH_SIZE_MULT+2]<<16))* - mmc->hc_wp_grp_size)<<9, "\n"); - + for (j = 0, temp = 0; j < 3; j++) + temp |= ext_csd[EXT_CSD_ENH_SIZE_MULT + j] << (8 * j); + temp *= mmc->hc_wp_grp_size; + print_size(temp << 9, "\n"); return -EPERM; } @@ -2242,80 +2239,130 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) } #endif -int mmc_key_read(unsigned char *buf, unsigned int size, uint32_t *actual_lenth) +extern ulong mmc_bwrite(int dev_num, lbaint_t start, + lbaint_t blkcnt, const void *src); +extern unsigned long mmc_berase(int dev_num, + lbaint_t start, lbaint_t blkcnt); +static int mmc_reserved_read(const char *name, + unsigned char *buf, unsigned int size) { ulong start, start_blk, blkcnt, ret; int dev = EMMC_DTB_DEV; - unsigned char *temp_buf = buf; struct partitions * part = NULL; struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_KEY_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); - *actual_lenth = 0x40000;/*key size is 256KB*/ + vpart = aml_get_virtual_partition_by_name(name); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); start = part->offset + vpart->offset; start_blk = (start / MMC_BLOCK_SIZE); blkcnt = (size / MMC_BLOCK_SIZE); - info_disprotect |= DISPROTECT_KEY; - ret = mmc_bread(dev, start_blk, blkcnt, temp_buf); - info_disprotect &= ~DISPROTECT_KEY; + ret = mmc_bread(dev, start_blk, blkcnt, buf); if (ret != blkcnt) { - printf("[%s] %d, mmc_bread error\n", - __func__, __LINE__); + printf("[%s] %d, mmc_bread %s error\n", + __func__, __LINE__, name); return 1; } return 0; } -extern ulong mmc_bwrite(int dev_num, lbaint_t start, - lbaint_t blkcnt, const void *src); -int mmc_key_write(unsigned char *buf, unsigned int size, uint32_t *actual_lenth) +static int mmc_reserved_write(const char *name, + unsigned char *buf, unsigned int size) { ulong start, start_blk, blkcnt, ret; - unsigned char * temp_buf = buf; int i = 2, dev = EMMC_DTB_DEV; struct partitions * part = NULL; struct virtual_partition *vpart = NULL; - vpart = aml_get_virtual_partition_by_name(MMC_KEY_NAME); - part = aml_get_partition_by_name(MMC_RESERVED_NAME); + vpart = aml_get_virtual_partition_by_name(name); + part = aml_get_partition_by_name(MMC_RESERVED_NAME); start = part->offset + vpart->offset; start_blk = (start / MMC_BLOCK_SIZE); blkcnt = (size / MMC_BLOCK_SIZE); - info_disprotect |= DISPROTECT_KEY; do { - ret = mmc_bwrite(dev, start_blk, blkcnt, temp_buf); + ret = mmc_bwrite(dev, start_blk, blkcnt, buf); if (ret != blkcnt) { - printf("[%s] %d, mmc_bwrite error\n", - __func__, __LINE__); + printf("[%s] %d, mmc_bwrite %s error\n", + __func__, __LINE__, name); return 1; } start_blk += vpart->size / MMC_BLOCK_SIZE; } while (--i); - info_disprotect &= ~DISPROTECT_KEY; return 0; } -extern unsigned long mmc_berase(int dev_num, - lbaint_t start, lbaint_t blkcnt); -int mmc_key_erase(void) +static int mmc_reserved_erase(const char *name, int number) { ulong start, start_blk, blkcnt, ret; struct partitions * part = NULL; struct virtual_partition *vpart = NULL; int dev = EMMC_DTB_DEV; - vpart = aml_get_virtual_partition_by_name(MMC_KEY_NAME); + + vpart = aml_get_virtual_partition_by_name(name); part = aml_get_partition_by_name(MMC_RESERVED_NAME); start = part->offset + vpart->offset; start_blk = (start / MMC_BLOCK_SIZE); - blkcnt = (vpart->size / MMC_BLOCK_SIZE) * 2;//key and backup key - info_disprotect |= DISPROTECT_KEY; + blkcnt = (vpart->size / MMC_BLOCK_SIZE) * number; ret = mmc_berase(dev, start_blk, blkcnt); - info_disprotect &= ~DISPROTECT_KEY; if (ret) { - printf("[%s] %d mmc_berase error\n", - __func__, __LINE__); + printf("[%s] %d mmc_berase %s error\n", + __func__, __LINE__, name); return 1; } return 0; } + +int mmc_key_read(unsigned char *buf, + unsigned int size, uint32_t *actual_lenth) +{ + int ret; + + info_disprotect |= DISPROTECT_KEY; + ret = mmc_reserved_read(MMC_KEY_NAME, buf, size); + info_disprotect &= ~DISPROTECT_KEY; + + /*key size is 256KB*/ + *actual_lenth = 0x40000; + + return ret; +} + +int mmc_key_write(unsigned char *buf, + unsigned int size, uint32_t *actual_lenth) +{ + int ret; + + info_disprotect |= DISPROTECT_KEY; + ret = mmc_reserved_write(MMC_KEY_NAME, buf, size); + info_disprotect &= ~DISPROTECT_KEY; + + return ret; +} + +int mmc_key_erase(void) +{ + int ret; + + info_disprotect |= DISPROTECT_KEY; + /* when write the 2nd key? */ + ret = mmc_reserved_erase(MMC_KEY_NAME, 2); + info_disprotect &= ~DISPROTECT_KEY; + + return ret; +} + +int mmc_ddr_parameter_read(unsigned char *buf, + unsigned int size) +{ + return mmc_reserved_read(MMC_DDR_PARAMETER_NAME, buf, size); +} + +int mmc_ddr_parameter_write(unsigned char *buf, + unsigned int size) +{ + return mmc_reserved_write(MMC_DDR_PARAMETER_NAME, buf, size); +} + +int mmc_ddr_parameter_erase(void) +{ + return mmc_reserved_erase(MMC_DDR_PARAMETER_NAME, 1); +} diff --git a/drivers/mtd/nand/amlogic_mtd/aml_dtb.c b/drivers/mtd/nand/amlogic_mtd/aml_dtb.c index 8ebbf2c0ed..5cbb7806fe 100644 --- a/drivers/mtd/nand/amlogic_mtd/aml_dtb.c +++ b/drivers/mtd/nand/amlogic_mtd/aml_dtb.c @@ -5,18 +5,6 @@ #include <malloc.h> #include "aml_mtd.h" -#ifndef AML_NAND_UBOOT -#include<linux/cdev.h> -#include <linux/device.h> - -#define DTB_NAME "amlnf_dtb" -static dev_t amlnf_dtb_no; -struct cdev amlnf_dtb; -struct device *dtb_dev = NULL; -struct class *amlnf_dtb_class = NULL; -#endif /* AML_NAND_UBOOT */ - - int dtb_erase_blk = -1; extern int get_partition_from_dts(unsigned char * buffer); @@ -25,6 +13,7 @@ struct aml_nand_chip *aml_chip_dtb = NULL; int amlnf_dtb_save(u8 *buf, unsigned int len) { + struct mtd_info *mtd = &aml_chip_dtb->mtd; u8 *dtb_buf = NULL; int ret = 0; @@ -33,11 +22,9 @@ int amlnf_dtb_save(u8 *buf, unsigned int len) printk("%s: amlnf not init yet!\n", __func__); return -EFAULT; } - if (len > aml_chip_dtb->dtbsize) { printk("warnning!!! %s: length too much\n", __func__); len = aml_chip_dtb->dtbsize; - /*return -EFAULT;*/ } dtb_buf = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); if (dtb_buf == NULL) { @@ -45,29 +32,11 @@ int amlnf_dtb_save(u8 *buf, unsigned int len) ret = -1; goto exit_err; } - memset(dtb_buf, 0, aml_chip_dtb->dtbsize); memcpy(dtb_buf, buf, len); -#if 0 //fixit - ret = amlnand_save_info_by_name(aml_chip_dtb, - (u8 *)&(aml_chip_dtb->amlnf_dtb), - dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: nand dtd save failed\n", __func__); - ret = -EFAULT; - goto exit_err; - } -#else - struct mtd_info *mtd = &aml_chip_dtb->mtd; - aml_nand_save_dtb(mtd, dtb_buf); -#endif + aml_nand_ext_save_rsv_info(mtd, + aml_chip_dtb->aml_nanddtb_info, dtb_buf); exit_err: - if (dtb_buf) { - /* kfree(dtb_buf); */ - kfree(dtb_buf); - dtb_buf = NULL; - } + kfree(dtb_buf); return ret; } @@ -76,12 +45,12 @@ int amlnf_dtb_erase(void) int ret = 0; struct mtd_info *mtd = &aml_chip_dtb->mtd; + printk("%s: ####\n", __func__); if (aml_chip_dtb == NULL) { printk("%s amlnf not ready yet!\n", __func__); return -1; } - - ret = aml_nand_erase_dtb(mtd); + ret = aml_nand_ext_erase_rsv_info(mtd, aml_chip_dtb->aml_nanddtb_info); if (ret) { printk("erase dtb error,%s\n", __func__); ret = -EFAULT; @@ -92,28 +61,20 @@ int amlnf_dtb_erase(void) int amlnf_dtb_read(u8 *buf, int len) { + struct mtd_info *mtd = &aml_chip_dtb->mtd; u8 *dtb_buf = NULL; int ret = 0; printk("%s: ####\n", __func__); - if (len > aml_chip_dtb->dtbsize) { printk("warnning!!! %s dtd length too much\n", __func__); len = aml_chip_dtb->dtbsize; - /*return -EFAULT;*/ } if (aml_chip_dtb == NULL) { memset(buf, 0x0, len); printk("%s amlnf not ready yet!\n", __func__); return 0; } -#if 0 //fixit - if (aml_chip_dtb->amlnf_dtb.arg_valid == 0) { - memset(buf, 0x0, len); - printk("%s arg_valid = 0 invalid\n", __func__); - return 0; - } -#endif dtb_buf = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); if (dtb_buf == NULL) { printk("%s: malloc failed\n", __func__); @@ -121,421 +82,17 @@ int amlnf_dtb_read(u8 *buf, int len) goto exit_err; } memset(dtb_buf, 0, aml_chip_dtb->dtbsize); -#if 0 //fixit - ret = amlnand_read_info_by_name(aml_chip_dtb, - (u8 *)&(aml_chip_dtb->amlnf_dtb), - (u8 *)dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret) { - printk("dtb error,%s\n", __func__); - ret = -EFAULT; - goto exit_err; - } -#else - struct mtd_info *mtd = &aml_chip_dtb->mtd; - size_t offset = 0; - ret = aml_nand_read_dtb(mtd, offset, (u8 *)dtb_buf); -#endif + ret = aml_nand_ext_read_rsv_info(mtd, + aml_chip_dtb->aml_nanddtb_info, 0, dtb_buf); memcpy(buf, dtb_buf, len); exit_err: - if (dtb_buf) { - /* kfree(dtb_buf); */ - kfree(dtb_buf); - dtb_buf = NULL; - } - return ret; -} - -/* under kernel */ -#ifndef AML_NAND_UBOOT -ssize_t dtb_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - printk("dtb_show : #####\n"); - /* fixme, read back and show in log! */ - return 0; -} - -ssize_t dtb_store(struct class *class, struct class_attribute *attr, - const char *buf, size_t count) -{ - int ret = 0; - u8 *dtb_ptr = NULL; - - printk("dtb_store : #####\n"); - dtb_ptr = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); - if (dtb_ptr == NULL) { - printk("%s: malloc buf failed\n ", __func__); - return -ENOMEM; - } - /* fixme, why read back then write? */ - ret = amlnf_dtb_read(dtb_ptr, aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: read failed\n", __func__); - kfree(dtb_ptr); - return -EFAULT; - } - - ret = amlnf_dtb_save(dtb_ptr, (unsigned int)aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: save failed\n", __func__); - kfree(dtb_ptr); - return -EFAULT; - } - - printk("dtb_store : OK #####\n"); - return count; -} - -static CLASS_ATTR(amlnf_dtb, S_IWUSR | S_IRUGO, dtb_show, dtb_store); - -int dtb_open(struct inode *node, struct file *file) -{ - return 0; -} - -ssize_t dtb_read(struct file *file, - char __user *buf, - size_t count, - loff_t *ppos) -{ - u8 *dtb_ptr = NULL; - struct nand_flash *flash = &aml_chip_dtb->flash; - ssize_t read_size = 0; - int ret = 0; - - if (*ppos == aml_chip_dtb->dtbsize) - return 0; - - if (*ppos >= aml_chip_dtb->dtbsize) { - printk("%s:data access out of space!\n", __func__); - return -EFAULT; - } - - dtb_ptr = vmalloc(aml_chip_dtb->dtbsize + flash->pagesize); - if (dtb_ptr == NULL) { - printk("%s: malloc buf failed\n", __func__); - return -ENOMEM; - } - - amlnand_get_device(aml_chip_dtb, CHIP_READING); - ret = amlnf_dtb_read((u8 *)dtb_ptr, aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: read failed:%d\n", __func__, ret); - ret = -EFAULT; - goto exit; - } - - if ((*ppos + count) > aml_chip_dtb->dtbsize) - read_size = aml_chip_dtb->dtbsize - *ppos; - else - read_size = count; - - ret = copy_to_user(buf, (dtb_ptr + *ppos), read_size); - *ppos += read_size; -exit: - amlnand_release_device(aml_chip_dtb); - /* kfree(dtb_ptr); */ - vfree(dtb_ptr); - return read_size; -} - -ssize_t dtb_write(struct file *file, - const char __user *buf, - size_t count, loff_t *ppos) -{ - u8 *dtb_ptr = NULL; - ssize_t write_size = 0; - struct nand_flash *flash = &aml_chip_dtb->flash; - int ret = 0; - - if (*ppos == aml_chip_dtb->dtbsize) - return 0; - - if (*ppos >= aml_chip_dtb->dtbsize) { - printk("%s: data access out of space!\n", __func__); - return -EFAULT; - } - - dtb_ptr = vmalloc(aml_chip_dtb->dtbsize + flash->pagesize); - if (dtb_ptr == NULL) { - printk("%s: malloc buf failed\n", __func__); - return -ENOMEM; - } - amlnand_get_device(aml_chip_dtb, CHIP_WRITING); - - ret = amlnf_dtb_read((u8 *)dtb_ptr, aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: read failed\n", __func__); - ret = -EFAULT; - goto exit; - } - - if ((*ppos + count) > aml_chip_dtb->dtbsize) - write_size = aml_chip_dtb->dtbsize - *ppos; - else - write_size = count; - - ret = copy_from_user((dtb_ptr + *ppos), buf, write_size); - - ret = amlnf_dtb_save(dtb_ptr, (unsigned int)aml_chip_dtb->dtbsize); - if (ret) { - printk("%s: read failed\n", __func__); - ret = -EFAULT; - goto exit; - } - - *ppos += write_size; -exit: - amlnand_release_device(aml_chip_dtb); - /* kfree(dtb_ptr); */ - vfree(dtb_ptr); - return write_size; -} - -long dtb_ioctl(struct file *file, u32 cmd, u32 args) -{ - return 0; -} - -static const struct file_operations dtb_ops = { - .open = dtb_open, - .read = dtb_read, - .write = dtb_write, - .unlocked_ioctl = dtb_ioctl, -}; -#endif /* AML_NAND_UBOOT */ - -int amlnf_dtb_init(struct aml_nand_chip *aml_chip) -{ - int ret = 0; - u8 *dtb_buf = NULL; - aml_chip_dtb = aml_chip; - - //aml_chip->dtbsize = 0x20000; //fixit - - dtb_buf = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); - if (dtb_buf == NULL) { - printk("nand malloc for dtb_buf failed\n"); - ret = -1; - goto exit_err; - } - - memset(dtb_buf, 0x0, aml_chip_dtb->dtbsize); -#if 0 //fixit - printk("nand dtb: probe.\n"); - ret = amlnand_info_init(aml_chip, - (u8 *)&(aml_chip->amlnf_dtb), - dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret < 0) { - printk("%s failed\n", __func__); - ret = -1; - goto exit_err; - } -#endif - -#ifndef AML_NAND_UBOOT - printk("%s: register dtb cdev\n", __func__); - ret = alloc_chrdev_region(&amlnf_dtb_no, 0, 1, DTB_NAME); - if (ret < 0) { - printk("%s alloc dtb dev_t number failed\n", __func__); - ret = -1; - goto exit_err; - } - - cdev_init(&amlnf_dtb, &dtb_ops); - amlnf_dtb.owner = THIS_MODULE; - ret = cdev_add(&amlnf_dtb, amlnf_dtb_no, 1); - if (ret) { - printk("%s amlnf dtd dev add failed\n", __func__); - ret = -1; - goto exit_err1; - } - - amlnf_dtb_class = class_create(THIS_MODULE, DTB_NAME); - if (IS_ERR(amlnf_dtb_class)) { - printk("%s: amlnf dtd class add failed\n", __func__); - ret = -1; - goto exit_err2; - } - - ret = class_create_file(amlnf_dtb_class, &class_attr_env); - if (ret) { - printk("%s dev add failed\n", __func__); - ret = -1; - goto exit_err2; - } - - dtb_dev = device_create(amlnf_dtb_class, - NULL, - amlnf_dtb_no, - NULL, - DTB_NAME); - if (IS_ERR(dtb_dev)) { - printk("%s: device_create failed\n", __func__); - ret = -1; - goto exit_err3; - } - - printk("%s: register dtd cdev OK\n", __func__); - kfree(dtb_buf); - dtb_buf = NULL; - - return ret; - -exit_err3: - class_remove_file(amlnf_dtb_class, &class_attr_env); - class_destroy(amlnf_dtb_class); -exit_err2: - cdev_del(&amlnf_dtb); -exit_err1: - unregister_chrdev_region(amlnf_dtb_no, 1); - -#endif /* AML_NAND_UBOOT */ -exit_err: - if (dtb_buf) { - kfree(dtb_buf); - dtb_buf = NULL; - } return ret; } -int amlnf_dtb_init_partitions(struct aml_nand_chip *aml_chip) -{ - int ret = 0; - u8 *dtb_buf = NULL; - aml_chip_dtb = aml_chip; - - dtb_buf = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); - if (dtb_buf == NULL) { - printk("nand malloc for dtb_buf failed\n"); - ret = -1; - goto exit_err; - } - memset(dtb_buf, 0x0, aml_chip_dtb->dtbsize); -#if 0 //fixit - printk("%s: probe. \n", __func__); - ret = amlnand_info_init(aml_chip, - (u8 *)&(aml_chip->amlnf_dtb), - dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret < 0) { - printk("%s failed\n", __func__); - ret = -1; - goto exit_err; - } -#endif - /*parse partitions table */ - ret = get_partition_from_dts(dtb_buf); - if (ret) { - printk("%s get_partition_from_dts failed\n", __func__); - } -exit_err: - if (dtb_buf) { - kfree(dtb_buf); - dtb_buf = NULL; - } - return ret; -} - - -/***************************************************************************** - Prototype : amlnf_detect_dtb_partitions - Description : if 'dtb, write the bad block, we can't erase this block. - So we have to find the 'dtb' address in flash and flag it. - Input : struct amlnand_chip *aml_chip - Output : NULL - Return Value : ret - Called By : amlnand_get_partition_table - - History : - 1.Date : 2015/10/15 - Author : Fly Mo - Modification : Created function - -*****************************************************************************/ -int amlnf_detect_dtb_partitions(struct aml_nand_chip *aml_chip) +int amlnf_dtb_init(struct aml_nand_chip *aml_chip) { -#if 0 //fixit - int ret = 0; - u8 *dtb_buf = NULL; aml_chip_dtb = aml_chip; - struct nand_arg_info test_amlnf_dtb; - memset(&test_amlnf_dtb, 0, sizeof(test_amlnf_dtb)); - dtb_erase_blk = -1; - dtb_buf = aml_nand_malloc(aml_chip_dtb->dtbsize); - if (dtb_buf == NULL) { - printk("nand malloc for dtb_buf failed\n"); - ret = -1; - goto exit_err; - } - memset(dtb_buf, 0x0, aml_chip_dtb->dtbsize); - test_amlnf_dtb.arg_type = aml_chip->amlnf_dtb.arg_type; - ret = amlnand_info_init(aml_chip, - (u8 *)&(test_amlnf_dtb), - dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (test_amlnf_dtb.arg_valid == 1) { - dtb_erase_blk = test_amlnf_dtb.valid_blk_addr; - } - printk("%s:dtb_erase_blk:%d\n", __func__,dtb_erase_blk); -exit_err: - if (dtb_buf) { - kfree(dtb_buf); - dtb_buf = NULL; - } - return ret; -#else - return 0; -#endif -} - -/* for blank positions... */ -int aml_nand_update_dtb(struct aml_nand_chip *aml_chip, char *dtb_ptr) -{ -#if 0 //fixit - int ret = 0; - char malloc_flag = 0; - char *dtb_buf = NULL; - - if (dtb_buf == NULL) { - dtb_buf = kzalloc(aml_chip_dtb->dtbsize, GFP_KERNEL); - malloc_flag = 1; - if (dtb_buf == NULL) - return -ENOMEM; - memset(dtb_buf, 0, aml_chip_dtb->dtbsize); - ret = amlnand_read_info_by_name(aml_chip, - (u8 *)&(aml_chip->amlnf_dtb), - (u8 *)dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret) { - printk("read dtb error,%s\n", __func__); - ret = -EFAULT; - goto exit; - } - } else - dtb_buf = dtb_ptr; - - ret = amlnand_save_info_by_name(aml_chip, - (u8 *)&(aml_chip->amlnf_dtb), - (u8 *)dtb_buf, - (u8 *)DTD_INFO_HEAD_MAGIC, - aml_chip_dtb->dtbsize); - if (ret < 0) - printk("%s: update failed\n", __func__); -exit: - if (malloc_flag && (dtb_buf)) { - kfree(dtb_buf); - dtb_buf = NULL; - } -#endif return 0; } diff --git a/drivers/mtd/nand/amlogic_mtd/aml_env.c b/drivers/mtd/nand/amlogic_mtd/aml_env.c index fe7f471ce1..2b20ef18eb 100644 --- a/drivers/mtd/nand/amlogic_mtd/aml_env.c +++ b/drivers/mtd/nand/amlogic_mtd/aml_env.c @@ -5,21 +5,6 @@ #include <malloc.h> #include "aml_mtd.h" -#ifndef AML_NAND_UBOOT -#include<linux/cdev.h> -#include <linux/device.h> - -#define CONFIG_ENV_SIZE \ - ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) ? (64*1024U) : (0x8000U)) - - -#define ENV_NAME "nand_env" -static dev_t uboot_env_no; -struct cdev uboot_env; -struct device *uboot_dev = NULL; -struct class *uboot_env_class = NULL; -#endif /* AML_NAND_UBOOT */ - struct aml_nand_chip *aml_chip_env = NULL; int amlnand_save_info_by_name_mtd(struct aml_nand_chip *aml_chip, @@ -27,7 +12,8 @@ int amlnand_save_info_by_name_mtd(struct aml_nand_chip *aml_chip, { struct mtd_info *mtd = &aml_chip->mtd; - aml_nand_save_env(mtd, buf); + aml_nand_ext_save_rsv_info(mtd, + aml_chip->aml_nandenv_info, buf); return 0; } @@ -35,24 +21,15 @@ int amlnand_read_info_by_name_mtd(struct aml_nand_chip *aml_chip, unsigned char *buf, int size) { struct mtd_info *mtd = &aml_chip->mtd; - size_t offset = 0; - aml_nand_read_env (mtd, offset, buf); - return 0; -} - -/* -int amlnand_info_init_mtd(struct aml_nand_chip *aml_chip_env, - unsigned char *buf, int size) -{ + aml_nand_ext_read_rsv_info(mtd, + aml_chip->aml_nandenv_info, 0, buf); return 0; } -*/ int amlnf_env_save(u8 *buf, int len) { u8 *env_buf = NULL; - //struct nand_flash *flash = &aml_chip_env->flash; int ret = 0; printk("uboot env amlnf_env_save : ####\n"); @@ -71,9 +48,8 @@ int amlnf_env_save(u8 *buf, int len) ret = -1; goto exit_err; } - memset(env_buf, 0, CONFIG_ENV_SIZE); - memcpy(env_buf, buf, len); + memcpy(env_buf, buf, len); ret = amlnand_save_info_by_name_mtd(aml_chip_env, env_buf, CONFIG_ENV_SIZE); @@ -83,11 +59,7 @@ int amlnf_env_save(u8 *buf, int len) goto exit_err; } exit_err: - if (env_buf) { - /* kfree(env_buf); */ - kfree(env_buf); - env_buf = NULL; - } + kfree(env_buf); return ret; } @@ -96,10 +68,8 @@ int amlnf_env_read(u8 *buf, int len) { u8 *env_buf = NULL; int ret = 0; - //struct nand_flash *flash = &aml_chip_env->flash; printk("uboot env amlnf_env_read : ####\n"); - if (len > CONFIG_ENV_SIZE) { printk("uboot env data len too much,%s\n", __func__); return -EFAULT; @@ -109,23 +79,12 @@ int amlnf_env_read(u8 *buf, int len) printk("uboot env arg_valid = 0 invalid,%s\n", __func__); return 0; } - - /* - if (aml_chip_env->uboot_env.arg_valid == 0) { - memset(buf, 0x0, len); - printk("uboot env arg_valid = 0 invalid,%s\n", __func__); - return 0; - } - */ - env_buf = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); if (env_buf == NULL) { printk("nand malloc for uboot env failed\n"); ret = -1; goto exit_err; } - memset(env_buf, 0, CONFIG_ENV_SIZE); - ret = amlnand_read_info_by_name_mtd(aml_chip_env, (u8 *)env_buf, CONFIG_ENV_SIZE); @@ -134,302 +93,17 @@ int amlnf_env_read(u8 *buf, int len) ret = -EFAULT; goto exit_err; } - memcpy(buf, env_buf, len); exit_err: - if (env_buf) { - /* kfree(env_buf); */ - kfree(env_buf); - env_buf = NULL; - } + kfree(env_buf); return ret; } -#ifndef AML_NAND_UBOOT -ssize_t env_show(struct class *class, struct class_attribute *attr, - char *buf) -{ - printk("env_show : #####\n"); - - return 0; -} - -ssize_t env_store(struct class *class, struct class_attribute *attr, - const char *buf, size_t count) -{ - int ret = 0; - u8 *env_ptr = NULL; - - printk("env_store : #####\n"); - - env_ptr = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); - if (env_ptr == NULL) { - printk("nand_env_read: nand env malloc buf failed\n"); - return -ENOMEM; - } - - ret = amlnf_env_read(env_ptr, CONFIG_ENV_SIZE); - if (ret) { - printk("nand_env_read: nand env read failed\n"); - kfree(env_ptr); - return -EFAULT; - } - - ret = amlnf_env_save(env_ptr, CONFIG_ENV_SIZE); - if (ret) { - printk("nand_env_read: nand env read failed\n"); - kfree(env_ptr); - return -EFAULT; - } - - printk("env_store : OK #####\n"); - return count; -} -static CLASS_ATTR(env, S_IWUSR | S_IRUGO, env_show, env_store); - -int uboot_env_open(struct inode *node, struct file *file) -{ - return 0; -} - -ssize_t uboot_env_read(struct file *file, - char __user *buf, - size_t count, - loff_t *ppos) -{ - u8 *env_ptr = NULL; - //struct nand_flash *flash = &aml_chip_env->flash; - ssize_t read_size = 0; - int ret = 0; - - if (*ppos == CONFIG_ENV_SIZE) - return 0; - - if (*ppos >= CONFIG_ENV_SIZE) { - aml_nand_msg("nand env: data access out of space!"); - return -EFAULT; - } - - /* env_ptr = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); */ - env_ptr = vmalloc(CONFIG_ENV_SIZE + 2048); - if (env_ptr == NULL) { - aml_nand_msg("nand_env_read: nand env malloc buf failed "); - return -ENOMEM; - } - - //amlnand_get_device(aml_chip_env, CHIP_READING); - ret = amlnf_env_read((u8 *)env_ptr, CONFIG_ENV_SIZE); - if (ret) { - aml_nand_msg("nand_env_read: nand env read failed:%d", ret); - ret = -EFAULT; - goto exit; - } - - if ((*ppos + count) > CONFIG_ENV_SIZE) - read_size = CONFIG_ENV_SIZE - *ppos; - else - read_size = count; - - ret = copy_to_user(buf, (env_ptr + *ppos), read_size); - *ppos += read_size; -exit: - //amlnand_release_device(aml_chip_env); - /* kfree(env_ptr); */ - vfree(env_ptr); - return read_size; -} - -ssize_t uboot_env_write(struct file *file, - const char __user *buf, - size_t count, loff_t *ppos) -{ - u8 *env_ptr = NULL; - ssize_t write_size = 0; - //struct nand_flash *flash = &aml_chip_env->flash; - int ret = 0; - - if (*ppos == CONFIG_ENV_SIZE) - return 0; - - if (*ppos >= CONFIG_ENV_SIZE) { - aml_nand_msg("nand env: data access out of space!"); - return -EFAULT; - } - - /* env_ptr = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); */ - env_ptr = vmalloc(CONFIG_ENV_SIZE + 2048); - if (env_ptr == NULL) { - aml_nand_msg("nand_env_read: nand env malloc buf failed "); - return -ENOMEM; - } - amlnand_get_device(aml_chip_env, CHIP_WRITING); - - if ((*ppos + count) > CONFIG_ENV_SIZE) - write_size = CONFIG_ENV_SIZE - *ppos; - else - write_size = count; - - ret = copy_from_user((env_ptr + *ppos), buf, write_size); - - ret = amlnf_env_save(env_ptr, CONFIG_ENV_SIZE); - if (ret) { - aml_nand_msg("nand_env_read: nand env read failed"); - ret = -EFAULT; - goto exit; - } - - *ppos += write_size; -exit: - amlnand_release_device(aml_chip_env); - /* kfree(env_ptr); */ - vfree(env_ptr); - return write_size; -} - -long uboot_env_ioctl(struct file *file, u32 cmd, u32 args) -{ - return 0; -} - -static const struct file_operations uboot_env_ops = { - .open = uboot_env_open, - .read = uboot_env_read, - .write = uboot_env_write, - .unlocked_ioctl = uboot_env_ioctl, -}; -#endif /* AML_NAND_UBOOT */ int aml_ubootenv_init(struct aml_nand_chip *aml_chip) { - int ret = 0; - u8 *env_buf = NULL; aml_chip_env = aml_chip; - - env_buf = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); - if (env_buf == NULL) { - printk("nand malloc for secure_ptr failed\n"); - ret = -1; - goto exit_err; - } - memset(env_buf, 0x0, CONFIG_ENV_SIZE); - /* - ret = amlnand_info_init_mtd(aml_chip, - env_buf, - CONFIG_ENV_SIZE); - if (ret < 0) { - printk("%s failed\n", __func__); - ret = -1; - goto exit_err; - } - */ - - /*if(aml_chip->uboot_env.arg_valid == 0){ - memset(env_buf,0x0,CONFIG_ENV_SIZE); - ret = amlnf_env_save(env_buf,CONFIG_ENV_SIZE); - if (ret) { - aml_nand_msg("amlnf_env_save: save env failed"); - } - }*/ -#ifndef AML_NAND_UBOOT - aml_nand_dbg("%s: register env chardev", __func__); - ret = alloc_chrdev_region(&uboot_env_no, 0, 1, ENV_NAME); - if (ret < 0) { - aml_nand_msg("alloc uboot env dev_t no failed"); - ret = -1; - goto exit_err; - } - - cdev_init(&uboot_env, &uboot_env_ops); - uboot_env.owner = THIS_MODULE; - ret = cdev_add(&uboot_env, uboot_env_no, 1); - if (ret) { - aml_nand_msg("uboot env dev add failed"); - ret = -1; - goto exit_err1; - } - - uboot_env_class = class_create(THIS_MODULE, ENV_NAME); - if (IS_ERR(uboot_env_class)) { - aml_nand_msg("uboot env dev add failed"); - ret = -1; - goto exit_err2; - } - - ret = class_create_file(uboot_env_class, &class_attr_env); - if (ret) { - aml_nand_msg("uboot env dev add failed"); - ret = -1; - goto exit_err2; - } - - uboot_dev = device_create(uboot_env_class, - NULL, - uboot_env_no, - NULL, - ENV_NAME); - if (IS_ERR(uboot_dev)) { - aml_nand_msg("uboot env dev add failed"); - ret = -1; - goto exit_err3; - } - - aml_nand_dbg("%s: register env chardev OK", __func__); - - kfree(env_buf); - env_buf = NULL; - - return ret; - -exit_err3: - class_remove_file(uboot_env_class, &class_attr_env); - class_destroy(uboot_env_class); -exit_err2: - cdev_del(&uboot_env); -exit_err1: - unregister_chrdev_region(uboot_env_no, 1); - -#endif /* AML_NAND_UBOOT */ -exit_err: - if (env_buf) { - kfree(env_buf); - env_buf = NULL; - } - return ret; -} -/* update env if only it is still readable! */ -int aml_nand_update_ubootenv(struct aml_nand_chip *aml_chip, char *env_ptr) -{ - int ret = 0; - char malloc_flag = 0; - char *env_buf = NULL; - - if (env_buf == NULL) { - env_buf = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL); - malloc_flag = 1; - if (env_buf == NULL) - return -ENOMEM; - memset(env_buf, 0, CONFIG_ENV_SIZE); - ret = amlnand_read_info_by_name_mtd(aml_chip, - (u8 *)env_buf, - CONFIG_ENV_SIZE); - if (ret) { - printk("read ubootenv error,%s\n", __func__); - ret = -EFAULT; - goto exit; - } - } else - env_buf = env_ptr; - - ret = amlnand_save_info_by_name_mtd(aml_chip, - (u8 *)env_buf, - CONFIG_ENV_SIZE); - if (ret < 0) - printk("aml_nand_update_secure : update secure failed\n"); -exit: - if (malloc_flag && (env_buf)) { - kfree(env_buf); - env_buf = NULL; - } return 0; } + diff --git a/drivers/mtd/nand/amlogic_mtd/aml_key.c b/drivers/mtd/nand/amlogic_mtd/aml_key.c index e093a78f47..eff4586d9e 100644 --- a/drivers/mtd/nand/amlogic_mtd/aml_key.c +++ b/drivers/mtd/nand/amlogic_mtd/aml_key.c @@ -7,111 +7,55 @@ static struct aml_nand_chip *aml_chip_key = NULL; -struct nand_menson_key { - u32 crc; - u8 data[252]; -}; -/* - * This funcion reads the u-boot keys. - */ -int amlnf_key_read(u8 * buf, int len, uint32_t *actual_lenth) +int amlnf_key_read(u8 *buf, int len, uint32_t *actual_lenth) { struct aml_nand_chip * aml_chip = aml_chip_key; - uint8_t *key_ptr = NULL; - u32 keysize = aml_chip->keysize - sizeof(u32); - //int error = 0; + struct mtd_info *mtd = &aml_chip->mtd; + u8 *key_ptr = NULL; - *actual_lenth = keysize; + printk("%s: ####\n", __func__); if (aml_chip == NULL) { printk("%s(): amlnf key not ready yet!", __func__); return -EFAULT; } - - if (len > keysize) { - /* - No return here! keep consistent, should memset zero - for the rest. - */ + if (len > aml_chip->keysize) { printk("%s key data len too much\n",__func__); - memset(buf + keysize, 0 , len - keysize); - //return -EFAULT; + return -EFAULT; } - key_ptr = kzalloc(aml_chip->keysize, GFP_KERNEL); if (key_ptr == NULL) return -ENOMEM; -#if 0 //fixit - error = amlnand_read_info_by_name(aml_chip, - (u8 *)&(aml_chip->nand_key), - (u8 *)key_ptr, - (u8*)KEY_INFO_HEAD_MAGIC, - aml_chip->keysize); - if (error) { - printk("%s: read key error\n",__func__); - error = -EFAULT; - goto exit; - } -#else - struct mtd_info *mtd = &aml_chip->mtd; - size_t offset = 0; - aml_nand_read_key(mtd, offset, key_ptr); -#endif - - memcpy(buf, key_ptr, keysize); - -//exit: + aml_nand_ext_read_rsv_info(mtd, + aml_chip_key->aml_nandkey_info, 0, key_ptr); + memcpy(buf, key_ptr, len); + *actual_lenth = aml_chip->keysize; kfree(key_ptr); return 0; } -/* - * This funcion write the keys. - */ int amlnf_key_write(u8 *buf, int len, uint32_t *actual_lenth) { struct aml_nand_chip * aml_chip = aml_chip_key; - uint8_t *key_ptr = NULL; - u32 keysize = aml_chip->keysize - sizeof(u32); + struct mtd_info *mtd = &aml_chip->mtd; + u8 *key_ptr = NULL; int error = 0; + printk("%s: ####\n", __func__); if (aml_chip == NULL) { printk("%s(): amlnf key not ready yet!", __func__); return -EFAULT; } - - if (len > keysize) { - /* - No return here! keep consistent, should memset zero - for the rest. - */ + if (len > aml_chip->keysize) { printk("key data len too much,%s\n",__func__); - memset(buf + keysize, 0 , len - keysize); - //return -EFAULT; + return -EFAULT; } - key_ptr = kzalloc(aml_chip->keysize, GFP_KERNEL); if (key_ptr == NULL) return -ENOMEM; - - memset(key_ptr, 0, aml_chip->keysize); - memcpy(key_ptr, buf, keysize); -#if 0 //fixit - error = amlnand_save_info_by_name(aml_chip, - (u8 *)&(aml_chip->nand_key), - (u8 *)key_ptr, - (u8 *)KEY_INFO_HEAD_MAGIC, - aml_chip->keysize); - if (error) { - printk("save key error,%s\n",__func__); - error = -EFAULT; - goto exit; - } -#else - struct mtd_info *mtd = &aml_chip->mtd; - aml_nand_save_key(mtd, key_ptr); -#endif -//exit: + memcpy(key_ptr, buf, len); + aml_nand_ext_save_rsv_info(mtd, + aml_chip_key->aml_nandkey_info, key_ptr); kfree(key_ptr); return error; } @@ -121,103 +65,86 @@ int amlnf_key_erase(void) int ret = 0; struct mtd_info *mtd = &aml_chip_key->mtd; + printk("%s: ####\n", __func__); if (aml_chip_key == NULL) { printk("%s amlnf not ready yet!\n", __func__); return -1; } - - ret = aml_nand_erase_key(mtd); + ret = aml_nand_ext_erase_rsv_info(mtd, aml_chip_key->aml_nandkey_info); if (ret) { printk("%s erase key error\n", __func__); ret = -EFAULT; } - return ret; } -int aml_key_init(struct aml_nand_chip *aml_chip) +int amlnf_ddr_parameter_read(u8 *buf, int len) { - int ret = 0; - - /* avoid null */ - aml_chip_key = aml_chip; -#if 0 //fixit - struct nand_menson_key *key_ptr = NULL; + struct aml_nand_chip *aml_chip = aml_chip_key; + struct mtd_info *mtd = &aml_chip->mtd; + u8 *key_ptr = NULL; - key_ptr = kzalloc(aml_chip->keysize, GFP_KERNEL); - if (key_ptr == NULL) { - printk("nand malloc for key_ptr failed"); - ret = -1; - goto exit_error0; + printk("%s: ####\n", __func__); + if (aml_chip == NULL) { + printk("%s(): amlnf key not ready yet!", __func__); + return -EFAULT; } - memset(key_ptr, 0x0, aml_chip->keysize); - printk("%s probe.\n", __func__); + key_ptr = malloc(2048); + if (key_ptr == NULL) + return -ENOMEM; + aml_nand_ext_read_rsv_info(mtd, + aml_chip_key->aml_nandddr_info, 0, key_ptr); + memcpy(buf, key_ptr, len); + free(key_ptr); + return 0; +} - ret = amlnand_info_init(aml_chip, - (u8 *)&(aml_chip->nand_key), - (u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, - aml_chip->keysize); - if (ret < 0) { - printk("invalid nand key\n"); - } +int amlnf_ddr_parameter_write(u8 *buf, int len) +{ + struct aml_nand_chip *aml_chip = aml_chip_key; + struct mtd_info *mtd = &aml_chip->mtd; + u8 *key_ptr = NULL; + int error = 0; -exit_error0: - if (key_ptr) { - kfree(key_ptr); - key_ptr =NULL; + printk("%s: ####\n", __func__); + if (aml_chip == NULL) { + printk("%s(): amlnf key not ready yet!", __func__); + return -EFAULT; } -#endif - printk("%s %d\n", __func__, __LINE__); - return ret; + if (len > 2048) { + printk("key data len too much,%s\n",__func__); + return -EFAULT; + } + key_ptr = malloc(2048); + if (key_ptr == NULL) + return -ENOMEM; + memcpy(key_ptr, buf, len); + aml_nand_ext_save_rsv_info(mtd, + aml_chip_key->aml_nandddr_info, key_ptr); + free(key_ptr); + return error; } - -int aml_nand_update_key(struct aml_nand_chip * aml_chip, char *key_ptr) +int amlnf_ddr_parameter_erase(void) { - //int ret = 0; - int malloc_flag = 0; - char *key_buf = NULL; - - if (key_buf == NULL) { - key_buf = kzalloc(aml_chip->keysize, GFP_KERNEL); - malloc_flag = 1; - if (key_buf == NULL) - return -ENOMEM; - memset(key_buf, 0, aml_chip->keysize); -#if 0 //fixit - ret = amlnand_read_info_by_name(aml_chip, - (u8 *)&(aml_chip->nand_key), - (u8 *)key_buf, - (u8 *)KEY_INFO_HEAD_MAGIC, - aml_chip->keysize); - if (ret) { - printk("%s: read key error\n", __func__); - ret = -EFAULT; - goto exit; - } -#endif - } else { - key_buf = key_ptr; - } -#if 0 //fixit - printk("amlnf_key : type %d, valid %d, flag %d, blk %d, page %d\n", - aml_chip->nand_key.arg_type,aml_chip->nand_key.arg_valid, - aml_chip->nand_key.update_flag,aml_chip->nand_key.valid_blk_addr, - aml_chip->nand_key.valid_page_addr); + int ret = 0; + struct mtd_info *mtd = &aml_chip_key->mtd; - ret = amlnand_save_info_by_name( aml_chip, - (u8 *)&(aml_chip->nand_key), - (u8 *)key_buf, - (u8 *)KEY_INFO_HEAD_MAGIC, - aml_chip->keysize); - if (ret < 0) { - printk("%s : save key info failed\n", __func__); + printk("%s: ####\n", __func__); + if (aml_chip_key == NULL) { + printk("%s amlnf not ready yet!\n", __func__); + return -1; } -#endif -//exit: - if (malloc_flag &&(key_buf)) { - kfree(key_buf); - key_buf = NULL; + ret = aml_nand_ext_erase_rsv_info(mtd, aml_chip_key->aml_nandddr_info); + if (ret) { + printk("%s erase key error\n", __func__); + ret = -EFAULT; } - return 0; + return ret; } + +int aml_key_init(struct aml_nand_chip *aml_chip) +{ + aml_chip_key = aml_chip; + return 0; +}
\ No newline at end of file diff --git a/drivers/mtd/nand/amlogic_mtd/aml_mtd.h b/drivers/mtd/nand/amlogic_mtd/aml_mtd.h index 0d1598d20c..7a72101c73 100644 --- a/drivers/mtd/nand/amlogic_mtd/aml_mtd.h +++ b/drivers/mtd/nand/amlogic_mtd/aml_mtd.h @@ -67,18 +67,22 @@ typedef struct nand_setup { typedef struct _ext_info{ uint32_t read_info; //nand_read_info; uint32_t new_type; //new_nand_type; - uint32_t page_per_blk; //pages_in_block; + uint32_t page_per_blk; //pages_in_block; uint32_t xlc; //slc=1, mlc=2, tlc=3. uint32_t ce_mask; - /* copact mode: boot means whole uboot - it's easy to understood that copies of - bl2 and fip are the same. - * discrete mode, boot means the fip only */ + /* + * copact mode: boot means whole uboot + * it's easy to understood that copies of + * bl2 and fip are the same. + * discrete mode, boot means the fip only. + */ uint32_t boot_num; uint32_t each_boot_pages; /* for comptible reason */ uint32_t bbt_occupy_pages; uint32_t bbt_start_block; + uint32_t ddrp_start_block; + uint32_t ddrp_start_occupy_pages; } ext_info_t; #define NAND_FIPMODE_COMPACT (0) @@ -88,7 +92,6 @@ typedef struct _ext_info{ * partitions, please enable this macro. * #define CONFIG_NOT_SKIP_BAD_BLOCK */ - typedef struct _fip_info { uint16_t version; //version uint16_t mode; //compact or discrete @@ -151,6 +154,7 @@ typedef union nand_core_clk { #define NAND_ENV_BLOCK_NUM 8 #define NAND_KEY_BLOCK_NUM 8 #define NAND_DTB_BLOCK_NUM 4 +#define NAND_DDR_BLOCK_NUM 2 #define AML_CHIP_NONE_RB 4 #define AML_INTERLEAVING_MODE 8 @@ -218,6 +222,7 @@ typedef union nand_core_clk { #define KEY_NAND_MAGIC "nkey" #define SEC_NAND_MAGIC "nsec" #define DTB_NAND_MAGIC "ndtb" +#define DDR_NAND_MAGIC "nddr" #define NAND_SYS_PART_SIZE 0x8000000 struct aml_nand_flash_dev { @@ -483,11 +488,14 @@ struct aml_nand_chip { unsigned char *rsv_data_buf; unsigned long long freeNodeBitmask; struct free_node_t *free_node[RESERVED_BLOCK_NUM]; + + unsigned int vernier; struct aml_nand_bbt_info *nand_bbt_info; struct aml_nandrsv_info_t *aml_nandbbt_info; struct aml_nandrsv_info_t *aml_nandenv_info; struct aml_nandrsv_info_t *aml_nandkey_info; struct aml_nandrsv_info_t *aml_nanddtb_info; + struct aml_nandrsv_info_t *aml_nandddr_info; struct aml_nand_bch_desc *bch_desc; #ifdef NEW_NAND_SUPPORT struct new_tech_nand_t new_nand_info; @@ -705,44 +713,31 @@ int aml_nand_block_bad_scrub_update_bbt(struct mtd_info *mtd); int aml_ubootenv_init(struct aml_nand_chip *aml_chip); -int aml_nand_read_env (struct mtd_info *mtd, size_t offset, u_char * buf); - -int aml_nand_save_env(struct mtd_info *mtd, u_char *buf); - int amlnf_dtb_init(struct aml_nand_chip *aml_chip); -int aml_nand_read_dtb (struct mtd_info *mtd, size_t offset, u_char * buf); - -int aml_nand_save_dtb(struct mtd_info *mtd, u_char *buf); - int aml_key_init(struct aml_nand_chip *aml_chip); -int aml_nand_rsv_erase_protect(struct mtd_info *mtd, unsigned int block_addr); - -int aml_nand_erase_dtb(struct mtd_info *mtd); - -int aml_nand_erase_key(struct mtd_info *mtd); - -int aml_nand_save_key(struct mtd_info *mtd, u_char *buf); - -int aml_nand_read_key (struct mtd_info *mtd, size_t offset, u_char * buf); - -int aml_nand_key_check(struct mtd_info *mtd); +int aml_nand_bbt_check(struct mtd_info *mtd); -//int aml_nand_free_valid_env(struct mtd_info *mtd); +int aml_nand_rsv_info_check_except_bbt(struct mtd_info *mtd); -int aml_nand_save_bbt(struct mtd_info *mtd, u_char *buf); +int aml_nand_rsv_erase_protect(struct mtd_info *mtd, unsigned int block_addr); int aml_nand_rsv_info_init(struct mtd_info *mtd); int aml_nand_scan_rsv_info(struct mtd_info *mtd, struct aml_nandrsv_info_t *nandrsv_info); -int aml_nand_env_check(struct mtd_info *mtd); +int aml_nand_ext_erase_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info); -int aml_nand_bbt_check(struct mtd_info *mtd); +int aml_nand_ext_read_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info, + size_t offset, u_char *buf); -int aml_nand_dtb_check(struct mtd_info *mtd); +int aml_nand_ext_save_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info, + u_char *buf); int aml_nand_scan_bbt(struct mtd_info *mtd); diff --git a/drivers/mtd/nand/amlogic_mtd/aml_nand.c b/drivers/mtd/nand/amlogic_mtd/aml_nand.c index 180a2d44fc..e342ad895d 100644 --- a/drivers/mtd/nand/amlogic_mtd/aml_nand.c +++ b/drivers/mtd/nand/amlogic_mtd/aml_nand.c @@ -3640,7 +3640,8 @@ int aml_nand_block_markbad(struct mtd_info *mtd, loff_t ofs) } else if (aml_chip->block_status[blk_addr] ==NAND_BLOCK_GOOD) { aml_chip->block_status[blk_addr] = NAND_BLOCK_BAD; buf = aml_chip->block_status; - aml_nand_save_bbt(mtd, (u_char *)buf); + aml_nand_ext_save_rsv_info(mtd, + aml_chip->aml_nandbbt_info, (u_char *)buf); } } mark_bad: @@ -3918,11 +3919,8 @@ int aml_nand_init(struct aml_nand_chip *aml_chip) printk("invalid nand bbt\n"); goto exit_error; } -#ifndef CONFIG_ENV_IS_IN_NAND - aml_nand_env_check(mtd); -#endif - aml_nand_key_check(mtd); - aml_nand_dtb_check(mtd); + + aml_nand_rsv_info_check_except_bbt(mtd); #ifdef NEW_NAND_SUPPORT if ((aml_chip->new_nand_info.type) diff --git a/drivers/mtd/nand/amlogic_mtd/boot.c b/drivers/mtd/nand/amlogic_mtd/boot.c index 1f1081245e..cb310a9445 100644 --- a/drivers/mtd/nand/amlogic_mtd/boot.c +++ b/drivers/mtd/nand/amlogic_mtd/boot.c @@ -143,6 +143,17 @@ void nand_info_page_prepare(struct aml_nand_chip *aml_chip, u8 *page0_buf) p_ext_info->bbt_occupy_pages = bbt_pages; p_ext_info->bbt_start_block = (BOOT_TOTAL_PAGES >> pages_per_blk_shift) + NAND_GAP_BLOCK_NUM; + p_ext_info->ddrp_start_occupy_pages = + (((2048 + mtd->writesize - 1) / mtd->writesize) << 16) & + 0xffff0000; + p_ext_info->ddrp_start_occupy_pages |= + aml_chip_normal->aml_nandddr_info->valid_node->phy_page_addr & + 0x0000ffff; + p_ext_info->ddrp_start_block = + aml_chip_normal->aml_nandddr_info->start_block; + printk("ddrp_start_occupy_pages = 0x%x ddr_start_block = 0x%x\n", + p_ext_info->ddrp_start_occupy_pages, + p_ext_info->ddrp_start_block); #ifdef CONFIG_DISCRETE_BOOTLOADER p_fip_info = &p_nand_page0->fip_info; p_fip_info->version = 1; diff --git a/drivers/mtd/nand/amlogic_mtd/rsv_manage.c b/drivers/mtd/nand/amlogic_mtd/rsv_manage.c index e59ac73d09..b9d80d35ac 100644 --- a/drivers/mtd/nand/amlogic_mtd/rsv_manage.c +++ b/drivers/mtd/nand/amlogic_mtd/rsv_manage.c @@ -32,6 +32,32 @@ static inline int _aml_rsv_isprotect(void) } //#define CONFIG_DBG_BITMAP 1 + +struct rsv_info { + char name[8]; + struct aml_nandrsv_info_t rsv_info; + unsigned int blocks; + unsigned int size; +}; + +#define BBT_INFO_INDEX 0 +#define ENV_INFO_INDEX 1 +#define KEY_INFO_INDEX 2 +#define DTB_INFO_INDEX 3 +#define DDR_INFO_INDEX 4 + +#define INFO_DATA(n, b, s) { .name = (n), .blocks = (b), .size = (s) } + +static struct rsv_info info[] = { + INFO_DATA(BBT_NAND_MAGIC, NAND_BBT_BLOCK_NUM, 0), +#ifndef CONFIG_ENV_IS_IN_NAND + INFO_DATA(ENV_NAND_MAGIC, NAND_ENV_BLOCK_NUM, CONFIG_ENV_SIZE), +#endif + INFO_DATA(KEY_NAND_MAGIC, NAND_KEY_BLOCK_NUM, 0), + INFO_DATA(DTB_NAND_MAGIC, NAND_DTB_BLOCK_NUM, 0), + INFO_DATA(DDR_NAND_MAGIC, NAND_DDR_BLOCK_NUM, 2048), +}; + static struct free_node_t *get_free_node(struct mtd_info *mtd) { struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); @@ -456,55 +482,21 @@ READ_RSV_AGAIN: } } #endif - //if(data_buf) - // kfree(data_buf); return 0; } -int aml_nand_read_env (struct mtd_info *mtd, size_t offset, u_char * buf) +int aml_nand_ext_read_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info, + size_t offset, u_char *buf) { - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - - if (!aml_chip->aml_nandenv_info->valid) { - printk("%s %d: %s is invalid! read exit!\n", - __func__, __LINE__, - aml_chip->aml_nandenv_info->name); - return 1; - } - if (aml_nand_read_rsv_info(mtd, - aml_chip->aml_nandenv_info, offset, (u_char *)buf)) - return 1; - return 0; -} - -int aml_nand_read_key (struct mtd_info *mtd, size_t offset, u_char * buf) -{ - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - - if (!aml_chip->aml_nandkey_info->valid) { - printk("%s %d: %s is invalid! read exit!\n", - __func__, __LINE__, - aml_chip->aml_nandkey_info->name); - return 1; - } - if (aml_nand_read_rsv_info(mtd, - aml_chip->aml_nandkey_info, offset, (u_char *)buf)) - return 1; - return 0; -} - -int aml_nand_read_dtb (struct mtd_info *mtd, size_t offset, u_char * buf) -{ - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - - if (!aml_chip->aml_nanddtb_info->valid) { + if (!info->valid) { printk("%s %d: %s is invalid! read exit!", - __func__, __LINE__, - aml_chip->aml_nanddtb_info->name); + __func__, + __LINE__, + info->name); return 1; } - if (aml_nand_read_rsv_info(mtd, - aml_chip->aml_nanddtb_info, offset, (u_char *)buf)) + if (aml_nand_read_rsv_info(mtd, info, offset, (u_char *)buf)) return 1; return 0; } @@ -639,20 +631,10 @@ int aml_nand_erase_rsv_info(struct mtd_info *mtd, return error; } -int aml_nand_erase_dtb(struct mtd_info *mtd) -{ - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - - if (aml_nand_erase_rsv_info(mtd, aml_chip->aml_nanddtb_info)) - return 1; - return 0; -} - -int aml_nand_erase_key(struct mtd_info *mtd) +int aml_nand_ext_erase_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info) { - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - - if (aml_nand_erase_rsv_info(mtd, aml_chip->aml_nandkey_info)) + if (aml_nand_erase_rsv_info(mtd, info)) return 1; return 0; } @@ -797,72 +779,78 @@ RE_SEARCH: return error; } -int aml_nand_save_env(struct mtd_info *mtd, u_char *buf) +int aml_nand_ext_save_rsv_info(struct mtd_info *mtd, + struct aml_nandrsv_info_t *info, + u_char *buf) { - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - //env_t *env_ptr = (env_t *)buf; - - if (!aml_chip->aml_nandenv_info->init) { + if (!info->init) { printk("%s %d %s not init\n", - __func__, __LINE__, - aml_chip->aml_nandenv_info->name); + __func__, __LINE__, info->name); return 1; } - /*fixit*/ - //env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); - if (aml_nand_save_rsv_info(mtd, aml_chip->aml_nandenv_info, buf)) + if (aml_nand_save_rsv_info(mtd, info, buf)) return 1; return 0; } -int aml_nand_save_key(struct mtd_info *mtd, u_char *buf) +static void aml_nand_rsv_info_size_fill(struct mtd_info *mtd) { struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - //env_t *env_ptr = (env_t *)buf; + struct nand_chip *chip = mtd->priv; + int subtract = -1; - if (!aml_chip->aml_nandkey_info->init) { - printk("%s %d %s not init\n", - __func__, __LINE__, - aml_chip->aml_nandkey_info->name); - return 1; - } - /*fixit*/ - //env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); - if (aml_nand_save_rsv_info(mtd, aml_chip->aml_nandkey_info, buf)) - return 1; - return 0; +#ifndef CONFIG_ENV_IS_IN_NAND + subtract = 0; +#endif + info[BBT_INFO_INDEX].size = mtd->size >> chip->phys_erase_shift; + info[KEY_INFO_INDEX + subtract].size = aml_chip->keysize; + info[DTB_INFO_INDEX + subtract].size = aml_chip->dtbsize; } -int aml_nand_save_dtb(struct mtd_info *mtd, u_char *buf) +static void aml_nand_rsv_info_ptr_fill(struct mtd_info *mtd) { struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - //env_t *env_ptr = (env_t *)buf; + int subtract = -1; - if (!aml_chip->aml_nanddtb_info->init) { - printk("%s %d %s not init\n", - __func__, __LINE__, - aml_chip->aml_nanddtb_info->name); - return 1; - } - /*fixit*/ - //env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); - if (aml_nand_save_rsv_info(mtd, aml_chip->aml_nanddtb_info, buf)) - return 1; - return 0; + aml_chip->aml_nandbbt_info = &info[BBT_INFO_INDEX].rsv_info; +#ifndef CONFIG_ENV_IS_IN_NAND + aml_chip->aml_nandenv_info = &info[ENV_INFO_INDEX].rsv_info; + subtract = 0; +#endif + aml_chip->aml_nandkey_info = &info[KEY_INFO_INDEX + subtract].rsv_info; + aml_chip->aml_nanddtb_info = &info[DTB_INFO_INDEX + subtract].rsv_info; + aml_chip->aml_nandddr_info = &info[DDR_INFO_INDEX + subtract].rsv_info; } -int aml_nand_save_bbt(struct mtd_info *mtd, u_char *buf) +static int aml_nand_rsv_info_alloc_init(struct mtd_info *mtd, + char *name, + struct aml_nandrsv_info_t **rsv_info, + unsigned int blocks, unsigned int size) { struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); + struct aml_nandrsv_info_t *rsvinfo = *rsv_info; + struct nand_chip *chip = mtd->priv; + unsigned int limit_blk, pages_per_blk_shift; - if (!aml_chip->aml_nandbbt_info->init) { - printk("%s %d %s not init\n", - __func__, __LINE__, - aml_chip->aml_nandbbt_info->name); - return 1; + pages_per_blk_shift = (chip->phys_erase_shift - chip->page_shift); + limit_blk = (BOOT_TOTAL_PAGES >> pages_per_blk_shift) + + RESERVED_BLOCK_NUM; + if (aml_chip->vernier + blocks > limit_blk) { + pr_info("ERROR: total blk number is over the limit\n"); + return -ERANGE; } - if (aml_nand_save_rsv_info(mtd, aml_chip->aml_nandbbt_info, buf)) - return 1; + + rsvinfo->mtd = mtd; + rsvinfo->valid_node = kzalloc(sizeof(struct valid_node_t), GFP_KERNEL); + if (rsvinfo->valid_node == NULL) + return -ENOMEM; + + rsvinfo->valid_node->phy_blk_addr = -1; + rsvinfo->start_block = aml_chip->vernier; + aml_chip->vernier += blocks; + rsvinfo->end_block = aml_chip->vernier; + rsvinfo->size = size; + memcpy(rsvinfo->name, name, 4); return 0; } @@ -870,22 +858,18 @@ int aml_nand_rsv_info_init(struct mtd_info *mtd) { struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); struct nand_chip *chip = mtd->priv; - unsigned int pages_per_blk_shift, bbt_start_block, vernier; - int phys_erase_shift , i; + struct aml_nandrsv_info_t *rsv_info; + unsigned int pages_per_blk_shift, bbt_start_block; + int i, ret; - phys_erase_shift = fls(mtd->erasesize) - 1; pages_per_blk_shift = (chip->phys_erase_shift - chip->page_shift); - - /*bootloader occupy 1024 pages*/ bbt_start_block = BOOT_TOTAL_PAGES >> pages_per_blk_shift; - bbt_start_block += NAND_GAP_BLOCK_NUM; /*gap occupy 4 blocks*/ - /* fixme, avoid dma occpied data buffer*/ - aml_chip->rsv_data_buf = kzalloc(2 * mtd->writesize, GFP_KERNEL); - - vernier = bbt_start_block; + bbt_start_block += NAND_GAP_BLOCK_NUM; + aml_chip->rsv_data_buf = kzalloc(mtd->writesize, GFP_KERNEL); if (aml_chip->rsv_data_buf == NULL) return -ENOMEM; + aml_chip->vernier = bbt_start_block; aml_chip->freeNodeBitmask = 0; for (i = 0; i < RESERVED_BLOCK_NUM; i++) { aml_chip->free_node[i] = @@ -893,107 +877,41 @@ int aml_nand_rsv_info_init(struct mtd_info *mtd) aml_chip->free_node[i]->index = i; } - /*bbt info init*/ - aml_chip->aml_nandbbt_info = - kzalloc(sizeof(struct aml_nandrsv_info_t), GFP_KERNEL); - if (aml_chip->aml_nandbbt_info == NULL) - return -ENOMEM; - - aml_chip->aml_nandbbt_info->mtd = mtd; - aml_chip->aml_nandbbt_info->valid_node = - kzalloc(sizeof(struct valid_node_t), GFP_KERNEL); - if (aml_chip->aml_nandbbt_info->valid_node == NULL) - return -ENOMEM; - - aml_chip->aml_nandbbt_info->valid_node->phy_blk_addr = -1; - aml_chip->aml_nandbbt_info->start_block = vernier; - aml_chip->aml_nandbbt_info->end_block = - vernier + NAND_BBT_BLOCK_NUM; - vernier += NAND_BBT_BLOCK_NUM; - aml_chip->aml_nandbbt_info->size = mtd->size >> phys_erase_shift; - memcpy(aml_chip->aml_nandbbt_info->name, BBT_NAND_MAGIC, 4); - /*block status*/ aml_chip->block_status = - kzalloc((mtd->size >> phys_erase_shift), GFP_KERNEL); + kzalloc((mtd->size >> chip->phys_erase_shift), GFP_KERNEL); if (aml_chip->block_status == NULL) { printk("no memory for flash block status\n"); return -ENOMEM; } - memset(aml_chip->block_status, 0, (mtd->size >> phys_erase_shift)); -#ifndef CONFIG_ENV_IS_IN_NAND - /*env info init*/ - aml_chip->aml_nandenv_info = - kzalloc(sizeof(struct aml_nandrsv_info_t), GFP_KERNEL); - if (aml_chip->aml_nandenv_info == NULL) - return -ENOMEM; - - aml_chip->aml_nandenv_info->mtd = mtd; - aml_chip->aml_nandenv_info->valid_node = - kzalloc(sizeof(struct valid_node_t), GFP_KERNEL); - if (aml_chip->aml_nandenv_info->valid_node == NULL) - return -ENOMEM; - - aml_chip->aml_nandenv_info->valid_node->phy_blk_addr = -1; - aml_chip->aml_nandenv_info->start_block = vernier; - aml_chip->aml_nandenv_info->end_block = - vernier + NAND_ENV_BLOCK_NUM; - vernier += NAND_ENV_BLOCK_NUM; - aml_chip->aml_nandenv_info->size = CONFIG_ENV_SIZE; - memcpy(aml_chip->aml_nandenv_info->name, ENV_NAND_MAGIC, 4); -#endif - aml_chip->aml_nandkey_info = - kzalloc(sizeof(struct aml_nandrsv_info_t), GFP_KERNEL); - if (aml_chip->aml_nandkey_info == NULL) - return -ENOMEM; - - /*key init*/ - aml_chip->aml_nandkey_info->mtd = mtd; - aml_chip->aml_nandkey_info->valid_node = - kzalloc(sizeof(struct valid_node_t), GFP_KERNEL); - if (aml_chip->aml_nandkey_info->valid_node == NULL) - return -ENOMEM; - - aml_chip->aml_nandkey_info->valid_node->phy_blk_addr = -1; - aml_chip->aml_nandkey_info->start_block = vernier; - aml_chip->aml_nandkey_info->end_block = - vernier + NAND_KEY_BLOCK_NUM; - vernier += NAND_KEY_BLOCK_NUM; - aml_chip->aml_nandkey_info->size = aml_chip->keysize; - memcpy(aml_chip->aml_nandkey_info->name, KEY_NAND_MAGIC, 4); - - aml_chip->aml_nanddtb_info = - kzalloc(sizeof(struct aml_nandrsv_info_t), GFP_KERNEL); - if (aml_chip->aml_nanddtb_info == NULL) - return -ENOMEM; - - /*dtb init*/ - aml_chip->aml_nanddtb_info->mtd = mtd; - aml_chip->aml_nanddtb_info->valid_node = - kzalloc(sizeof(struct valid_node_t), GFP_KERNEL); - if (aml_chip->aml_nanddtb_info->valid_node == NULL) - return -ENOMEM; + memset(aml_chip->block_status, + 0, (mtd->size >> chip->phys_erase_shift)); + + aml_nand_rsv_info_size_fill(mtd); + + for (i = 0; i < ARRAY_SIZE(info); i++) { + rsv_info = &info[i].rsv_info; + ret = aml_nand_rsv_info_alloc_init(mtd, info[i].name, + &rsv_info, + info[i].blocks, + info[i].size); + if (ret) { + printk("%s info alloc init failed\n", info[i].name); + return ret; + } + printk("%s=%d\n", info[i].name, info[i].rsv_info.start_block); + } - aml_chip->aml_nanddtb_info->valid_node->phy_blk_addr = -1; - aml_chip->aml_nanddtb_info->start_block = vernier; - aml_chip->aml_nanddtb_info->end_block = - vernier + NAND_DTB_BLOCK_NUM; - vernier += NAND_DTB_BLOCK_NUM; - aml_chip->aml_nanddtb_info->size = aml_chip->dtbsize; - memcpy(aml_chip->aml_nanddtb_info->name, DTB_NAND_MAGIC, 4); + aml_nand_rsv_info_ptr_fill(mtd); - if ((vernier - (BOOT_TOTAL_PAGES >> pages_per_blk_shift)) > - RESERVED_BLOCK_NUM) { - pr_info("ERROR: total blk number is over the limit\n"); - return -ENOMEM; - } - pr_info("bbt_start=%d ", aml_chip->aml_nandbbt_info->start_block); + printk("bbt_start=%d ", aml_chip->aml_nandbbt_info->start_block); #ifndef CONFIG_ENV_IS_IN_NAND - pr_info("env_start=%d ", aml_chip->aml_nandenv_info->start_block); + printk("env_start=%d ", aml_chip->aml_nandenv_info->start_block); #endif - pr_info("key_start=%d ", aml_chip->aml_nandkey_info->start_block); - pr_info("dtb_start=%d ", aml_chip->aml_nanddtb_info->start_block); - pr_info("\n"); + printk("key_start=%d ", aml_chip->aml_nandkey_info->start_block); + printk("dtb_start=%d ", aml_chip->aml_nanddtb_info->start_block); + printk("ddr_start=%d ", aml_chip->aml_nandddr_info->start_block); + printk("\n"); return 0; } @@ -1043,6 +961,7 @@ int aml_nand_free_rsv_info(struct mtd_info *mtd, return error; } + int aml_nand_scan_rsv_info(struct mtd_info *mtd, struct aml_nandrsv_info_t *nandrsv_info) { @@ -1271,47 +1190,18 @@ RE_RSV_INFO: return ret; } -int aml_nand_env_check(struct mtd_info *mtd) -{ - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - int ret =0; - - ret = aml_nand_scan_rsv_info(mtd, aml_chip->aml_nandenv_info); - if ((ret !=0) && ((ret != (-1)))) - printk("%s %d\n", __func__, __LINE__); - - if (aml_chip->aml_nandenv_info->valid == 0) - printk("%s %d NO env exist\n", __func__, __LINE__); - - return ret; -} - -int aml_nand_key_check(struct mtd_info *mtd) -{ - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - int ret =0; - - ret = aml_nand_scan_rsv_info(mtd, aml_chip->aml_nandkey_info); - if ((ret !=0) && ((ret != (-1)))) - printk("%s %d\n", __func__, __LINE__); - - if (aml_chip->aml_nandkey_info->valid == 0) - printk("%s %d NO key exist\n", __func__, __LINE__); - - return ret; -} - -int aml_nand_dtb_check(struct mtd_info *mtd) +int aml_nand_rsv_info_check_except_bbt(struct mtd_info *mtd) { - struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd); - int ret =0; - - ret = aml_nand_scan_rsv_info(mtd, aml_chip->aml_nanddtb_info); - if ((ret !=0) && ((ret != (-1)))) - printk("%s %d\n", __func__, __LINE__); - - if (aml_chip->aml_nanddtb_info->valid == 0) - printk("%s %d NO dtb exist\n", __func__, __LINE__); + int ret = 0, i; + + for (i = ENV_INFO_INDEX; i < ARRAY_SIZE(info); i++) { + ret = aml_nand_scan_rsv_info(mtd, &info[i].rsv_info); + if (ret !=0 && ret != -1) + printk("%s %d\n", __func__, __LINE__); + if (info[i].rsv_info.valid == 0) + printk("%s %d NO %s exist\n", + __func__, __LINE__, info[i].name); + } return ret; } @@ -1350,7 +1240,8 @@ int aml_nand_bbt_check(struct mtd_info *mtd) memset(aml_chip->block_status, 0, (mtd->size >> phys_erase_shift)); aml_nand_scan_shipped_bbt(mtd); - aml_nand_save_bbt(mtd, (u_char *)buf); + aml_nand_ext_save_rsv_info(mtd, + aml_chip->aml_nandbbt_info, (u_char *)buf); if (aml_chip->nand_bbt_info) kfree(aml_chip->nand_bbt_info); } diff --git a/include/amlogic/aml_mmc.h b/include/amlogic/aml_mmc.h index a684866ba5..6edf90bd84 100644 --- a/include/amlogic/aml_mmc.h +++ b/include/amlogic/aml_mmc.h @@ -19,7 +19,6 @@ #include <common.h> - /* bootloader operation */ #define AML_BL_USER (0x1 << 0) #define AML_BL_BOOT0 (0x1 << 1) @@ -27,6 +26,31 @@ #define AML_BL_BOOT (0x6) #define AML_BL_ALL (0x7) +#define VPART_PROPERTY_SIZE sizeof(struct vpart_property) +struct vpart_property { + u32 addr; + u32 size; +}; + +/* + * sizeof(struct storage_emmc_boot_info) is strictly + * smaller than or equal to one sector. we will bind + * it in one sector with u-boot.bin together and + * write into boot loader area. + * @rsv_base_addr : the sector address of reserved area + * @dtb : the sector address and size of dtb property + * @ddr : the sector address and size of ddr property + */ +#define EMMC_BOOT_INFO_SIZE 512 +struct storage_emmc_boot_info { + u32 version; + u32 rsv_base_addr; + struct vpart_property dtb; + struct vpart_property ddr; + u8 reserved[512 - 2 * VPART_PROPERTY_SIZE - 12]; + u32 checksum; +}; + int amlmmc_write_bootloader(int dev, int map, unsigned int size, const void *src); int amlmmc_erase_bootloader(int dev, int map); @@ -56,7 +80,4 @@ int emmc_update_mbr(unsigned char *buffer); /*mmc ext_csd register operation*/ int mmc_get_ext_csd(struct mmc *mmc, u8 *ext_csd); int mmc_set_ext_csd(struct mmc *mmc, u8 index, u8 value); - - - #endif /* __AML_MMC_H__ */ diff --git a/include/emmc_partitions.h b/include/emmc_partitions.h index fe60a3fd5b..72830ebd32 100644 --- a/include/emmc_partitions.h +++ b/include/emmc_partitions.h @@ -99,6 +99,11 @@ #define RANDOM_SIZE (256 * 512) #define RANDOM_BLOCK_SIZE (512) #define RANDOM_PATTERN (0X52414E44) + +#define MMC_DDR_PARAMETER_NAME "ddr-parameter" +#define DDR_PARAMETER_OFFSET (SZ_1M * 8) +#define DDR_PARAMETER_SIZE (4 * 512) + /* * 2 copies dtb were stored in dtb area. * each is 256K. @@ -254,6 +259,7 @@ int mmc_boot_size(char *name, uint64_t* size); struct virtual_partition *aml_get_virtual_partition_by_name(const char *name); bool aml_is_emmc_tsd (struct mmc *mmc); int mmc_device_init (struct mmc *mmc); +ulong _get_inherent_offset(const char *name); #define PARTITION_ELEMENT(na, sz, flags) {.name = na, .size = sz, .mask_flags = flags,} |