aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 16a533a78edd..959cb9b70310 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1081,6 +1081,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1081 int first, last, marker_pos; 1081 int first, last, marker_pos;
1082 int ecc_parity_size; 1082 int ecc_parity_size;
1083 int col = 0; 1083 int col = 0;
1084 int old_swap_block_mark = this->swap_block_mark;
1084 1085
1085 /* The size of ECC parity */ 1086 /* The size of ECC parity */
1086 ecc_parity_size = geo->gf_len * geo->ecc_strength / 8; 1087 ecc_parity_size = geo->gf_len * geo->ecc_strength / 8;
@@ -1089,17 +1090,21 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1089 first = offs / size; 1090 first = offs / size;
1090 last = (offs + len - 1) / size; 1091 last = (offs + len - 1) / size;
1091 1092
1092 /* 1093 if (this->swap_block_mark) {
1093 * Find the chunk which contains the Block Marker. If this chunk is 1094 /*
1094 * in the range of [first, last], we have to read out the whole page. 1095 * Find the chunk which contains the Block Marker.
1095 * Why? since we had swapped the data at the position of Block Marker 1096 * If this chunk is in the range of [first, last],
1096 * to the metadata which is bound with the chunk 0. 1097 * we have to read out the whole page.
1097 */ 1098 * Why? since we had swapped the data at the position of Block
1098 marker_pos = geo->block_mark_byte_offset / size; 1099 * Marker to the metadata which is bound with the chunk 0.
1099 if (last >= marker_pos && first <= marker_pos) { 1100 */
1100 dev_dbg(this->dev, "page:%d, first:%d, last:%d, marker at:%d\n", 1101 marker_pos = geo->block_mark_byte_offset / size;
1102 if (last >= marker_pos && first <= marker_pos) {
1103 dev_dbg(this->dev,
1104 "page:%d, first:%d, last:%d, marker at:%d\n",
1101 page, first, last, marker_pos); 1105 page, first, last, marker_pos);
1102 return gpmi_ecc_read_page(mtd, chip, buf, 0, page); 1106 return gpmi_ecc_read_page(mtd, chip, buf, 0, page);
1107 }
1103 } 1108 }
1104 1109
1105 meta = geo->metadata_size; 1110 meta = geo->metadata_size;
@@ -1145,7 +1150,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1145 writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0); 1150 writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0);
1146 writel(r2_old, bch_regs + HW_BCH_FLASH0LAYOUT1); 1151 writel(r2_old, bch_regs + HW_BCH_FLASH0LAYOUT1);
1147 this->bch_geometry = old_geo; 1152 this->bch_geometry = old_geo;
1148 this->swap_block_mark = true; 1153 this->swap_block_mark = old_swap_block_mark;
1149 1154
1150 return max_bitflips; 1155 return max_bitflips;
1151} 1156}
@@ -1309,10 +1314,10 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
1309 1314
1310 /* 1315 /*
1311 * Now, we want to make sure the block mark is correct. In the 1316 * Now, we want to make sure the block mark is correct. In the
1312 * Swapping/Raw case, we already have it. Otherwise, we need to 1317 * non-transcribing case (!GPMI_IS_MX23()), we already have it.
1313 * explicitly read it. 1318 * Otherwise, we need to explicitly read it.
1314 */ 1319 */
1315 if (!this->swap_block_mark) { 1320 if (GPMI_IS_MX23(this)) {
1316 /* Read the block mark into the first byte of the OOB buffer. */ 1321 /* Read the block mark into the first byte of the OOB buffer. */
1317 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); 1322 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
1318 chip->oob_poi[0] = chip->read_byte(mtd); 1323 chip->oob_poi[0] = chip->read_byte(mtd);
@@ -1353,7 +1358,7 @@ static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)
1353 chipnr = (int)(ofs >> chip->chip_shift); 1358 chipnr = (int)(ofs >> chip->chip_shift);
1354 chip->select_chip(mtd, chipnr); 1359 chip->select_chip(mtd, chipnr);
1355 1360
1356 column = this->swap_block_mark ? mtd->writesize : 0; 1361 column = !GPMI_IS_MX23(this) ? mtd->writesize : 0;
1357 1362
1358 /* Write the block mark. */ 1363 /* Write the block mark. */
1359 block_mark = this->data_buffer_dma; 1364 block_mark = this->data_buffer_dma;
@@ -1649,9 +1654,6 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
1649 struct bch_geometry *bch_geo = &this->bch_geometry; 1654 struct bch_geometry *bch_geo = &this->bch_geometry;
1650 int ret; 1655 int ret;
1651 1656
1652 /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
1653 this->swap_block_mark = !GPMI_IS_MX23(this);
1654
1655 /* Set up the medium geometry */ 1657 /* Set up the medium geometry */
1656 ret = gpmi_set_geometry(this); 1658 ret = gpmi_set_geometry(this);
1657 if (ret) 1659 if (ret)
@@ -1715,9 +1717,20 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
1715 chip->badblock_pattern = &gpmi_bbt_descr; 1717 chip->badblock_pattern = &gpmi_bbt_descr;
1716 chip->block_markbad = gpmi_block_markbad; 1718 chip->block_markbad = gpmi_block_markbad;
1717 chip->options |= NAND_NO_SUBPAGE_WRITE; 1719 chip->options |= NAND_NO_SUBPAGE_WRITE;
1718 if (of_get_nand_on_flash_bbt(this->dev->of_node)) 1720
1721 /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
1722 this->swap_block_mark = !GPMI_IS_MX23(this);
1723
1724 if (of_get_nand_on_flash_bbt(this->dev->of_node)) {
1719 chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; 1725 chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
1720 1726
1727 if (of_property_read_bool(this->dev->of_node,
1728 "fsl,no-blockmark-swap"))
1729 this->swap_block_mark = false;
1730 }
1731 dev_dbg(this->dev, "Blockmark swapping %sabled\n",
1732 this->swap_block_mark ? "en" : "dis");
1733
1721 /* 1734 /*
1722 * Allocate a temporary DMA buffer for reading ID in the 1735 * Allocate a temporary DMA buffer for reading ID in the
1723 * nand_scan_ident(). 1736 * nand_scan_ident().