Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 530a1876 authored by Pradeep P V K's avatar Pradeep P V K
Browse files

mtd: msm_qpic_nand: check for page_erased bit along with op_err



Due to a hardware bug in ECC-Engine, ECC-Engine couldn't able
to set OP_ERR bit in flash_status regesiter whenever an erased
page encounters bitflips. Due to this, ECC-Engine is trying to
correct the bitflips on an erased page and leading to data
corruption. So, a check for PAGE_ERASED bit is added prior to
OP_ERR bit for an erased page detection logic.

Change-Id: I570625123fe828450dade06570f782ebe93d39f1
Signed-off-by: default avatarPradeep P V K <ppvk@codeaurora.org>
parent b4791b81
Loading
Loading
Loading
Loading
+58 −4
Original line number Diff line number Diff line
@@ -1993,7 +1993,7 @@ static int msm_nand_is_erased_page_ps(struct mtd_info *mtd, loff_t from,
			if (last_pos < ecc_bytes_percw_in_bits)
				num_zero_bits++;

			if (num_zero_bits > 4) {
			if (num_zero_bits > MAX_ECC_BIT_FLIPS) {
				*erased_page = false;
				goto free_mem;
			}
@@ -2005,7 +2005,7 @@ static int msm_nand_is_erased_page_ps(struct mtd_info *mtd, loff_t from,
		ecc_temp += chip->ecc_parity_bytes;
	}

	if ((n == cwperpage) && (num_zero_bits <= 4))
	if ((n == cwperpage) && (num_zero_bits <= MAX_ECC_BIT_FLIPS))
		*erased_page = true;
free_mem:
	kfree(ecc);
@@ -2228,6 +2228,33 @@ static int msm_nand_read_pagescope(struct mtd_info *mtd, loff_t from,
			goto free_dma;
		/* Check for flash status errors */
		pageerr = rawerr = 0;

		/*
		 * PAGE_ERASED bit will set only if all
		 * CODEWORD_ERASED bit of all codewords
		 * of the page is set.
		 *
		 * PAGE_ERASED bit is a 'logical and' of all
		 * CODEWORD_ERASED bit of all codewords i.e.
		 * even if one codeword is detected as not
		 * an erased codeword, PAGE_ERASED bit will unset.
		 */
		for (n = rw_params.start_sector; n < cwperpage; n++) {
			if ((dma_buffer->result[n].erased_cw_status &
					(1 << PAGE_ERASED)) &&
					(dma_buffer->result[n].buffer_status &
					 NUM_ERRORS)) {
				err = msm_nand_is_erased_page_ps(mtd,
						from, ops,
						&rw_params,
						&erased_page);
				if (err)
					goto free_dma;
				if (erased_page)
					rawerr = -EIO;
				break;
			}
		}
		for (n = rw_params.start_sector; n < cwperpage; n++) {
			if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
					FS_MPU_ERR)) {
@@ -2633,7 +2660,7 @@ static int msm_nand_is_erased_page(struct mtd_info *mtd, loff_t from,
			if (last_pos < ecc_bytes_percw_in_bits)
				num_zero_bits++;

			if (num_zero_bits > 4) {
			if (num_zero_bits > MAX_ECC_BIT_FLIPS) {
				*erased_page = false;
				goto free_mem;
			}
@@ -2645,7 +2672,7 @@ static int msm_nand_is_erased_page(struct mtd_info *mtd, loff_t from,
		ecc_temp += chip->ecc_parity_bytes;
	}

	if ((n == cwperpage) && (num_zero_bits <= 4))
	if ((n == cwperpage) && (num_zero_bits <= MAX_ECC_BIT_FLIPS))
		*erased_page = true;
free_mem:
	kfree(ecc);
@@ -2840,6 +2867,33 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
			goto free_dma;
		/* Check for flash status errors */
		pageerr = rawerr = 0;

		/*
		 * PAGE_ERASED bit will set only if all
		 * CODEWORD_ERASED bit of all codewords
		 * of the page is set.
		 *
		 * PAGE_ERASED bit is a 'logical and' of all
		 * CODEWORD_ERASED bit of all codewords i.e.
		 * even if one codeword is detected as not
		 * an erased codeword, PAGE_ERASED bit will unset.
		 */
		for (n = rw_params.start_sector; n < cwperpage; n++) {
			if ((dma_buffer->result[n].erased_cw_status &
					(1 << PAGE_ERASED)) &&
					(dma_buffer->result[n].buffer_status &
					 NUM_ERRORS)) {
				err = msm_nand_is_erased_page(mtd,
						from, ops,
						&rw_params,
						&erased_page);
				if (err)
					goto free_dma;
				if (erased_page)
					rawerr = -EIO;
				break;
			}
		}
		for (n = rw_params.start_sector; n < cwperpage; n++) {
			if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
					FS_MPU_ERR)) {
+6 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 Google, Inc.
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -165,7 +165,10 @@
#define RESET_ERASED_DET	(1 << AUTO_DETECT_RES)
#define ACTIVE_ERASED_DET	(0 << AUTO_DETECT_RES)
#define CLR_ERASED_PAGE_DET	(RESET_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET	(ACTIVE_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET	(ACTIVE_ERASED_DET | MASK_ECC | SET_N_MAX_ZEROS)
#define N_MAX_ZEROS		2
#define MAX_ECC_BIT_FLIPS       4
#define SET_N_MAX_ZEROS		(MAX_ECC_BIT_FLIPS << N_MAX_ZEROS)

#define MSM_NAND_ERASED_CW_DETECT_STATUS(info)  MSM_NAND_REG(info, 0x300EC)
#define PAGE_ALL_ERASED		7
@@ -174,6 +177,7 @@
#define CODEWORD_ERASED		4
#define ERASED_PAGE	((1 << PAGE_ALL_ERASED) | (1 << PAGE_ERASED))
#define ERASED_CW	((1 << CODEWORD_ALL_ERASED) | (1 << CODEWORD_ERASED))
#define NUM_ERRORS		0x1f

#define MSM_NAND_CTRL(info)		    MSM_NAND_REG(info, 0x30F00)
#define BAM_MODE_EN	0