/* 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; } }