|
@@ -47,10 +47,44 @@ static struct nand_bbt_descr gpmi_bbt_descr = {
|
|
* We may change the layout if we can get the ECC info from the datasheet,
|
|
* We may change the layout if we can get the ECC info from the datasheet,
|
|
* else we will use all the (page + OOB).
|
|
* else we will use all the (page + OOB).
|
|
*/
|
|
*/
|
|
-static struct nand_ecclayout gpmi_hw_ecclayout = {
|
|
|
|
- .eccbytes = 0,
|
|
|
|
- .eccpos = { 0, },
|
|
|
|
- .oobfree = { {.offset = 0, .length = 0} }
|
|
|
|
|
|
+static int gpmi_ooblayout_ecc(struct mtd_info *mtd, int section,
|
|
|
|
+ struct mtd_oob_region *oobregion)
|
|
|
|
+{
|
|
|
|
+ struct nand_chip *chip = mtd_to_nand(mtd);
|
|
|
|
+ struct gpmi_nand_data *this = nand_get_controller_data(chip);
|
|
|
|
+ struct bch_geometry *geo = &this->bch_geometry;
|
|
|
|
+
|
|
|
|
+ if (section)
|
|
|
|
+ return -ERANGE;
|
|
|
|
+
|
|
|
|
+ oobregion->offset = 0;
|
|
|
|
+ oobregion->length = geo->page_size - mtd->writesize;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int gpmi_ooblayout_free(struct mtd_info *mtd, int section,
|
|
|
|
+ struct mtd_oob_region *oobregion)
|
|
|
|
+{
|
|
|
|
+ struct nand_chip *chip = mtd_to_nand(mtd);
|
|
|
|
+ struct gpmi_nand_data *this = nand_get_controller_data(chip);
|
|
|
|
+ struct bch_geometry *geo = &this->bch_geometry;
|
|
|
|
+
|
|
|
|
+ if (section)
|
|
|
|
+ return -ERANGE;
|
|
|
|
+
|
|
|
|
+ /* The available oob size we have. */
|
|
|
|
+ if (geo->page_size < mtd->writesize + mtd->oobsize) {
|
|
|
|
+ oobregion->offset = geo->page_size - mtd->writesize;
|
|
|
|
+ oobregion->length = mtd->oobsize - oobregion->offset;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const struct mtd_ooblayout_ops gpmi_ooblayout_ops = {
|
|
|
|
+ .ecc = gpmi_ooblayout_ecc,
|
|
|
|
+ .free = gpmi_ooblayout_free,
|
|
};
|
|
};
|
|
|
|
|
|
static const struct gpmi_devdata gpmi_devdata_imx23 = {
|
|
static const struct gpmi_devdata gpmi_devdata_imx23 = {
|
|
@@ -141,7 +175,6 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
|
|
struct bch_geometry *geo = &this->bch_geometry;
|
|
struct bch_geometry *geo = &this->bch_geometry;
|
|
struct nand_chip *chip = &this->nand;
|
|
struct nand_chip *chip = &this->nand;
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
|
- struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree;
|
|
|
|
unsigned int block_mark_bit_offset;
|
|
unsigned int block_mark_bit_offset;
|
|
|
|
|
|
if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
|
|
if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
|
|
@@ -229,12 +262,6 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this)
|
|
geo->page_size = mtd->writesize + geo->metadata_size +
|
|
geo->page_size = mtd->writesize + geo->metadata_size +
|
|
(geo->gf_len * geo->ecc_strength * geo->ecc_chunk_count) / 8;
|
|
(geo->gf_len * geo->ecc_strength * geo->ecc_chunk_count) / 8;
|
|
|
|
|
|
- /* The available oob size we have. */
|
|
|
|
- if (geo->page_size < mtd->writesize + mtd->oobsize) {
|
|
|
|
- of->offset = geo->page_size - mtd->writesize;
|
|
|
|
- of->length = mtd->oobsize - of->offset;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
geo->payload_size = mtd->writesize;
|
|
geo->payload_size = mtd->writesize;
|
|
|
|
|
|
geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
|
|
geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
|
|
@@ -1842,6 +1869,7 @@ static void gpmi_nand_exit(struct gpmi_nand_data *this)
|
|
static int gpmi_init_last(struct gpmi_nand_data *this)
|
|
static int gpmi_init_last(struct gpmi_nand_data *this)
|
|
{
|
|
{
|
|
struct nand_chip *chip = &this->nand;
|
|
struct nand_chip *chip = &this->nand;
|
|
|
|
+ struct mtd_info *mtd = nand_to_mtd(chip);
|
|
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
struct bch_geometry *bch_geo = &this->bch_geometry;
|
|
struct bch_geometry *bch_geo = &this->bch_geometry;
|
|
int ret;
|
|
int ret;
|
|
@@ -1863,7 +1891,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
|
|
ecc->mode = NAND_ECC_HW;
|
|
ecc->mode = NAND_ECC_HW;
|
|
ecc->size = bch_geo->ecc_chunk_size;
|
|
ecc->size = bch_geo->ecc_chunk_size;
|
|
ecc->strength = bch_geo->ecc_strength;
|
|
ecc->strength = bch_geo->ecc_strength;
|
|
- ecc->layout = &gpmi_hw_ecclayout;
|
|
|
|
|
|
+ mtd_set_ooblayout(mtd, &gpmi_ooblayout_ops);
|
|
|
|
|
|
/*
|
|
/*
|
|
* We only enable the subpage read when:
|
|
* We only enable the subpage read when:
|