Received: by 10.213.65.68 with SMTP id h4csp689985imn; Wed, 4 Apr 2018 05:45:14 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+b5bXiVWT3ZaVzBIihy7RSJCphgw3wYf27MljWjbqFhD9iMTR/Ecb7wqSjOdxbxZLPYPao X-Received: by 10.101.86.141 with SMTP id v13mr11915974pgs.353.1522845913981; Wed, 04 Apr 2018 05:45:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522845913; cv=none; d=google.com; s=arc-20160816; b=BbSqIgNzvsJ2SiK0YxUP53PTn2osYycegwlpF8Dwrza640ulN9GalQL6aXLjUEndml ZkSZtMIj0TSu2A+7OBZngwQ9J8EOdhCPUQvAVwQMW/TJkjpoLVGzYaeIaw01tszwvpa9 fUEPMX5cO36Nn6TKK7HNQrmFxRWLuBbPbgk6gD9eAc73dhUprXrhiKxokD/0371vh5w6 N7DKLUKJKHbDq+vgpeVFDJeWVgcuM/noj088HvZmkt9m3rPGluV+1YMLsOxaslKVdnUU WCX+MnnyzpHCE+pJnBf9tk9z+zCyGs/JbDdv7GifzWdFXzgkSbV1gsQZu8JP2o3aGpsV Kg7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dmarc-filter:dkim-signature:dkim-signature :arc-authentication-results; bh=ixtIZA4Fundzbasw+5wu1/1ktOcpviwjSghb4TBqL0k=; b=J5/iCZx5h0J+08JKKHJe7YtyqQ2KsB3w71pJCfPDrT44hP8aGAwJZcWF3FFkUpClK3 fn+zWwJsCrPH5w0ZU1SbY6eMIntB6j0d0BdwPvqBmukFK1j3g43eebkR/R0Xxxe+JCkW HRBPByGFUZ9u2H8fP5S1KZ9Mbk8BVgU7VsHIFDimxvLmxRFqRSjw37YN+b4AXcc5UDO5 fIxb19GRjnyXdLkBRIMGQ0eohcrSZn4XlvZ4jzP9QS3OcqOloz/cpN8ZtzoaFJo5H0xs VGaEhrRWjipsafld2ynjFEATsS/bnsvwlR9PZgzUFeQPgnuRhLo7bDmW+D5ocbuTDE1d 6hig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=HF4vjLXL; dkim=pass header.i=@codeaurora.org header.s=default header.b=ZOmW47Es; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h6-v6si2784441pll.726.2018.04.04.05.45.00; Wed, 04 Apr 2018 05:45:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=HF4vjLXL; dkim=pass header.i=@codeaurora.org header.s=default header.b=ZOmW47Es; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751829AbeDDMnl (ORCPT + 99 others); Wed, 4 Apr 2018 08:43:41 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:41718 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751743AbeDDMni (ORCPT ); Wed, 4 Apr 2018 08:43:38 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 8CF5860F5C; Wed, 4 Apr 2018 12:43:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1522845817; bh=BIiZ5xbCrEptn5nEsV4sFh8tdbW19g3S0vC4uEnOhWs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HF4vjLXLncyW5AYjrk8WZwsHlfvuj4nAAVakJJxAYl/kxWYIV0G3zvvoW8z0eqbzm 7SPslLl8XFdFEub/c8L9eW1QIfsESel5Pvi13d7rzE8Ow28BSDA+Ev1LqkfKvDrFb4 t0GOk90g8ezp1jtXIFSVa0Dwfmxs7QTeXl5asoqc= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from absahu-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: absahu@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 3648C60F78; Wed, 4 Apr 2018 12:43:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1522845816; bh=BIiZ5xbCrEptn5nEsV4sFh8tdbW19g3S0vC4uEnOhWs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZOmW47EsSr8tMS3dlJIg8A/XsjK9nWjII0xudNCJiGYVuJIzyvYO/25ITnz8uXKHk MGHDVtyjZqXt2hDhO+csuFENzv70IKzD8HllSwiPKJguL+XOvaDiEy77OpQdPRKo1j WWI3TAk2/UMUzLnB2XeRqYstzC3YTfg/YQBL435c= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 3648C60F78 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=absahu@codeaurora.org From: Abhishek Sahu To: Boris Brezillon Cc: David Woodhouse , Brian Norris , Marek Vasut , Richard Weinberger , Cyrille Pitchen , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, Andy Gross , Archit Taneja , Abhishek Sahu Subject: [PATCH 8/9] mtd: nand: qcom: helper function for raw read Date: Wed, 4 Apr 2018 18:12:24 +0530 Message-Id: <1522845745-6624-9-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1522845745-6624-1-git-send-email-absahu@codeaurora.org> References: <1522845745-6624-1-git-send-email-absahu@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch does minor code reorganization for raw reads. Currently the raw read is required for complete page but for subsequent patches related with erased codeword bit flips detection, only few CW should be read. So, this patch adds helper function and introduces the read CW bitmask which specifies which CW reads are required in complete page. Signed-off-by: Abhishek Sahu --- drivers/mtd/nand/qcom_nandc.c | 186 +++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 76 deletions(-) diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c index 40c790e..f5d1fa4 100644 --- a/drivers/mtd/nand/qcom_nandc.c +++ b/drivers/mtd/nand/qcom_nandc.c @@ -1590,6 +1590,114 @@ static int check_flash_errors(struct qcom_nand_host *host, int cw_cnt) } /* + * Helper to perform the page raw read operation. The read_cw_mask will be + * used to specify the codewords for which the data should be read. The + * single page contains multiple CW. Sometime, only few CW data is required + * in complete page. Also, start address will be determined with + * this CW mask to skip unnecessary data copy from NAND flash device. Then, + * actual data copy from NAND controller to data buffer will be done only + * for the CWs which have the mask set. + */ +static int +nandc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + u8 *data_buf, u8 *oob_buf, + int page, unsigned long read_cw_mask) +{ + struct qcom_nand_host *host = to_qcom_nand_host(chip); + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + int i, ret; + int read_loc, start_step, last_step; + + nand_read_page_op(chip, page, 0, NULL, 0); + + host->use_ecc = false; + start_step = ffs(read_cw_mask) - 1; + last_step = fls(read_cw_mask); + + clear_bam_transaction(nandc); + set_address(host, host->cw_size * start_step, page); + update_rw_regs(host, last_step - start_step, true); + config_nand_page_read(nandc); + + for (i = start_step; i < last_step; i++) { + int data_size1, data_size2, oob_size1, oob_size2; + int reg_off = FLASH_BUF_ACC; + + data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); + oob_size1 = host->bbm_size; + + if (i == (ecc->steps - 1)) { + data_size2 = ecc->size - data_size1 - + ((ecc->steps - 1) << 2); + oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + + host->spare_bytes; + } else { + data_size2 = host->cw_data - data_size1; + oob_size2 = host->ecc_bytes_hw + host->spare_bytes; + } + + /* + * Don't perform actual data copy from NAND controller to data + * buffer through DMA for this codeword + */ + if (!(read_cw_mask & BIT(i))) { + if (nandc->props->is_bam) + nandc_set_read_loc(nandc, 0, 0, 0, 1); + + config_nand_cw_read(nandc, false); + + data_buf += data_size1 + data_size2; + oob_buf += oob_size1 + oob_size2; + + continue; + } + + if (nandc->props->is_bam) { + read_loc = 0; + nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0); + read_loc += data_size1; + + nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0); + read_loc += oob_size1; + + nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0); + read_loc += data_size2; + + nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1); + } + + config_nand_cw_read(nandc, false); + + read_data_dma(nandc, reg_off, data_buf, data_size1, 0); + reg_off += data_size1; + data_buf += data_size1; + + read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0); + reg_off += oob_size1; + oob_buf += oob_size1; + + read_data_dma(nandc, reg_off, data_buf, data_size2, 0); + reg_off += data_size2; + data_buf += data_size2; + + read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); + oob_buf += oob_size2; + } + + ret = submit_descs(nandc); + if (ret) + dev_err(nandc->dev, "failure to read raw page\n"); + + free_descs(nandc); + + if (!ret) + ret = check_flash_errors(host, last_step - start_step); + + return 0; +} + +/* * reads back status registers set by the controller to notify page read * errors. this is equivalent to what 'ecc->correct()' would do. */ @@ -1839,82 +1947,8 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) { - struct qcom_nand_host *host = to_qcom_nand_host(chip); - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - u8 *data_buf, *oob_buf; - struct nand_ecc_ctrl *ecc = &chip->ecc; - int i, ret; - int read_loc; - - nand_read_page_op(chip, page, 0, NULL, 0); - data_buf = buf; - oob_buf = chip->oob_poi; - - host->use_ecc = false; - - clear_bam_transaction(nandc); - update_rw_regs(host, ecc->steps, true); - config_nand_page_read(nandc); - - for (i = 0; i < ecc->steps; i++) { - int data_size1, data_size2, oob_size1, oob_size2; - int reg_off = FLASH_BUF_ACC; - - data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); - oob_size1 = host->bbm_size; - - if (i == (ecc->steps - 1)) { - data_size2 = ecc->size - data_size1 - - ((ecc->steps - 1) << 2); - oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + - host->spare_bytes; - } else { - data_size2 = host->cw_data - data_size1; - oob_size2 = host->ecc_bytes_hw + host->spare_bytes; - } - - if (nandc->props->is_bam) { - read_loc = 0; - nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0); - read_loc += data_size1; - - nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0); - read_loc += oob_size1; - - nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0); - read_loc += data_size2; - - nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1); - } - - config_nand_cw_read(nandc, false); - - read_data_dma(nandc, reg_off, data_buf, data_size1, 0); - reg_off += data_size1; - data_buf += data_size1; - - read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0); - reg_off += oob_size1; - oob_buf += oob_size1; - - read_data_dma(nandc, reg_off, data_buf, data_size2, 0); - reg_off += data_size2; - data_buf += data_size2; - - read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); - oob_buf += oob_size2; - } - - ret = submit_descs(nandc); - if (ret) - dev_err(nandc->dev, "failure to read raw page\n"); - - free_descs(nandc); - - if (!ret) - ret = check_flash_errors(host, ecc->steps); - - return 0; + return nandc_read_page_raw(mtd, chip, buf, chip->oob_poi, page, + BIT(chip->ecc.steps) - 1); } /* implements ecc->read_oob() */ -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation