/*
 * (C) Copyright 2003
 * Kyle Harris, kharris@nexus-tech.net
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <malloc.h>
#include <command.h>
#include <linux/ctype.h>
#include <mmc.h>
#include <partition_table.h>
#include <emmc_partitions.h>
#include <asm/arch/cpu_sdio.h>
#include <asm/arch/sd_emmc.h>
#include <linux/sizes.h>
#include <asm/cpu_id.h>

extern int mmc_key_erase(void);
extern int find_dev_num_by_partition_name (char *name);
extern int mmc_get_ext_csd(struct mmc *mmc, u8 *ext_csd);
extern int mmc_set_ext_csd(struct mmc *mmc, u8 index, u8 value);
extern void mmc_write_cali_mattern(void *addr);

/* info system. */
#define dtb_err(fmt, ...) printf( "%s()-%d: " fmt , \
                  __func__, __LINE__, ##__VA_ARGS__)

#define dtb_wrn(fmt, ...) printf( "%s()-%d: " fmt , \
                  __func__, __LINE__, ##__VA_ARGS__)

/* for detail debug info */
#define dtb_info(fmt, ...) printf( "%s()-%d: " fmt , \
                  __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;
};

struct aml_dtb_info {
	u32 stamp[2];
	u8 valid[2];
};

#define stamp_after(a,b)   ((int)(b) - (int)(a)  < 0)
/* glb dtb infos */
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)
#endif

#define GXB_START_BLK   0
#define GXL_START_BLK   1
#define UBOOT_SIZE  (0x1000) // uboot size  2MB
int info_disprotect = 0;
bool emmckey_is_protected (struct mmc *mmc)
{
#ifdef CONFIG_STORE_COMPATIBLE
#ifdef CONFIG_SECURITYKEY
    if (info_disprotect & DISPROTECT_KEY) { // disprotect
        printf("emmckey_is_protected : disprotect\n ");
        return 0;
    }else{
        printf("emmckey_is_protected : protect\n ");
    // protect
        return 1;
    }
#else
        return 0;
#endif
#else
#ifdef CONFIG_SECURITYKEY
        //return mmc->key_protect;
        return 0; /* fixme, */
#else
        return 0;
#endif
#endif
}

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;
}


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;
}

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;
}

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;
}


int do_amlmmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
        int rc = 0;
        /*printf("%s:%d\n",__func__,__LINE__);*/
        /*printf("argc = %d\n",argc);*/
        switch (argc) {
                case 3:
                        if (strcmp(argv[1], "rescan") == 0) {
                                int dev = simple_strtoul(argv[2], NULL, 10);
                                if (dev < 0) {
                                        printf("Cannot find dev.\n");
                                        return 1;
                                }
                                struct mmc *mmc = find_mmc_device(dev);

                                if (!mmc)
                                        return 1;

                                return mmc_init(mmc);
                        } else if (strncmp(argv[1], "part", 4) == 0) {
                                int dev = simple_strtoul(argv[2], NULL, 10);
                                block_dev_desc_t *mmc_dev;
                                struct mmc *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;
                        } else if (strcmp(argv[1], "erase") == 0) {
                                char *name = NULL;
                                int dev;
                                u32 n=0;
                                bool is_part = false;//is argv[2] partition name
                                bool protect_cache = false;
                                bool non_loader = false;
                                int blk_shift;
                                u64 cnt=0, blk =0,start_blk =0;
                                struct partitions *part_info;

                                if (isstring(argv[2])) {
                                        if (!strcmp(argv[2], "whole")) {
                                                name = "logo";
                                                dev = find_dev_num_by_partition_name (name);
                                        }else if(!strcmp(argv[2], "non_cache")){
                                                name = "logo";
                                                dev = find_dev_num_by_partition_name (name);
                                                protect_cache = true;
                                        }
                                        else if(!strcmp(argv[2], "non_loader")){
                                                dev = 1;
                                                non_loader = true;
                                        }
                                        else{
                                                name = argv[2];
                                                dev = find_dev_num_by_partition_name (name);
                                                is_part = true;
                                        }
                                }else if(isdigit(argv[2][0])){
                                        dev = simple_strtoul(argv[2], NULL, 10);
                                }else{
                                        printf("Input is invalid, nothing happen.\n");
                                        return 1;
                                }

                                if (dev < 0) {
                                        printf("Cannot find dev.\n");
                                        return 1;
                                }
                                struct mmc *mmc = find_mmc_device(dev);

                                if (!mmc)
                                        return 1;

                                mmc_init(mmc);

                                blk_shift = ffs(mmc->read_bl_len) -1;
                                if (is_part) { // erase only one partition
                                        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);
                                } else { // erase the whole card if possible

                                        if (non_loader) {
                                                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;
                                                }
                                        }
                                        else{
                                                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;
                                                if (blk > 0) { // it means: there should be other partitions before reserve-partition.
                                                        blk -= PARTITION_RESERVED;
                                                }
                                                blk >>= blk_shift;
                                                blk -= start_blk;

                                                n=0;

                                                // (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
                                                        if (protect_cache) {
                                                                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) - 1 - start_blk;
                                                        n = mmc->block_dev.block_erase(dev, start_blk, erase_cnt);
                                                        // printf("(2) erase blk: %#llx --> %#llx %s\n", start_blk, start_blk+erase_cnt, (n == 0) ? "OK" : "ERROR");
                                                }

                                        } else {
                                                n = mmc->block_dev.block_erase(dev, start_blk, 0); // erase the whole card
                                        }

                                        //erase boot partition
                                        if (mmc->boot_size && (n == 0) && (non_loader == false)) {

                                                for (cnt=0;cnt<2;cnt++) {
                                                        rc = mmc_switch_part(dev, cnt+1);
                                                        if (rc != 0) {
                                                                printf("mmc switch %s failed\n", (cnt == 0)?"boot0":"boot1");
                                                                break;
                                                        }

                                                        n = mmc->block_dev.block_erase(dev, 0, mmc->boot_size>>blk_shift);
                                                        if (n != 0) {
                                                                printf("mmc erase %s failed\n", (cnt == 0)?"boot0":"boot1");
                                                                break;
                                                        }
                                                }

                                                rc = mmc_switch_part(dev, 0);
                                                if (rc != 0) {
                                                        printf("mmc switch back to user failed\n");
                                                }
                                        }
                                }

                                // printf("dev # %d, %s, # %#llx blocks erased %s\n",
                                // dev, (is_part == 0) ? "card":(argv[2]) ,
                                // (cnt == 0) ? (int)(mmc->block_dev.lba): cnt ,
                                // (n == 0) ? "OK" : "ERROR");
                                return (n == 0) ? 0 : 1;
                        } else if (strcmp(argv[1], "status") == 0) {
                            int dev = simple_strtoul(argv[2], NULL, 10);
                            if (dev < 0) {
                                printf("Cannot find dev.\n");
                                return 1;
                            }
                            struct mmc *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;
                        } else if (strcmp(argv[1], "response") == 0) {
                            int dev = simple_strtoul(argv[2], NULL, 10);
                            if (dev < 0) {
                                printf("Cannot find dev.\n");
                                return 1;
                            }
                            struct mmc *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;
                            }
                            struct aml_card_sd_info *aml_priv = mmc->priv;
                            struct sd_emmc_global_regs *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;
                        } else if (strcmp(argv[1], "controller") == 0) {
                            int dev = simple_strtoul(argv[2], NULL, 10);
                            if (dev < 0) {
                                printf("Cannot find dev.\n");
                                return 1;
                            }
                            struct mmc *mmc = find_mmc_device(dev);
                            if (!mmc)
                                return 1;
                            struct aml_card_sd_info *aml_priv = mmc->priv;
                            struct sd_emmc_global_regs *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;
                        } else {
                                return cmd_usage(cmdtp);
                        }

                case 0:
                case 1:
                        return CMD_RET_USAGE;
                case 4:
                        if (strcmp(argv[1], "switch") == 0) {
                                int dev = simple_strtoul(argv[2], NULL, 10);
                                struct mmc* 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");
                                        }
                                }
#endif
                                else
                                        printf("%s failed\n", argv[3]);
                                return rc;
                        } else if (strcmp(argv[1], "ext_csd") == 0) {
                            int ret;
                            u8 ext_csd[512] = {0};
                            int dev = simple_strtoul(argv[2], NULL, 10);
                            int bit = simple_strtoul(argv[3], NULL, 10);
                            if ((bit > 511) || (bit < 0)) {
                                printf("bit is out of area!\n");
                                return 1;
                            }
                            struct mmc* 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 bit[%d] val[0x%x] %s\n",
                                    bit, ext_csd[bit], (ret == 0) ? "ok" : "fail");
                            return ret;
                        } else if (strcmp(argv[1], "size") == 0) {
                            char *name;
                            uint64_t* addr =NULL;
                            name = argv[2];
                            addr = (uint64_t *)simple_strtoul(argv[3], NULL, 16);
                            if (!strcmp(name, "wholeDev")) {
                                int dev = CONFIG_SYS_MMC_BOOT_DEV;
                                struct mmc* 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);
                        }
                        return cmd_usage(cmdtp);

                case 2:
                        if (!strcmp(argv[1], "list")) {
                                print_mmc_devices('\n');
                                return 0;
                        }

                        if (strcmp(argv[1], "env") == 0) {
                                printf("herh\n");
                                env_relocate();
                                return 0 ;
                        }

#ifdef CONFIG_SECURITYKEY
                        if (strcmp(argv[1], "key") == 0) {
                                struct mmc* mmc;
                                //char *name = "logo";
                                int 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");
#endif
                                return 0;
                        }
#endif
                        return cmd_usage(cmdtp);

                default: /* at least 5 args */
                        if (strcmp(argv[1], "read") == 0) {
                                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;

                                if (argc != 6) {
                                        printf("Input is invalid, nothing happen.\n");
                                        return 1;
                                }

                                if (isstring(argv[2])) {
                                        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);
                                        /*printf("offset %llx size %llx\n",offset,size);*/
                                        flag = 1;
                                        if ((strcmp(argv[2], "card") == 0)) {
                                                flag = 2;
                                        }
                                }else{
                                        dev = simple_strtoul(argv[2], NULL, 10);
                                        addr = (void *)simple_strtoul(argv[3], NULL, 16);
                                        cnt = simple_strtoull(argv[5], NULL, 16);
                                        blk = simple_strtoull(argv[4], NULL, 16);
                                }
                                if (dev < 0) {
                                        printf("Cannot find dev.\n");
                                        return 1;
                                }
                                struct mmc *mmc = find_mmc_device(dev);
                                if (!mmc) {
                                        printf("dev = %d;, no mmc device found",dev);
                                        return 1;
                                }

                                if (flag == 1) { // emmc or tsd
                                        /*printf("offset %#llx size %#llx\n",offset,size);*/
                                        get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte);
                                }
                                else if(flag == 2){ // card
                                        int blk_shift = ffs( mmc->read_bl_len) -1;
                                        cnt = size >> blk_shift;
                                        blk = offset >> blk_shift;
                                        sz_byte = size - (cnt<<blk_shift);
                                }


                                /*printf("MMC read: dev # %d, block # %#llx, count # %#llx ...\n",*/
                                                /*dev, blk, cnt);*/
                                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);*/
                                        void *addr_tmp = malloc(mmc->read_bl_len);
                                        void *addr_byte = (void *)(addr+cnt*(mmc->read_bl_len));
                                        ulong 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);
                                }

                                /* flush cache after read */
                                //flush_cache((ulong)addr, cnt * 512); /* FIXME */

                                //printf("MMC read: dev # %d, block # %#llx, count # %#llx, byte_size # %#llx %s!\n",
                                //                        dev, blk, cnt, sz_byte, (n==cnt) ? "OK" : "ERROR");
                                return (n == cnt) ? 0 : 1;
                        } else if (strcmp(argv[1], "write") == 0) {
                                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;
                                cpu_id_t cpu_id = get_cpu_id();
                                if (argc != 6) {
                                        printf("Input is invalid, nothing happen.\n");
                                        return 1;
                                }

                                if (isstring(argv[2])) {
                                        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);
                                        flag = 1;
                                        if ((strcmp(argv[2], "card") == 0)) {
                                            flag = 2;
                                        }
                                }else{
                                        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;
                                }
                                struct mmc *mmc = find_mmc_device(dev);

                                if (flag == 1) { // tsd or emmc
                                        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;
                                            sz_byte = 0;
                                        } else
                                            get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte);
                                }
                                else if(flag == 2){ // card
                                        int blk_shift = ffs( mmc->read_bl_len) -1;
                                        cnt = size >> blk_shift;
                                        blk = offset >> blk_shift;
                                        sz_byte = size - (cnt<<blk_shift);
                                }

                                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);

                                //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;
                        }
                        else if (strcmp(argv[1], "erase") == 0) {

                                int dev=0;
                                u32 flag=0;
                                u64 cnt = 0, blk = 0, n = 0, sz_byte =0;
                                char *name=NULL;
                                u64 offset_addr =0, size=0;

                                if (argc != 5) {
                                        printf("Input is invalid, nothing happen.\n");
                                        return 1;
                                }

                                if (isstring(argv[2])) {
                                        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);
                                        flag = 1;
                                        if ((strcmp(argv[2], "card") == 0)) {
                                                flag = 2;
                                        }
                                }else if(isdigit(argv[2][0])){
                                        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;
                                }

                                struct mmc *mmc = find_mmc_device(dev);

                                if (flag == 1) { // mmc write logo add offset size
                                        struct partitions *part_info  = find_mmc_partition_by_name(name);

                                        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);
                                }
                                else if(flag == 2){
                                        int tmp_shift = ffs( mmc->read_bl_len) -1;
                                        cnt = size >> tmp_shift;
                                        blk = offset_addr >> tmp_shift;
                                        sz_byte = size - (cnt<<tmp_shift);
                                }

                                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, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR");

                                return (n == 0) ? 0 : 1;

                        } else if (strcmp(argv[1], "ext_csd") == 0) {
                            int ret;
                            int dev = simple_strtoul(argv[2], NULL, 10);
                            int bit = simple_strtoul(argv[3], NULL, 10);
                            int val = simple_strtoul(argv[4], NULL, 16);
                            if ((bit > 191) || (bit < 0)) {
                                printf("bit is not able to write!\n");
                                return 1;
                            }
                            struct mmc* mmc = find_mmc_device(dev);
                            if (!mmc) {
                                puts("no mmc devices available\n");
                                return 1;
                            }
                            mmc_init(mmc);
                            ret = mmc_set_ext_csd(mmc, bit, val);
                            printf("write EXT_CSD bit[%d] val[0x%x] %s\n",
                                    bit, val, (ret == 0) ? "ok" : "fail");
                            return ret;

                        } else
                                rc = cmd_usage(cmdtp);

                        return rc;
        }
}

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 switch <device_num> <part name> - part name : boot0, boot1, user\n"
    "amlmmc status <device_num> - read sd/emmc device status\n"
    "amlmmc ext_csd <bit> <value> - read/write sd/emmc device EXT_CSD [bit] value\n"
    "amlmmc response <device_num> - read sd/emmc last command response\n"
    "amlmmc controller <device_num> - read sd/emmc controller register\n");

/* 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;

	if ((u64)dtb % 4 != 0) {
        BUG();
    }

    size = size >> 2;
    buffer = (u32*) dtb;
	while (i < size)
        checksum += buffer[i++];

    return checksum;
}

static int _verify_dtb_checksum(struct aml_dtb_rsv * dtb)
{
    u32 checksum;

    checksum = _calc_dtb_checksum(dtb);
    dtb_info("calc %x, store %x\n", 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);
}
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);
}

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;
}

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;
}

int dtb_read(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 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;

	if (0 == dtb_read_shortcut(mmc, addr))
        return ret;

    /* read dtb2 1st, for compatibility without checksum. */
	while (cpy >= 0) {
		blk = (dtb_glb_offset + cpy * (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);
        } 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 --;
    }
    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:
			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;
            }
        break;
        /* both are valid, pickup new one. */
        case 2:
			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");
            }
        break;
        default:
            dtb_err("impossble valid values.\n");
            BUG();
        break;
    }

_out:
    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;
}

extern int check_valid_dts(unsigned char *buffer);
int renew_partition_tbl(unsigned char *buffer)
{
    int ret = 0;
    /* todo, check new dts imcoming.... */
    ret = check_valid_dts(buffer);
    /* 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;
}

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;
                    }
                    addr = (void *)malloc(CALI_PATTERN_SIZE);
                    mmc_write_cali_mattern(addr);
                    vpart = aml_get_virtual_partition_by_name(MMC_PATTERN_NAME);
                    part = aml_get_partition_by_name(MMC_RESERVED_NAME);
                    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 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;
    }
#ifndef DTB_BIND_KERNEL
    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");
_out:
    return ret;
}

U_BOOT_CMD(
    emmc, 4, 1, do_amlmmc_dtb_key,
    "EMMC sub system",
    "emmc dtb_read addr size\n"
    "emmc dtb_write addr size\n"
    "emmc erase dtb\n"
    "emmc erase key\n");
