From patchwork Thu Jun 9 13:23:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12875563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B738CCA473 for ; Thu, 9 Jun 2022 13:24:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243376AbiFINYT (ORCPT ); Thu, 9 Jun 2022 09:24:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245054AbiFINYS (ORCPT ); Thu, 9 Jun 2022 09:24:18 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17F4D33E92; Thu, 9 Jun 2022 06:24:17 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id kq6so34423484ejb.11; Thu, 09 Jun 2022 06:24:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gIwvHle+n2X1mQu/sBa72r2guouaN1SD/l3le1h2rXk=; b=HRky5jZwzY5xTj4BXvqGmlXLwHXe0dloHZelSAteZl3sTquOX17mNHse8P9rcxPzQv 9r07VrAkUjEj3fpb2sFor0XUAT5h85p8EEUkfH2it2ohwW12UznZfnef7Xj5fNJwxsvi I77N8yvszS/xopOrwJhK3vMKorVL5bTwIf/iBuxlSDge8Ag1qlQS1qEFnn+QK4Wy/xVI 1fH4KiujZSVR4taMC+QPc3TecMhwYg/0ADG8VMl1V50vHtXQcrBWKaeWIN5nUQVE/12s UJBdHM5OmS/o4oK3qy5w9dmzeDiD++Gw5Hcw9KnAgtcH5KaBsDy16M0ec+ghp13Q+PXL TeTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gIwvHle+n2X1mQu/sBa72r2guouaN1SD/l3le1h2rXk=; b=2wv+lCWepIkVNTgYRttJSD5wSbPTU9VSkhU0CbaoTPQcMUtyqgTsn6/cpDfbGHf550 pKtnNdr6dWVvjVHC3SyXO/1j2HiIVB1zvjA36hz90T9YCy9JZRyXkmstTh7hoSsEZQe4 nwkzY18llh9zvTxdp/st2DmPF2+/Qd2YZcx7S/G8M40NkzfAKMzjLhjpBVdsBd1wqqrB IijExJM4QaREpYqEViWTl7j0AXEHICiE+7jqZN96I/oWMgvY+ykUURrAkThh8Un8VXSs Hi2dvBqEcUZ75a/erWCyaWvM7Aqs47LTeIfmr7thdjnqtEQpmz/2n4Q7/e9XWhNRyy0h ZebA== X-Gm-Message-State: AOAM530EzoatK2vuA/7SA+0RvORiOphvyKytpZ1V1LbotD7EpLMF8xC7 t3rXVQRcEq1LmrFsThpA8w8= X-Google-Smtp-Source: ABdhPJzdi6Md0ie0GOTMZr35izgM3gdVIkqtDp5YdEOZQonq9YZhxo59/FPb4+1PCMB9SDDABsbx5g== X-Received: by 2002:a17:906:414f:b0:711:ce99:69ec with SMTP id l15-20020a170906414f00b00711ce9969ecmr19398213ejk.724.1654781055196; Thu, 09 Jun 2022 06:24:15 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id i2-20020a056402054200b004315050d7dfsm8360263edx.81.2022.06.09.06.24.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 06:24:14 -0700 (PDT) From: Ansuel Smith To: Manivannan Sadhasivam , Andy Gross , Bjorn Andersson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , linux-mtd@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ansuel Smith Subject: [PATCH v6 1/3] mtd: nand: raw: qcom_nandc: reorder qcom_nand_host struct Date: Thu, 9 Jun 2022 15:23:42 +0200 Message-Id: <20220609132344.17548-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609132344.17548-1-ansuelsmth@gmail.com> References: <20220609132344.17548-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Reorder qcom_nand_host to save holes in the struct. Signed-off-by: Ansuel Smith --- drivers/mtd/nand/raw/qcom_nandc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 1a77542c6d67..7fbbd3e7784c 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -431,11 +431,12 @@ struct qcom_nand_controller { * and reserved bytes * @cw_data: the number of bytes within a codeword protected * by ECC + * @ecc_bytes_hw: ECC bytes used by controller hardware for this + * chip + * * @use_ecc: request the controller to use ECC for the * upcoming read/write * @bch_enabled: flag to tell whether BCH ECC mode is used - * @ecc_bytes_hw: ECC bytes used by controller hardware for this - * chip * @status: value to be returned if NAND_CMD_STATUS command * is executed * @last_command: keeps track of last command on this chip. used @@ -452,11 +453,12 @@ struct qcom_nand_host { int cs; int cw_size; int cw_data; - bool use_ecc; - bool bch_enabled; int ecc_bytes_hw; int spare_bytes; int bbm_size; + + bool use_ecc; + bool bch_enabled; u8 status; int last_command; From patchwork Thu Jun 9 13:23:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12875564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F547C43334 for ; Thu, 9 Jun 2022 13:24:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343830AbiFINYW (ORCPT ); Thu, 9 Jun 2022 09:24:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343784AbiFINYU (ORCPT ); Thu, 9 Jun 2022 09:24:20 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AA1A2600; Thu, 9 Jun 2022 06:24:18 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id v1so36771368ejg.13; Thu, 09 Jun 2022 06:24:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=h1crhyNkxdVEN3CIxYVK7t53ZLK9qDm4UCcsQqJ+Rts=; b=pioTNJHBVbpcPvAVlnA3Q0cqli37oqdjpdca2x8CUHWxtVwwLuPVKVE4iBB4+MVKyi 6H4B/5G+opxYnMVZJmdfdwmX08lm/LvuoEGsj0BAhxDIyh1y7NzqgGYLsEVBq/qTrEmk pFXQ9hlmzeCKUsioteKcbVWYjkRbgVZtvpkPiBwaGbiRhaZ+HprAvJUHirPrjxf12sU1 Mowt2c6QsIpJJL1M1AkZf1YeJLdfQc+ta/5TYNMip/SGdqfyPwkzUS++lVokcQ5i0gMZ 5pMcA2yRQ5Soa/Q66dC37V4Snsqysxp0HDmj9xQ+6J8e2dXpqgJwhKK9VegRC+nAz80D H6uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=h1crhyNkxdVEN3CIxYVK7t53ZLK9qDm4UCcsQqJ+Rts=; b=539Soi0t+3ZLjKueS/H49ZJzBQvbt2/gUb17Yh0DIYbdZ0fe4EhOVV6H4lFBTsm7D6 /LO/TP3alA8vc+Rgv3mswNKfXSLZrWjBM7lzBVyVzv7kbO4bpZiydZGOKIVrHRUydweF BK2iCCDtS0QglAqxP+KK+xOeb1gDR/qCcdVI6kF5SinxuM0f1xw3kLlYpb9MepBoeHS0 0A6neXLiRLWtSAhzBwNbKHNhIgRtjO7iSiT9lZrv+rIkuD3EUmZvY1o8RdzJCIKWxqi4 ApTE/FVRv1WIgMgnPq+xq7BsJlCYKPK8X/ZWcxO6JpaZa4phgWzCHhMHWx/7ougsOH+e 7IkA== X-Gm-Message-State: AOAM533xbwVl+SEI2jY0Mj4XSrgQ+/3cbQEff7rFptGOgY9mk5N81eSZ lCn182p7PkWPTGq/V9WywuQ= X-Google-Smtp-Source: ABdhPJxoHTEbLyuwFopQW13K9S6opBZJnCprTRSR+I/lRaicgiQ4ygq8ugA6bX9xqCbxXfqfvNu+kg== X-Received: by 2002:a17:907:9496:b0:711:f459:664 with SMTP id dm22-20020a170907949600b00711f4590664mr7676144ejc.704.1654781056564; Thu, 09 Jun 2022 06:24:16 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id i2-20020a056402054200b004315050d7dfsm8360263edx.81.2022.06.09.06.24.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 06:24:16 -0700 (PDT) From: Ansuel Smith To: Manivannan Sadhasivam , Andy Gross , Bjorn Andersson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , linux-mtd@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ansuel Smith Subject: [PATCH v6 2/3] mtd: nand: raw: qcom_nandc: add support for unprotected spare data pages Date: Thu, 9 Jun 2022 15:23:43 +0200 Message-Id: <20220609132344.17548-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609132344.17548-1-ansuelsmth@gmail.com> References: <20220609132344.17548-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org IPQ8064 nand have special pages where a different layout scheme is used. These special page are used by boot partition and on reading them lots of warning are reported about wrong ECC data and if written to results in broken data and not bootable device. The layout scheme used by these special page consist in using 512 bytes as the codeword size (even for the last codeword) while writing to CFG0 register. This forces the NAND controller to unprotect the 4 bytes of spare data. Since the kernel is unaware of this different layout for these special page, it does try to protect the spare data too during read/write and warn about CRC errors. Add support for this by permitting the user to declare these special pages in dts by declaring offset and size of the partition. The driver internally will convert these value to nand pages. On user read/write the page is checked and if it's a boot page the correct layout is used. Signed-off-by: Ansuel Smith --- drivers/mtd/nand/raw/qcom_nandc.c | 204 +++++++++++++++++++++++++++++- 1 file changed, 199 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 7fbbd3e7784c..29a16534bee3 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -80,8 +80,10 @@ #define DISABLE_STATUS_AFTER_WRITE 4 #define CW_PER_PAGE 6 #define UD_SIZE_BYTES 9 +#define UD_SIZE_BYTES_MASK GENMASK(18, 9) #define ECC_PARITY_SIZE_BYTES_RS 19 #define SPARE_SIZE_BYTES 23 +#define SPARE_SIZE_BYTES_MASK GENMASK(26, 23) #define NUM_ADDR_CYCLES 27 #define STATUS_BFR_READ 30 #define SET_RD_MODE_AFTER_STATUS 31 @@ -102,6 +104,7 @@ #define ECC_MODE 4 #define ECC_PARITY_SIZE_BYTES_BCH 8 #define ECC_NUM_DATA_BYTES 16 +#define ECC_NUM_DATA_BYTES_MASK GENMASK(25, 16) #define ECC_FORCE_CLK_OPEN 30 /* NAND_DEV_CMD1 bits */ @@ -418,6 +421,19 @@ struct qcom_nand_controller { const struct qcom_nandc_props *props; }; +/* + * NAND special boot partitions + * + * @page_offset: offset of the partition where spare data is not protected + * by ECC (value in pages) + * @page_offset: size of the partition where spare data is not protected + * by ECC (value in pages) + */ +struct qcom_nand_boot_partition { + u32 page_offset; + u32 page_size; +}; + /* * NAND chip structure * @@ -434,6 +450,8 @@ struct qcom_nand_controller { * @ecc_bytes_hw: ECC bytes used by controller hardware for this * chip * + * @codeword_fixup: keep track of the current layout used by + * the driver for read/write operation. * @use_ecc: request the controller to use ECC for the * upcoming read/write * @bch_enabled: flag to tell whether BCH ECC mode is used @@ -445,6 +463,11 @@ struct qcom_nand_controller { * @cfg0, cfg1, cfg0_raw..: NANDc register configurations needed for * ecc/non-ecc mode for the current nand flash * device + * + * @nr_boot_partitions: count of the boot partitions where spare data is not + * protected by ECC + * @boot_partitions: array of boot partitions where offset and size of the + * boot partitions are stored */ struct qcom_nand_host { struct nand_chip chip; @@ -457,6 +480,7 @@ struct qcom_nand_host { int spare_bytes; int bbm_size; + bool codeword_fixup; bool use_ecc; bool bch_enabled; u8 status; @@ -468,6 +492,9 @@ struct qcom_nand_host { u32 ecc_bch_cfg; u32 clrflashstatus; u32 clrreadstatus; + + int nr_boot_partitions; + struct qcom_nand_boot_partition *boot_partitions; }; /* @@ -477,6 +504,7 @@ struct qcom_nand_host { * @is_bam - whether NAND controller is using BAM * @is_qpic - whether NAND CTRL is part of qpic IP * @qpic_v2 - flag to indicate QPIC IP version 2 + * @use_codeword_fixup - whether NAND has different layout for boot partitions * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset */ struct qcom_nandc_props { @@ -484,6 +512,7 @@ struct qcom_nandc_props { bool is_bam; bool is_qpic; bool qpic_v2; + bool use_codeword_fixup; u32 dev_cmd_reg_start; }; @@ -1703,7 +1732,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (qcom_nandc_is_last_cw(ecc, cw)) { + if (qcom_nandc_is_last_cw(ecc, cw) && !host->codeword_fixup) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) * 4); oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + @@ -1784,7 +1813,7 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf, } for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { - if (qcom_nandc_is_last_cw(ecc, cw)) { + if (qcom_nandc_is_last_cw(ecc, cw) && !host->codeword_fixup) { data_size = ecc->size - ((ecc->steps - 1) * 4); oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; } else { @@ -1942,7 +1971,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (qcom_nandc_is_last_cw(ecc, i)) { + if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2039,6 +2068,78 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) return ret; } +static bool qcom_nandc_is_boot_partition(struct qcom_nand_host *host, int page) +{ + struct qcom_nand_boot_partition *boot_partition; + u32 start, end; + int i; + + /* + * Since the frequent access will be to the non-boot partitions like rootfs, + * optimize the page check by: + + * 1. Checking if the page lies after the last boot partition. + * 2. Checking from the boot partition end. + * + * This comes from the fact that an example partition table is: + * mtd0: 00c80000 00020000 "qcadata" (require codeword fix) + * mtd1: 00500000 00020000 "APPSBL" (require codeword fix) + * mtd2: 00080000 00020000 "APPSBLENV" (doesn't require codeword fix) + * mtd3: 00140000 00020000 "art" (doesn't require codeword fix) + * mtd4: 00140000 00020000 "artbak" (doesn't require codeword fix) + * mtd5: 00400000 00020000 "kernel" (doesn't require codeword fix) + * mtd6: 06080000 00020000 "ubi" (doesn't require codeword fix) + * mtd7: 00700000 00020000 "reserve" (doesn't require codeword fix) + * + * where the boot partition are always the first partition and rootfs + * partition are at the end. + * + * Defining a big single boot partition is not possible since some + * device have the following partition table: + * mtd0: 00c80000 00020000 "qcadata" (require codeword fix) + * mtd1: 00500000 00020000 "APPSBL" (require codeword fix) + * mtd2: 00080000 00020000 "APPSBLENV" (doesn't require codeword fix) + * mtd3: 00140000 00020000 "APPSBL2" (require codeword fix) + * + * where a backup partition is placed after a partition where the + * codeword fix should not be used. + */ + for (i = host->nr_boot_partitions - 1; i >= 0; i--) { + boot_partition = &host->boot_partitions[i]; + start = boot_partition->page_offset; + end = start + boot_partition->page_size; + + if (page < end && page >= start) + return true; + } + + return false; +} + +static void +qcom_nandc_codeword_fixup(struct qcom_nand_host *host, int page) +{ + bool codeword_fixup = qcom_nandc_is_boot_partition(host, page); + + /* Skip conf write if we are already in the correct mode */ + if (codeword_fixup == host->codeword_fixup) + return; + + host->codeword_fixup = codeword_fixup; + + host->cw_data = codeword_fixup ? 512 : 516; + host->spare_bytes = host->cw_size - host->ecc_bytes_hw - + host->bbm_size - host->cw_data; + + host->cfg0 &= ~(SPARE_SIZE_BYTES_MASK | UD_SIZE_BYTES_MASK); + host->cfg0 |= host->spare_bytes << SPARE_SIZE_BYTES | + host->cw_data << UD_SIZE_BYTES; + + host->ecc_bch_cfg &= ~ECC_NUM_DATA_BYTES_MASK; + host->ecc_bch_cfg |= host->cw_data << ECC_NUM_DATA_BYTES; + host->ecc_buf_cfg = (host->cw_data - 1) << NUM_STEPS; +} + /* implements ecc->read_page() */ static int qcom_nandc_read_page(struct nand_chip *chip, uint8_t *buf, int oob_required, int page) @@ -2047,6 +2148,9 @@ static int qcom_nandc_read_page(struct nand_chip *chip, uint8_t *buf, struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); u8 *data_buf, *oob_buf = NULL; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + nand_read_page_op(chip, page, 0, NULL, 0); data_buf = buf; oob_buf = oob_required ? chip->oob_poi : NULL; @@ -2066,6 +2170,9 @@ static int qcom_nandc_read_page_raw(struct nand_chip *chip, uint8_t *buf, int cw, ret; u8 *data_buf = buf, *oob_buf = chip->oob_poi; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + for (cw = 0; cw < ecc->steps; cw++) { ret = qcom_nandc_read_cw_raw(mtd, chip, data_buf, oob_buf, page, cw); @@ -2086,6 +2193,9 @@ static int qcom_nandc_read_oob(struct nand_chip *chip, int page) struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); struct nand_ecc_ctrl *ecc = &chip->ecc; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + clear_read_regs(nandc); clear_bam_transaction(nandc); @@ -2106,6 +2216,9 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, u8 *data_buf, *oob_buf; int i, ret; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + nand_prog_page_begin_op(chip, page, 0, NULL, 0); clear_read_regs(nandc); @@ -2121,7 +2234,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (qcom_nandc_is_last_cw(ecc, i)) { + if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2178,6 +2291,9 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, u8 *data_buf, *oob_buf; int i, ret; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + nand_prog_page_begin_op(chip, page, 0, NULL, 0); clear_read_regs(nandc); clear_bam_transaction(nandc); @@ -2196,7 +2312,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (qcom_nandc_is_last_cw(ecc, i)) { + if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) << 2); oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + @@ -2256,6 +2372,9 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) int data_size, oob_size; int ret; + if (host->nr_boot_partitions) + qcom_nandc_codeword_fixup(host, page); + host->use_ecc = true; clear_bam_transaction(nandc); @@ -2904,6 +3023,74 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) static const char * const probes[] = { "cmdlinepart", "ofpart", "qcomsmem", NULL }; +static int qcom_nand_host_parse_boot_partitions(struct qcom_nand_controller *nandc, + struct qcom_nand_host *host, + struct device_node *dn) +{ + struct nand_chip *chip = &host->chip; + struct mtd_info *mtd = nand_to_mtd(chip); + struct qcom_nand_boot_partition *boot_partition; + struct device *dev = nandc->dev; + int partitions_count, i, j, ret; + + if (!of_find_property(dn, "qcom,boot-partitions", NULL)) + return 0; + + partitions_count = of_property_count_u32_elems(dn, "qcom,boot-partitions"); + if (partitions_count <= 0) { + dev_err(dev, "Error parsing boot partition\n"); + return ret; + } + + host->nr_boot_partitions = partitions_count / 2; + host->boot_partitions = devm_kcalloc(dev, host->nr_boot_partitions, + sizeof(*host->boot_partitions), GFP_KERNEL); + if (!host->boot_partitions) { + host->nr_boot_partitions = 0; + return -ENOMEM; + } + + for (i = 0, j = 0; i < host->nr_boot_partitions; i++, j += 2) { + boot_partition = &host->boot_partitions[i]; + + ret = of_property_read_u32_index(dn, "qcom,boot-partitions", j, + &boot_partition->page_offset); + if (ret) { + dev_err(dev, "Error parsing boot partition offset at index %d", i); + host->nr_boot_partitions = 0; + return ret; + } + + if (boot_partition->page_offset % mtd->writesize) { + dev_err(dev, "Boot partition offset not multiple of writesize at index %i\n", + i); + host->nr_boot_partitions = 0; + return -EINVAL; + } + /* Convert offset to nand pages */ + boot_partition->page_offset /= mtd->writesize; + + ret = of_property_read_u32_index(dn, "qcom,boot-partitions", j + 1, + &boot_partition->page_size); + if (ret) { + dev_err(dev, "Error parsing boot partition size at index %d\n", i); + host->nr_boot_partitions = 0; + return ret; + } + + if (boot_partition->page_size % mtd->writesize) { + dev_err(dev, "Boot partition size not multiple of writesize at index %i", + i); + host->nr_boot_partitions = 0; + return -EINVAL; + } + /* Convert size to nand pages */ + boot_partition->page_size /= mtd->writesize; + } + + return 0; +} + static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, struct qcom_nand_host *host, struct device_node *dn) @@ -2972,6 +3159,12 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, if (ret) nand_cleanup(chip); + if (nandc->props->use_codeword_fixup) { + ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn); + if (ret) + return ret; + } + return ret; } @@ -3137,6 +3330,7 @@ static int qcom_nandc_remove(struct platform_device *pdev) static const struct qcom_nandc_props ipq806x_nandc_props = { .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT), .is_bam = false, + .use_codeword_fixup = true, .dev_cmd_reg_start = 0x0, }; From patchwork Thu Jun 9 13:23:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 12875565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A250CC43334 for ; Thu, 9 Jun 2022 13:24:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343816AbiFINYX (ORCPT ); Thu, 9 Jun 2022 09:24:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343786AbiFINYV (ORCPT ); Thu, 9 Jun 2022 09:24:21 -0400 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4DD036B69; Thu, 9 Jun 2022 06:24:19 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id h19so31227910edj.0; Thu, 09 Jun 2022 06:24:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6jeqtgRl8bKHnXZ4AwxPt+xAQ0F0PxiC5aWs7JdMOrY=; b=cJVhmrHYyT63kIWknwWNHq8H3Fm9koj9Te576ocCrSOqv18WrgBUMotLdhsN3HIdgM /aoYBLe/1EthBKwzLMOnDMzMig7pgkcWUDz16SM9QlGmsvii3FqSwftw9IOpua1hqHWt 25Lmz9S4wLtucB+FC0jlpNDPXt28Iw7T+JqGvOtDSU9eNPMNLImvrJ4EyIofVj3wjzF/ NmsQbdligcS3Jl35T6bp6lduzJbYTPUS2LCFpZA5Koky7S9y1t5KWRyGqqGgjh0huMkj 4YDSGmibIrJm/1RE4XIvWQzFiHPn6y7ILU3OChbYMf6D77+KLKMiE9opqoyC8nXEIaNw Emdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6jeqtgRl8bKHnXZ4AwxPt+xAQ0F0PxiC5aWs7JdMOrY=; b=HBP1A7FG+fFH5bAACeWi5dsPQ/70i89IIsn+knSkWTKeF8cxYwcD1XY7rbHId2/78v aoJpy5ZF9LkaiiQ6eY2jfUekQRqqtgBeZfKpv7G2Q301dH0kx1Eo06zEjjMrJyffiqJe MoWuJ4sT11MMDqX63BZ53MQeigQhzcBPdnkbVFUSPC1VpN300LbYBn7huhb/agMABfTt lGvudZ4RJ6zdWYmIlVyR3DHxbv/13IKfS8xYsQ+1XYK/AFkHlNGvwGtlSG8dYpFDWk5w 9NtgY3TqmKM6g5OHul2s7HTyHH+v91xzEMyWSbXwRXvsS6Xq40A4CTTqbw3gHqC8tIA0 M7NA== X-Gm-Message-State: AOAM5315kcf3rOi2Wcc2udJKQcBAjeOPyx3cZAWRV4uWWRZ55sIaxeiV MsNHDCSP5J49gjRRK+MhhAs= X-Google-Smtp-Source: ABdhPJz4eKUEq7ZrMsvoEKZtpxBHOSayxyiXJ2PgF4vC9W0d68Yh4tOffD3uKBEr3qTbYLCZAaDwpA== X-Received: by 2002:a05:6402:31fa:b0:42d:cd6d:c8fd with SMTP id dy26-20020a05640231fa00b0042dcd6dc8fdmr44609520edb.347.1654781058277; Thu, 09 Jun 2022 06:24:18 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id i2-20020a056402054200b004315050d7dfsm8360263edx.81.2022.06.09.06.24.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 06:24:17 -0700 (PDT) From: Ansuel Smith To: Manivannan Sadhasivam , Andy Gross , Bjorn Andersson , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , linux-mtd@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ansuel Smith Subject: [PATCH v6 3/3] dt-bindings: mtd: qcom_nandc: document qcom,boot-partitions binding Date: Thu, 9 Jun 2022 15:23:44 +0200 Message-Id: <20220609132344.17548-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609132344.17548-1-ansuelsmth@gmail.com> References: <20220609132344.17548-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Document new qcom,boot-partition binding used to apply special read/write layout to boot partitions. QCOM apply a special layout where spare data is not protected by ECC for some special pages (used for boot partition). Add Documentation on how to declare these special pages. Signed-off-by: Ansuel Smith Reviewed-by: Manivannan Sadhasivam Reviewed-by: Rob Herring --- .../devicetree/bindings/mtd/qcom,nandc.yaml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml index 84ad7ff30121..482a2c068740 100644 --- a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml +++ b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml @@ -102,6 +102,31 @@ allOf: - const: rx - const: cmd + - if: + properties: + compatible: + contains: + enum: + - qcom,ipq806x-nand + + then: + properties: + qcom,boot-partitions: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: offset + - description: size + description: + Boot partition use a different layout where the 4 bytes of spare + data are not protected by ECC. Use this to declare these special + partitions by defining first the offset and then the size. + + It's in the form of + and should be declared in ascending order. + + Refer to the ipq8064 example on how to use this special binding. + required: - compatible - reg @@ -135,6 +160,8 @@ examples: nand-ecc-strength = <4>; nand-bus-width = <8>; + qcom,boot-partitions = <0x0 0x58a0000>; + partitions { compatible = "fixed-partitions"; #address-cells = <1>;