mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-13 09:58:54 +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.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);
|
||||
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,11 +63,15 @@ static int do_nor_boot(int argc, char *argv[])
|
||||
|
||||
info.dev = (void *)mtd;
|
||||
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);
|
||||
|
||||
out:
|
||||
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_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);
|
||||
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;
|
||||
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ static int mtd_spinand_erase(struct mtd_dev *mtd, u32 offset, u32 len)
|
||||
u8 err;
|
||||
u32 start, dolen;
|
||||
struct aic_spinand *flash;
|
||||
u32 flash_size = 0;
|
||||
|
||||
if (!mtd)
|
||||
return -1;
|
||||
@@ -87,6 +88,14 @@ static int mtd_spinand_erase(struct mtd_dev *mtd, u32 offset, u32 len)
|
||||
if ((mtd->size - offset) < dolen)
|
||||
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);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -121,7 +130,7 @@ static int mtd_spinand_block_isbad(struct mtd_dev *mtd, u32 offset)
|
||||
|
||||
err = spinand_block_isbad(flash, blk);
|
||||
if (err != 0) {
|
||||
printf("Block %d is bad.\n", blk);
|
||||
pr_err("Block %d is bad.\n", blk);
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -156,7 +165,7 @@ static int mtd_spinand_block_markbad(struct mtd_dev *mtd, u32 offset)
|
||||
|
||||
err = spinand_block_markbad(flash, blk);
|
||||
if (err != 0) {
|
||||
printf("Mark badblock %d failed.\n",blk);
|
||||
pr_err("Mark badblock %d failed.\n", blk);
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -260,7 +269,8 @@ static char *aic_spinand_get_partition_string(struct mtd_dev *mtd)
|
||||
parts = strdup(parts);
|
||||
#else
|
||||
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);
|
||||
if (parts == NULL)
|
||||
parts = IMAGE_CFG_JSON_PARTS_MTD;
|
||||
@@ -303,7 +313,7 @@ struct aic_spinand *spinand_probe(u32 spi_bus)
|
||||
|
||||
err = spinand_flash_init(flash);
|
||||
if (err < 0) {
|
||||
printf("Failed to probe spinand flash.\n");
|
||||
pr_err("Failed to probe spinand flash.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#undef pr_debug
|
||||
#ifdef AIC_SPINAND_DRV_DEBUG
|
||||
#define pr_debug pr_info
|
||||
#define pr_debug pr_info
|
||||
#else
|
||||
#define pr_debug(fmt, ...)
|
||||
#endif
|
||||
@@ -34,6 +34,8 @@ struct nand_bbt {
|
||||
u8 *cache;
|
||||
};
|
||||
|
||||
struct aic_spinand;
|
||||
|
||||
/* SPI NAND flash information */
|
||||
struct aic_spinand_info {
|
||||
u32 devid;
|
||||
@@ -44,6 +46,7 @@ struct aic_spinand_info {
|
||||
u8 is_die_select;
|
||||
const char *sz_description;
|
||||
struct spi_nand_cmd_cfg *cmd;
|
||||
int (*get_status)(struct aic_spinand *flash, u8 status);
|
||||
};
|
||||
typedef struct aic_spinand_info *aic_spinand_info_t;
|
||||
|
||||
@@ -175,14 +178,15 @@ struct spi_nand_cmd_cfg {
|
||||
#define CFG_QUAD_ENABLE BIT(0)
|
||||
|
||||
/* status register */
|
||||
#define REG_STATUS 0xc0
|
||||
#define STATUS_BUSY BIT(0)
|
||||
#define STATUS_ERASE_FAILED BIT(2)
|
||||
#define STATUS_PROG_FAILED BIT(3)
|
||||
#define STATUS_ECC_MASK GENMASK(5, 4)
|
||||
#define STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
#define STATUS_ECC_HAS_BITFLIPS (1 << 4)
|
||||
#define STATUS_ECC_UNCOR_ERROR (2 << 4)
|
||||
#define REG_STATUS 0xc0
|
||||
#define STATUS_BUSY BIT(0)
|
||||
#define STATUS_ERASE_FAILED BIT(2)
|
||||
#define STATUS_PROG_FAILED BIT(3)
|
||||
|
||||
#define STATUS_ECC_MASK GENMASK(5, 4)
|
||||
#define STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
#define STATUS_ECC_HAS_1_4_BITFLIPS (1 << 4)
|
||||
#define STATUS_ECC_UNCOR_ERROR (2 << 4)
|
||||
|
||||
#ifdef SPI_NAND_WINBOND
|
||||
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
|
||||
|
||||
@@ -138,6 +138,27 @@ int spinand_read_cfg(struct aic_spinand *flash, u8 *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)
|
||||
{
|
||||
u8 SR = 0xFF;
|
||||
@@ -495,11 +516,13 @@ int spinand_read_page(struct aic_spinand *flash, u32 page, u8 *data,
|
||||
goto exit_spinand_read_page;
|
||||
}
|
||||
|
||||
status = (status & 0x30) >> 4;
|
||||
if ((status > 0x01)) {
|
||||
result = -SPINAND_ERR_ECC;
|
||||
result = spinand_check_ecc_status(flash, status);
|
||||
if (result < 0) {
|
||||
pr_err("Error ECC status error[0x%x].\n", status);
|
||||
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) {
|
||||
@@ -658,11 +681,14 @@ int spinand_continuous_read(struct aic_spinand *flash, u32 page, u8 *data,
|
||||
goto exit_spinand_continuous_read;
|
||||
}
|
||||
|
||||
status = (status & 0x30) >> 4;
|
||||
if ((status > 0x01)) {
|
||||
result = spinand_check_ecc_status(flash, status);
|
||||
if (result < 0) {
|
||||
result = -SPINAND_ERR_ECC;
|
||||
pr_err("Error ECC status error[0x%x].\n", status);
|
||||
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);
|
||||
@@ -760,11 +786,13 @@ int spinand_write_page(struct aic_spinand *flash, u32 page, const u8 *data,
|
||||
goto exit_spinand_write_page;
|
||||
}
|
||||
|
||||
status = (status & 0x30) >> 4;
|
||||
if ((status > 0x01)) {
|
||||
result = -SPINAND_ERR_ECC;
|
||||
result = spinand_check_ecc_status(flash, status);
|
||||
if (result < 0) {
|
||||
pr_err("Error ECC status error[0x%x].\n", status);
|
||||
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;
|
||||
@@ -796,27 +824,25 @@ int spinand_block_markbad(struct aic_spinand *flash, u16 blk)
|
||||
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 err = 0;
|
||||
u32 page, cplen;
|
||||
u32 off = offset;
|
||||
u8 *buf = NULL, *p, copy_flag;
|
||||
u8 *buf = NULL, *p, copy_flag = 0;
|
||||
u32 remaining = size;
|
||||
u16 blk;
|
||||
u32 blk_size;
|
||||
u32 off_in_page = 0;
|
||||
|
||||
if (!flash) {
|
||||
pr_err("flash is NULL\r\n");
|
||||
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);
|
||||
if (!buf) {
|
||||
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) {
|
||||
if (remaining >= flash->info->page_size) {
|
||||
p = addr;
|
||||
copy_flag = 0;
|
||||
if (off % flash->info->page_size == 0) {
|
||||
if (remaining >= flash->info->page_size) {
|
||||
p = addr;
|
||||
copy_flag = 0;
|
||||
} else {
|
||||
p = buf;
|
||||
copy_flag = READ_DATE_OFFSET_UNALIGN;
|
||||
memset(buf, 0xFF, flash->info->page_size);
|
||||
}
|
||||
} else {
|
||||
p = buf;
|
||||
copy_flag = 1;
|
||||
copy_flag = READ_DATE_OFFSET_ALIGN;
|
||||
memset(buf, 0xFF, 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;
|
||||
|
||||
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;
|
||||
if (copy_flag)
|
||||
memcpy(addr, buf, cplen);
|
||||
}
|
||||
|
||||
remaining -= cplen;
|
||||
off += cplen;
|
||||
addr += cplen;
|
||||
|
||||
Reference in New Issue
Block a user