151 lines
4.2 KiB
C
151 lines
4.2 KiB
C
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
|
/*
|
|
* drivers/nand/logic/aml_phyops.c
|
|
*
|
|
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include "aml_nftl.h"
|
|
|
|
int nand_erase_superblk(struct aml_nftl_part_t *part,_physic_op_par *p)
|
|
{
|
|
struct amlnand_phydev *phydev = (struct amlnand_phydev *)aml_nftl_get_part_priv(part);
|
|
struct phydev_ops *ops = &phydev->ops;
|
|
|
|
memset(ops, 0, sizeof(struct phydev_ops));
|
|
|
|
ops->addr = p->phy_page.blkNO_in_chip;
|
|
ops->addr <<= phydev->erasesize_shift;
|
|
ops->len = phydev->erasesize;
|
|
|
|
return phydev->erase(phydev);
|
|
}
|
|
|
|
int nand_read_page(struct aml_nftl_part_t *part,_physic_op_par *p)
|
|
{
|
|
|
|
struct amlnand_phydev *phydev = (struct amlnand_phydev *)aml_nftl_get_part_priv(part);
|
|
struct phydev_ops *ops = &phydev->ops;
|
|
int ret;
|
|
uint32 temp;
|
|
|
|
memset(ops, 0, sizeof(struct phydev_ops));
|
|
|
|
ops->addr = p->phy_page.blkNO_in_chip;
|
|
ops->addr <<= phydev->erasesize_shift;
|
|
temp = p->phy_page.Page_NO;
|
|
temp <<= phydev->writesize_shift;
|
|
ops->addr += temp;
|
|
|
|
ops->len = phydev->writesize;
|
|
ops->ooblen = BYTES_OF_USER_PER_PAGE;
|
|
ops->datbuf = p->main_data_addr;
|
|
//aml_nftl_blk->nand_dev->ops.oobbuf = p->spare_data_addr;
|
|
ops->oobbuf = p->spare_data_addr;//aml_nftl_blk->spare_buf;
|
|
|
|
aml_nftl_add_part_total_read(part);
|
|
//NPRINT("111aml_ops_read_page : %llx %d %d\n", aml_nftl_blk->nand_dev->ops.addr, p->phy_page.blkNO_in_chip, p->phy_page.Page_NO);
|
|
//NPRINT("%s() addr %llx [%d, %d]\n", __func__, ops->addr, p->phy_page.blkNO_in_chip, p->phy_page.Page_NO);
|
|
ret = phydev->read(phydev);
|
|
//NPRINT("222aml_ops_read_page : %llx %d %d\n", aml_nftl_blk->nand_dev->ops.addr, p->phy_page.blkNO_in_chip, p->phy_page.Page_NO);
|
|
|
|
if (ret == -EUCLEAN)
|
|
{
|
|
NPRINT("read reclaim\n");
|
|
}
|
|
|
|
/*if(p->spare_data_addr)
|
|
memcpy(p->spare_data_addr,aml_nftl_blk->spare_buf, BYTES_OF_USER_PER_PAGE);*/
|
|
|
|
if ((ret!=0) &&(ret != -EUCLEAN)){
|
|
NPRINT("aml_ops_read_page failed: %llx %d %d\n", ops->addr, p->phy_page.blkNO_in_chip, p->phy_page.Page_NO);
|
|
ret = -EBADMSG;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int nand_write_page(struct aml_nftl_part_t *part, _physic_op_par *p)
|
|
{
|
|
int ret;
|
|
uint32 temp;
|
|
struct amlnand_phydev *phydev = (struct amlnand_phydev *)aml_nftl_get_part_priv(part);
|
|
struct phydev_ops *ops = &phydev->ops;
|
|
|
|
memset(ops, 0, sizeof(struct phydev_ops));
|
|
|
|
// aml_nftl_blk->nand_dev->ops.addr = aml_nftl_blk->nand_dev->erasesize;
|
|
// aml_nftl_blk->nand_dev->ops.addr *= p->phy_page.blkNO_in_chip;
|
|
// aml_nftl_blk->nand_dev->ops.addr += p->phy_page.Page_NO * aml_nftl_blk->nand_dev->writesize;
|
|
|
|
ops->addr = p->phy_page.blkNO_in_chip;
|
|
ops->addr <<= phydev->erasesize_shift;
|
|
temp = p->phy_page.Page_NO;
|
|
temp <<= phydev->writesize_shift;
|
|
ops->addr += temp;
|
|
|
|
ops->len = phydev->writesize;
|
|
ops->ooblen = BYTES_OF_USER_PER_PAGE;
|
|
ops->datbuf = p->main_data_addr;
|
|
ops->oobbuf = p->spare_data_addr;
|
|
|
|
aml_nftl_add_part_total_write(part);
|
|
NFTL_LINE
|
|
aml_nand_dbg("%s() addr %llx [%d, %d]\n", __func__, ops->addr, p->phy_page.blkNO_in_chip, p->phy_page.Page_NO);
|
|
ret = phydev->write(phydev);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int nand_is_blk_good(struct aml_nftl_part_t *part,_physic_op_par *p)
|
|
{
|
|
int ret;
|
|
struct amlnand_phydev *phydev = (struct amlnand_phydev *)aml_nftl_get_part_priv(part);
|
|
struct phydev_ops *ops = &phydev->ops;
|
|
|
|
memset(ops, 0, sizeof(struct phydev_ops));
|
|
|
|
ops->addr = phydev->erasesize;
|
|
ops->addr *= p->phy_page.blkNO_in_chip;
|
|
ops->addr <<= phydev->erasesize_shift;
|
|
|
|
// NPRINT("nand_is_blk_good %x,%x,%llx\n",p->phy_page.blkNO_in_chip,aml_nftl_blk->nand_dev->erasesize,aml_nftl_blk->nand_dev->ops.addr);
|
|
|
|
ret = phydev->block_isbad(phydev);
|
|
// NPRINT("nand_is_blk_good 2\n");
|
|
if(ret == 0)
|
|
{
|
|
return RET_YES;
|
|
}
|
|
else
|
|
{
|
|
if(ret == 1)
|
|
ret = RET_NO;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
int nand_mark_bad_blk(struct aml_nftl_part_t *part,_physic_op_par *p)
|
|
{
|
|
int ret;
|
|
struct amlnand_phydev *phydev = (struct amlnand_phydev *)aml_nftl_get_part_priv(part);
|
|
struct phydev_ops *ops = &phydev->ops;
|
|
|
|
memset(ops, 0, sizeof(struct phydev_ops));
|
|
// aml_nftl_blk->nand_dev->ops.addr = aml_nftl_blk->nand_dev->erasesize;
|
|
ops->addr = p->phy_page.blkNO_in_chip;
|
|
ops->addr <<= phydev->erasesize_shift;
|
|
ops->len = phydev->erasesize;
|
|
|
|
ret = phydev->block_markbad(phydev);
|
|
if(ret == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|