mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
v1.0.2 fix fitimage issue
This commit is contained in:
@@ -64,12 +64,15 @@ static int do_nand_boot(int argc, char *argv[])
|
|||||||
|
|
||||||
info.dev = (void *)mtd;
|
info.dev = (void *)mtd;
|
||||||
info.bl_len = mtd->writesize;
|
info.bl_len = mtd->writesize;
|
||||||
|
info.dev_type = DEVICE_SPINAND;
|
||||||
|
|
||||||
spl_load_simple_fit(&info, &entry_point);
|
ret = spl_load_simple_fit(&info, &entry_point);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
boot_app((void *)entry_point);
|
boot_app((void *)entry_point);
|
||||||
|
|
||||||
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,15 @@ static int do_nor_boot(int argc, char *argv[])
|
|||||||
|
|
||||||
info.dev = (void *)mtd;
|
info.dev = (void *)mtd;
|
||||||
info.bl_len = 1;
|
info.bl_len = 1;
|
||||||
|
info.dev_type = DEVICE_SPINOR;
|
||||||
|
|
||||||
spl_load_simple_fit(&info, &entry_point);
|
ret = spl_load_simple_fit(&info, &entry_point);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
boot_app((void *)entry_point);
|
boot_app((void *)entry_point);
|
||||||
|
|
||||||
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static s32 nand_fwc_get_mtd_partitions(struct fwc_info *fwc,
|
|||||||
priv->nftl_handler[idx]->nandt->block_start = priv->mtd[idx]->start / priv->mtd[idx]->erasesize;
|
priv->nftl_handler[idx]->nandt->block_start = priv->mtd[idx]->start / priv->mtd[idx]->erasesize;
|
||||||
priv->nftl_handler[idx]->nandt->block_end = (priv->mtd[idx]->start + priv->mtd[idx]->size) / priv->mtd[idx]->erasesize;
|
priv->nftl_handler[idx]->nandt->block_end = (priv->mtd[idx]->start + priv->mtd[idx]->size) / priv->mtd[idx]->erasesize;
|
||||||
|
|
||||||
for (int offset_e = priv->mtd[idx]->start; offset_e < priv->mtd[idx]->start + priv->mtd[idx]->size;) {
|
for (int offset_e = 0; offset_e < priv->mtd[idx]->size;) {
|
||||||
mtd_erase(priv->mtd[idx], offset_e, priv->mtd[idx]->erasesize);
|
mtd_erase(priv->mtd[idx], offset_e, priv->mtd[idx]->erasesize);
|
||||||
offset_e += priv->mtd[idx]->erasesize;
|
offset_e += priv->mtd[idx]->erasesize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ static int mtd_spinand_read_oob(struct mtd_dev *mtd, u32 offset, u8 *data,
|
|||||||
flash = (struct aic_spinand *)mtd->priv;
|
flash = (struct aic_spinand *)mtd->priv;
|
||||||
|
|
||||||
if (offset % flash->info->page_size) {
|
if (offset % flash->info->page_size) {
|
||||||
printf("Offset not aligned with a page (0x%x)\r\n",
|
pr_err("Offset not aligned with a page (0x%x)\r\n",
|
||||||
flash->info->page_size);
|
flash->info->page_size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mtd->size - offset) < flash->info->page_size) {
|
if ((mtd->size - offset) < flash->info->page_size) {
|
||||||
printf("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
pr_err("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +75,7 @@ static int mtd_spinand_erase(struct mtd_dev *mtd, u32 offset, u32 len)
|
|||||||
u8 err;
|
u8 err;
|
||||||
u32 start, dolen;
|
u32 start, dolen;
|
||||||
struct aic_spinand *flash;
|
struct aic_spinand *flash;
|
||||||
|
u32 flash_size = 0;
|
||||||
|
|
||||||
if (!mtd)
|
if (!mtd)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -87,6 +88,14 @@ static int mtd_spinand_erase(struct mtd_dev *mtd, u32 offset, u32 len)
|
|||||||
if ((mtd->size - offset) < dolen)
|
if ((mtd->size - offset) < dolen)
|
||||||
dolen = mtd->size - offset;
|
dolen = mtd->size - offset;
|
||||||
|
|
||||||
|
flash_size = flash->info->page_size * flash->info->pages_per_eraseblock *
|
||||||
|
flash->info->block_per_lun;
|
||||||
|
if ((start + dolen) > flash_size) {
|
||||||
|
pr_err("Erase range 0x%x out of flash capacity 0x%x!\n", start + dolen,
|
||||||
|
flash_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
err = spinand_erase(flash, start, dolen);
|
err = spinand_erase(flash, start, dolen);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -107,12 +116,12 @@ static int mtd_spinand_block_isbad(struct mtd_dev *mtd, u32 offset)
|
|||||||
blocksize = flash->info->page_size * flash->info->pages_per_eraseblock;
|
blocksize = flash->info->page_size * flash->info->pages_per_eraseblock;
|
||||||
|
|
||||||
if (offset % blocksize) {
|
if (offset % blocksize) {
|
||||||
printf("Offset not aligned with a block (0x%x)\r\n", blocksize);
|
pr_err("Offset not aligned with a block (0x%x)\r\n", blocksize);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mtd->size - offset) < blocksize) {
|
if ((mtd->size - offset) < blocksize) {
|
||||||
printf("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
pr_err("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +130,7 @@ static int mtd_spinand_block_isbad(struct mtd_dev *mtd, u32 offset)
|
|||||||
|
|
||||||
err = spinand_block_isbad(flash, blk);
|
err = spinand_block_isbad(flash, blk);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
printf("Block %d is bad.\n", blk);
|
pr_err("Block %d is bad.\n", blk);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -142,12 +151,12 @@ static int mtd_spinand_block_markbad(struct mtd_dev *mtd, u32 offset)
|
|||||||
blocksize = flash->info->page_size * flash->info->pages_per_eraseblock;
|
blocksize = flash->info->page_size * flash->info->pages_per_eraseblock;
|
||||||
|
|
||||||
if (offset % blocksize) {
|
if (offset % blocksize) {
|
||||||
printf("Offset not aligned with a block (0x%x)\r\n", blocksize);
|
pr_err("Offset not aligned with a block (0x%x)\r\n", blocksize);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mtd->size - offset) < blocksize) {
|
if ((mtd->size - offset) < blocksize) {
|
||||||
printf("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
pr_err("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +165,7 @@ static int mtd_spinand_block_markbad(struct mtd_dev *mtd, u32 offset)
|
|||||||
|
|
||||||
err = spinand_block_markbad(flash, blk);
|
err = spinand_block_markbad(flash, blk);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
printf("Mark badblock %d failed.\n",blk);
|
pr_err("Mark badblock %d failed.\n", blk);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -196,13 +205,13 @@ static int mtd_spinand_write_oob(struct mtd_dev *mtd, u32 offset, u8 *data,
|
|||||||
flash = (struct aic_spinand *)mtd->priv;
|
flash = (struct aic_spinand *)mtd->priv;
|
||||||
|
|
||||||
if (offset % flash->info->page_size) {
|
if (offset % flash->info->page_size) {
|
||||||
printf("Offset not aligned with a page (0x%x)\r\n",
|
pr_err("Offset not aligned with a page (0x%x)\r\n",
|
||||||
flash->info->page_size);
|
flash->info->page_size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mtd->size - offset) < flash->info->page_size) {
|
if ((mtd->size - offset) < flash->info->page_size) {
|
||||||
printf("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
pr_err("Offset: 0x%x is out of mtd size: 0x%lx.\n", offset, mtd->size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +269,8 @@ static char *aic_spinand_get_partition_string(struct mtd_dev *mtd)
|
|||||||
parts = strdup(parts);
|
parts = strdup(parts);
|
||||||
#else
|
#else
|
||||||
void *res_addr = NULL;
|
void *res_addr = NULL;
|
||||||
res_addr = aic_get_boot_resource_from_nand(mtd, mtd->writesize, nand_read_data);
|
res_addr =
|
||||||
|
aic_get_boot_resource_from_nand(mtd, mtd->writesize, nand_read_data);
|
||||||
parts = private_get_partition_string(res_addr);
|
parts = private_get_partition_string(res_addr);
|
||||||
if (parts == NULL)
|
if (parts == NULL)
|
||||||
parts = IMAGE_CFG_JSON_PARTS_MTD;
|
parts = IMAGE_CFG_JSON_PARTS_MTD;
|
||||||
@@ -303,7 +313,7 @@ struct aic_spinand *spinand_probe(u32 spi_bus)
|
|||||||
|
|
||||||
err = spinand_flash_init(flash);
|
err = spinand_flash_init(flash);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
printf("Failed to probe spinand flash.\n");
|
pr_err("Failed to probe spinand flash.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ struct nand_bbt {
|
|||||||
u8 *cache;
|
u8 *cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct aic_spinand;
|
||||||
|
|
||||||
/* SPI NAND flash information */
|
/* SPI NAND flash information */
|
||||||
struct aic_spinand_info {
|
struct aic_spinand_info {
|
||||||
u32 devid;
|
u32 devid;
|
||||||
@@ -44,6 +46,7 @@ struct aic_spinand_info {
|
|||||||
u8 is_die_select;
|
u8 is_die_select;
|
||||||
const char *sz_description;
|
const char *sz_description;
|
||||||
struct spi_nand_cmd_cfg *cmd;
|
struct spi_nand_cmd_cfg *cmd;
|
||||||
|
int (*get_status)(struct aic_spinand *flash, u8 status);
|
||||||
};
|
};
|
||||||
typedef struct aic_spinand_info *aic_spinand_info_t;
|
typedef struct aic_spinand_info *aic_spinand_info_t;
|
||||||
|
|
||||||
@@ -179,9 +182,10 @@ struct spi_nand_cmd_cfg {
|
|||||||
#define STATUS_BUSY BIT(0)
|
#define STATUS_BUSY BIT(0)
|
||||||
#define STATUS_ERASE_FAILED BIT(2)
|
#define STATUS_ERASE_FAILED BIT(2)
|
||||||
#define STATUS_PROG_FAILED BIT(3)
|
#define STATUS_PROG_FAILED BIT(3)
|
||||||
|
|
||||||
#define STATUS_ECC_MASK GENMASK(5, 4)
|
#define STATUS_ECC_MASK GENMASK(5, 4)
|
||||||
#define STATUS_ECC_NO_BITFLIPS (0 << 4)
|
#define STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||||
#define STATUS_ECC_HAS_BITFLIPS (1 << 4)
|
#define STATUS_ECC_HAS_1_4_BITFLIPS (1 << 4)
|
||||||
#define STATUS_ECC_UNCOR_ERROR (2 << 4)
|
#define STATUS_ECC_UNCOR_ERROR (2 << 4)
|
||||||
|
|
||||||
#ifdef SPI_NAND_WINBOND
|
#ifdef SPI_NAND_WINBOND
|
||||||
|
|||||||
@@ -138,6 +138,27 @@ int spinand_read_cfg(struct aic_spinand *flash, u8 *cfg)
|
|||||||
return spinand_read_reg_op(flash, REG_CFG, cfg);
|
return spinand_read_reg_op(flash, REG_CFG, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spinand_check_ecc_status(struct aic_spinand *flash, u8 status)
|
||||||
|
{
|
||||||
|
if (flash->info->get_status) {
|
||||||
|
return flash->info->get_status(flash, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status & STATUS_ECC_MASK) {
|
||||||
|
case STATUS_ECC_NO_BITFLIPS:
|
||||||
|
return 0;
|
||||||
|
case STATUS_ECC_HAS_1_4_BITFLIPS:
|
||||||
|
return 4;
|
||||||
|
case STATUS_ECC_UNCOR_ERROR:
|
||||||
|
return -SPINAND_ERR_ECC;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -SPINAND_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
int spinand_isbusy(struct aic_spinand *flash, u8 *status)
|
int spinand_isbusy(struct aic_spinand *flash, u8 *status)
|
||||||
{
|
{
|
||||||
u8 SR = 0xFF;
|
u8 SR = 0xFF;
|
||||||
@@ -495,11 +516,13 @@ int spinand_read_page(struct aic_spinand *flash, u32 page, u8 *data,
|
|||||||
goto exit_spinand_read_page;
|
goto exit_spinand_read_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = (status & 0x30) >> 4;
|
result = spinand_check_ecc_status(flash, status);
|
||||||
if ((status > 0x01)) {
|
if (result < 0) {
|
||||||
result = -SPINAND_ERR_ECC;
|
|
||||||
pr_err("Error ECC status error[0x%x].\n", status);
|
pr_err("Error ECC status error[0x%x].\n", status);
|
||||||
goto exit_spinand_read_page;
|
goto exit_spinand_read_page;
|
||||||
|
} else if (result > 0) {
|
||||||
|
pr_debug("with %d bit/page ECC corrections, status : [0x%x].\n", result,
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data && data_len) {
|
if (data && data_len) {
|
||||||
@@ -658,11 +681,14 @@ int spinand_continuous_read(struct aic_spinand *flash, u32 page, u8 *data,
|
|||||||
goto exit_spinand_continuous_read;
|
goto exit_spinand_continuous_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = (status & 0x30) >> 4;
|
result = spinand_check_ecc_status(flash, status);
|
||||||
if ((status > 0x01)) {
|
if (result < 0) {
|
||||||
result = -SPINAND_ERR_ECC;
|
result = -SPINAND_ERR_ECC;
|
||||||
pr_err("Error ECC status error[0x%x].\n", status);
|
pr_err("Error ECC status error[0x%x].\n", status);
|
||||||
goto exit_spinand_continuous_read;
|
goto exit_spinand_continuous_read;
|
||||||
|
} else if (result > 0) {
|
||||||
|
pr_debug("with %d bit/page ECC corrections, status : [0x%x].\n", result,
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = spinand_read_from_cache_cont_op(flash, data, size);
|
result = spinand_read_from_cache_cont_op(flash, data, size);
|
||||||
@@ -760,11 +786,13 @@ int spinand_write_page(struct aic_spinand *flash, u32 page, const u8 *data,
|
|||||||
goto exit_spinand_write_page;
|
goto exit_spinand_write_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = (status & 0x30) >> 4;
|
result = spinand_check_ecc_status(flash, status);
|
||||||
if ((status > 0x01)) {
|
if (result < 0) {
|
||||||
result = -SPINAND_ERR_ECC;
|
|
||||||
pr_err("Error ECC status error[0x%x].\n", status);
|
pr_err("Error ECC status error[0x%x].\n", status);
|
||||||
goto exit_spinand_write_page;
|
goto exit_spinand_write_page;
|
||||||
|
} else if (result > 0) {
|
||||||
|
pr_debug("with %d bit/page ECC corrections, status : [0x%x].\n", result,
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = SPINAND_SUCCESS;
|
result = SPINAND_SUCCESS;
|
||||||
@@ -796,27 +824,25 @@ int spinand_block_markbad(struct aic_spinand *flash, u16 blk)
|
|||||||
return spinand_write_page(flash, page, NULL, 0, &badblockmarker, 1);
|
return spinand_write_page(flash, page, NULL, 0, &badblockmarker, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define READ_DATE_OFFSET_ALIGN 1
|
||||||
|
#define READ_DATE_OFFSET_UNALIGN 2
|
||||||
|
|
||||||
int spinand_read(struct aic_spinand *flash, u8 *addr, u32 offset, u32 size)
|
int spinand_read(struct aic_spinand *flash, u8 *addr, u32 offset, u32 size)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u32 page, cplen;
|
u32 page, cplen;
|
||||||
u32 off = offset;
|
u32 off = offset;
|
||||||
u8 *buf = NULL, *p, copy_flag;
|
u8 *buf = NULL, *p, copy_flag = 0;
|
||||||
u32 remaining = size;
|
u32 remaining = size;
|
||||||
u16 blk;
|
u16 blk;
|
||||||
u32 blk_size;
|
u32 blk_size;
|
||||||
|
u32 off_in_page = 0;
|
||||||
|
|
||||||
if (!flash) {
|
if (!flash) {
|
||||||
pr_err("flash is NULL\r\n");
|
pr_err("flash is NULL\r\n");
|
||||||
return -SPINAND_ERR;
|
return -SPINAND_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset % flash->info->page_size) {
|
|
||||||
pr_err("Offset not aligned with a page (0x%x)\r\n",
|
|
||||||
flash->info->page_size);
|
|
||||||
return -SPINAND_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = malloc(flash->info->page_size + flash->info->oob_size);
|
buf = malloc(flash->info->page_size + flash->info->oob_size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
pr_err("Failed to malloc spinand buf.\n");
|
pr_err("Failed to malloc spinand buf.\n");
|
||||||
@@ -835,12 +861,19 @@ int spinand_read(struct aic_spinand *flash, u8 *addr, u32 offset, u32 size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
|
if (off % flash->info->page_size == 0) {
|
||||||
if (remaining >= flash->info->page_size) {
|
if (remaining >= flash->info->page_size) {
|
||||||
p = addr;
|
p = addr;
|
||||||
copy_flag = 0;
|
copy_flag = 0;
|
||||||
} else {
|
} else {
|
||||||
p = buf;
|
p = buf;
|
||||||
copy_flag = 1;
|
copy_flag = READ_DATE_OFFSET_UNALIGN;
|
||||||
|
memset(buf, 0xFF, flash->info->page_size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p = buf;
|
||||||
|
copy_flag = READ_DATE_OFFSET_ALIGN;
|
||||||
|
memset(buf, 0xFF, flash->info->page_size);
|
||||||
}
|
}
|
||||||
page = off / flash->info->page_size;
|
page = off / flash->info->page_size;
|
||||||
|
|
||||||
@@ -850,10 +883,22 @@ int spinand_read(struct aic_spinand *flash, u8 *addr, u32 offset, u32 size)
|
|||||||
goto exit_spinand_read;
|
goto exit_spinand_read;
|
||||||
|
|
||||||
cplen = flash->info->page_size;
|
cplen = flash->info->page_size;
|
||||||
if (remaining < cplen)
|
|
||||||
|
if (copy_flag == READ_DATE_OFFSET_ALIGN) {
|
||||||
|
/*Misaligned offset with page address*/
|
||||||
|
off_in_page = off % flash->info->page_size;
|
||||||
|
if (remaining <= flash->info->page_size - off_in_page) {
|
||||||
|
cplen = remaining;
|
||||||
|
} else {
|
||||||
|
cplen = flash->info->page_size - off_in_page;
|
||||||
|
}
|
||||||
|
memcpy(addr, buf + off_in_page, cplen);
|
||||||
|
} else if (copy_flag == READ_DATE_OFFSET_UNALIGN) {
|
||||||
|
/*Align offset with page address*/
|
||||||
cplen = remaining;
|
cplen = remaining;
|
||||||
if (copy_flag)
|
|
||||||
memcpy(addr, buf, cplen);
|
memcpy(addr, buf, cplen);
|
||||||
|
}
|
||||||
|
|
||||||
remaining -= cplen;
|
remaining -= cplen;
|
||||||
off += cplen;
|
off += cplen;
|
||||||
addr += cplen;
|
addr += cplen;
|
||||||
|
|||||||
Reference in New Issue
Block a user