mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
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:
parent
2cead0c0ea
commit
f53151f421
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user