drivers: rkflash: fix firmware-lost-error in power lost case

1.Fix recovery vpn mistaken subtraction
2.Improve cache flush strategy
3.Avoid currunt map_block being gc
4.Make ftl buffer align
5.Rm unuse file ftl_flash_plat.c
6.Update ftl version to 5.0.48

Change-Id: I51d85f60702a1e0d2c904b76e875f0ec52d2e1d4
Signed-off-by: Dingqiang Lin <jon.lin@rock-chips.com>
This commit is contained in:
Dingqiang Lin 2018-09-29 15:53:43 +08:00 committed by Tao Huang
parent 2cead0c0ea
commit f53151f421
10 changed files with 27998 additions and 28014 deletions

View File

@ -52,6 +52,11 @@ int sftl_flash_vendor_write(u32 sec, u32 n_sec, void *p_data)
return sftl_vendor_write(sec, n_sec, p_data);
}
int sftl_flash_gc(void)
{
return sftl_gc();
}
void sftl_flash_deinit(void)
{
u8 chip_sel = 0;

View File

@ -138,7 +138,6 @@ static void nandc_xfer_start(u8 chip_sel,
{
union BCH_CTL_T bch_reg;
union FL_CTL_T fl_reg;
u8 bus_mode = (p_spare || p_data);
u32 i;
union MTRANS_CFG_T master_reg;
u16 *p_spare_tmp = (u16 *)p_spare;
@ -159,7 +158,7 @@ static void nandc_xfer_start(u8 chip_sel,
master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
master_reg.V6.bus_mode = 0;
#ifdef NANDC_MASTER_EN
if (bus_mode != 0 && dir != 0) {
if (dir != 0) {
u32 spare_sz = 64;
for (i = 0; i < sector_count / 2; i++) {
@ -219,7 +218,8 @@ static void nandc_xfer_comp(u8 chip_sel)
do {
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
stat_reg.d32 = nandc_readl(NANDC_MTRANS_STAT);
} while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num);
} while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num ||
fl_reg.V6.tr_rdy == 0);
if (master.mapped) {
rknandc_dma_unmap_single((u64)master.page_phy,
@ -233,7 +233,16 @@ static void nandc_xfer_comp(u8 chip_sel)
do {
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
} while (fl_reg.V6.tr_rdy == 0);
if (master.mapped) {
rknandc_dma_unmap_single(
(unsigned long)(master.page_phy),
fl_reg.V6.page_num * 1024, 1);
rknandc_dma_unmap_single(
(unsigned long)(master.spare_phy),
fl_reg.V6.page_num * 64, 1);
}
}
master.mapped = 0;
} else {
do {
fl_reg.d32 = nandc_readl(NANDC_FLCTL);
@ -256,19 +265,6 @@ u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 sector_count,
nandc_xfer_start(chip_sel, dir, sector_count, 0, p_data, p_spare);
nandc_xfer_comp(chip_sel);
if (dir == NANDC_READ) {
if (p_spare) {
u32 spare_sz = 64;
u32 temp_data;
u8 *p_spare_temp = (u8 *)p_spare;
for (i = 0; i < sector_count / 2; i++) {
temp_data = master.spare_buf[i * spare_sz / 4];
*p_spare_temp++ = (u8)temp_data;
*p_spare_temp++ = (u8)(temp_data >> 8);
*p_spare_temp++ = (u8)(temp_data >> 16);
*p_spare_temp++ = (u8)(temp_data >> 24);
}
}
for (i = 0; i < sector_count / 4 ; i++) {
bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i));
if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) {
@ -284,6 +280,19 @@ u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 sector_count,
status = max(tmp, status);
}
}
if (p_spare) {
u32 spare_sz = 64;
u32 temp_data;
u8 *p_spare_temp = (u8 *)p_spare;
for (i = 0; i < sector_count / 2; i++) {
temp_data = master.spare_buf[i * spare_sz / 4];
*p_spare_temp++ = (u8)temp_data;
*p_spare_temp++ = (u8)(temp_data >> 8);
*p_spare_temp++ = (u8)(temp_data >> 16);
*p_spare_temp++ = (u8)(temp_data >> 24);
}
}
}
nandc_writel(0, NANDC_MTRANS_CFG);
return status;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@ unsigned int sftl_flash_get_capacity(void);
void sftl_flash_deinit(void);
int sftl_flash_resume(void __iomem *reg_addr);
void sftl_flash_clean_irq(void);
int sftl_flash_gc(void);
#endif
#ifdef CONFIG_RK_SFC_NOR
@ -28,6 +29,7 @@ void snor_deinit(void);
int snor_resume(void __iomem *reg_addr);
int snor_vendor_read(unsigned int sec, unsigned int n_sec, void *p_data);
int snor_vendor_write(unsigned int sec, unsigned int n_sec, void *p_data);
int snor_gc(void);
#endif
#ifdef CONFIG_RK_SFC_NAND
@ -40,6 +42,7 @@ unsigned int snand_get_capacity(void);
void snand_deinit(void);
int snand_resume(void __iomem *reg_addr);
void sfc_clean_irq(void);
int snand_gc(void);
#endif
#endif

View File

@ -53,8 +53,9 @@ static struct flash_boot_ops nandc_nand_ops = {
sftl_flash_resume,
sftl_flash_vendor_read,
sftl_flash_vendor_write,
sftl_flash_gc,
#else
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
#endif
};
@ -69,8 +70,9 @@ static struct flash_boot_ops sfc_nor_ops = {
snor_resume,
snor_vendor_read,
snor_vendor_write,
snor_gc,
#else
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
#endif
};
@ -85,8 +87,9 @@ static struct flash_boot_ops sfc_nand_ops = {
snand_resume,
snand_vendor_read,
snand_vendor_write,
snand_gc,
#else
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
#endif
};
@ -149,16 +152,31 @@ int rkflash_vendor_write(u32 sec, u32 n_sec, void *p_data)
return ret;
}
static int rkflash_flash_gc(void)
{
int ret;
if (g_boot_ops[g_flash_type]->gc) {
mutex_lock(&g_flash_ops_mutex);
ret = g_boot_ops[g_flash_type]->gc();
mutex_unlock(&g_flash_ops_mutex);
} else {
ret = -EPERM;
}
return ret;
}
static unsigned int rk_partition_init(struct flash_part *part)
{
int i, part_num = 0;
int desity;
u32 desity;
struct STRUCT_PART_INFO *g_part; /* size 2KB */
g_part = kmalloc(sizeof(*g_part), GFP_KERNEL | GFP_DMA);
if (!g_part)
return 0;
mutex_lock(&g_flash_ops_mutex);
if (g_boot_ops[g_flash_type]->read(0, 4, g_part) == 0) {
if (g_part->hdr.ui_fw_tag == RK_PARTITION_TAG) {
part_num = g_part->hdr.ui_part_entry_count;
@ -172,9 +190,14 @@ static unsigned int rk_partition_init(struct flash_part *part)
part[i].type = 0;
if (part[i].size == UINT_MAX)
part[i].size = desity - part[i].offset;
if (part[i].offset + part[i].size > desity) {
part[i].size = desity - part[i].offset;
break;
}
}
}
}
mutex_unlock(&g_flash_ops_mutex);
kfree(g_part);
memset(&fw_header_p, 0x0, sizeof(fw_header_p));
@ -325,6 +348,7 @@ static int rkflash_blktrans_thread(void *arg)
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(rq->queue_lock);
rkflash_req_jiffies = HZ / 10;
rkflash_flash_gc();
wait_event_timeout(blk_ops->thread_wq,
blk_ops->quit || rknand_req_do,
rkflash_req_jiffies);

View File

@ -25,6 +25,7 @@ enum flash_type {
struct flash_boot_ops {
int id;
int (*init)(void __iomem *reg_addr);
int (*read)(u32 sec, u32 n_sec, void *p_data);
int (*write)(u32 sec, u32 n_sec, void *p_data);
@ -33,6 +34,7 @@ struct flash_boot_ops {
int (*resume)(void __iomem *reg_addr);
int (*vendor_read)(u32 sec, u32 n_sec, void *p_data);
int (*vendor_write)(u32 sec, u32 n_sec, void *p_data);
int (*gc)(void);
};
struct flash_part {

View File

@ -48,6 +48,11 @@ int snand_vendor_write(u32 sec, u32 n_sec, void *p_data)
return sftl_vendor_write(sec, n_sec, p_data);
}
int snand_gc(void)
{
return sftl_gc();
}
void snand_deinit(void)
{
sftl_deinit();

View File

@ -94,6 +94,11 @@ int snor_vendor_write(u32 sec, u32 n_sec, void *p_data)
return (u32)ret == n_sec ? 0 : ret;
}
int snor_gc(void)
{
return 0;
}
unsigned int snor_capacity(void)
{
return snor_get_capacity(&sfnor_dev);