Message ID | 20231031120307.1600689-2-quic_mdalam@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b90f:0:b0:403:3b70:6f57 with SMTP id t15csp183944vqg; Tue, 31 Oct 2023 05:04:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IElloXryFUZuv6WGeSFDMmXgfq3wmfRG7MNCUGg6Q8imiTldl0Z7Ff0KW8d9c3eNj62X4V9 X-Received: by 2002:a17:902:e848:b0:1c2:193e:1126 with SMTP id t8-20020a170902e84800b001c2193e1126mr3026948plg.28.1698753860741; Tue, 31 Oct 2023 05:04:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698753860; cv=none; d=google.com; s=arc-20160816; b=Pm5CqPSHfPgY3mx7QrEpNJxmCW3PisebwlXXNRk0CPO9Ubu3X0dqBskuieo5bGn7wd ROSQcdz5pZ1KIebWZhOh7EqJCqswnvVZCK5UnfMXBtglVm3QA//nq1q9STq4Md8RZCFE PbzpYG3ArWdFBXkpm03lsiSIRhN3K23HwXyeRRFBDZ3ktUW7nVZprKS4wPcSaP/AZQaX ESizrIw883NSG0WUswS6ELppTHzMkBVxpvxyepJp41SfBGMOoqU2jR6k73PlkwyUeePF XkSSB7/aVFKSl3QWqlXd4A9HDQsuvaJwDAvSMrafQZfprGEx7ZM6LSynOZPNnkQeBkvr mCLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=AuA+t3/r+JWkHJYnQkTl6/U/0J6YgPnNxPXKN17FIh8=; fh=gv5Z3UYh4OJrEQHzuaRSDOa6LHGr3r586M32+msCC1g=; b=juKRLkvpK9LZImfNjLMWourw59iXuEPKbbbOIZvZMW5YP1IuOjW1KJcuyBhEXHHUUx ATsb1i/p6LGWRqjiEguzPz9bdyF6nPTLp8foBjs+VnjxoumUkiHUMQ/H1I43VNigREIT CmOvS5xZpvrTldRbx/Jx0cJtZd/k+xYdXkOstaRIDpQLgaKSBqoyJgQmtHbAQFI4DkGI QrAGF05hmwydYUKQQ98G4BYtl2kBDpg6hBJjMXBEQAeGrWUMTEVA7SCkrrL223uvrJye F2Qi0JhgcqYZGkYpw1TCOaDfpGu5ZlSr8DwpuWB5YTo6boJu9BqiZicfHqov+fWgRvh3 2TeQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=eUQ3E53H; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id k17-20020a170902c41100b001cc5cbf50dbsi957386plk.493.2023.10.31.05.04.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Oct 2023 05:04:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=eUQ3E53H; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id AD8D980C4DB6; Tue, 31 Oct 2023 05:04:16 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344118AbjJaMEI (ORCPT <rfc822;chrisjones.unixmen@gmail.com> + 33 others); Tue, 31 Oct 2023 08:04:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43786 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344186AbjJaMEB (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 31 Oct 2023 08:04:01 -0400 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78F0A5586; Tue, 31 Oct 2023 05:03:58 -0700 (PDT) Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 39VBo1qO031040; Tue, 31 Oct 2023 12:03:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=qcppdkim1; bh=AuA+t3/r+JWkHJYnQkTl6/U/0J6YgPnNxPXKN17FIh8=; b=eUQ3E53H8zHWCLYUq67ehRCwxTDm17SfNL6iWxzPoR2gTvF7PWEd2+ZvfnaM2RgqLVjY Y0zujWxAoZSi0lcKi4Eeh9AKt4QwHcQIOgbvTlP0k8qil32nLq3uDA0hKpvNV8BCPYtB YA9VyHApdN1on2GhltGwtcW3Qih+QGOkIuf5MJLK3PwdKmaKm63C80uu+ZeSRrzDC8OA t+p5uOdRDZ6tBicmVXz/+AHAXsOcLeTysnVK+aQkbHkpjUT09SthVm+nmBGnj3gpl97h VsZCq0+jGd9mlHU1xVkg2CLtPEJ73rf6E4lxWc4S24lFK1ujBPaof4yMYe6jhOPfvwQL 7w== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3u2dey2thn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Oct 2023 12:03:13 +0000 Received: from pps.filterd (APBLRPPMTA02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 39VC3AH9005259; Tue, 31 Oct 2023 12:03:10 GMT Received: from pps.reinject (localhost [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTPS id 3u0uckvvp4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Oct 2023 12:03:10 +0000 Received: from APBLRPPMTA02.qualcomm.com (APBLRPPMTA02.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 39VC3AjF005252; Tue, 31 Oct 2023 12:03:10 GMT Received: from hu-devc-blr-u22-a.qualcomm.com (hu-mdalam-blr.qualcomm.com [10.131.36.157]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTPS id 39VC3AnZ005251 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Oct 2023 12:03:10 +0000 Received: by hu-devc-blr-u22-a.qualcomm.com (Postfix, from userid 466583) id 9B6D64162D; Tue, 31 Oct 2023 17:33:09 +0530 (+0530) From: Md Sadre Alam <quic_mdalam@quicinc.com> To: agross@kernel.org, andersson@kernel.org, konrad.dybcio@linaro.org, robh+dt@kernel.org, conor+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, broonie@kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, linux-spi@vger.kernel.org, quic_srichara@quicinc.com, qpic_varada@quicinc.com Cc: quic_mdalam@quicinc.com Subject: [RFC PATCH 1/5] mtd: nand: ecc-qcom: Add support for ECC Engine Driver Date: Tue, 31 Oct 2023 17:33:03 +0530 Message-Id: <20231031120307.1600689-2-quic_mdalam@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231031120307.1600689-1-quic_mdalam@quicinc.com> References: <20231031120307.1600689-1-quic_mdalam@quicinc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: LA_jYFVdTJG1wQuJR_Athd-pxEwgUZVJ X-Proofpoint-GUID: LA_jYFVdTJG1wQuJR_Athd-pxEwgUZVJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-10-31_01,2023-10-31_03,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 suspectscore=0 spamscore=0 bulkscore=0 mlxscore=0 phishscore=0 priorityscore=1501 impostorscore=0 mlxlogscore=999 adultscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2310240000 definitions=main-2310310094 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Tue, 31 Oct 2023 05:04:16 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781272528657720146 X-GMAIL-MSGID: 1781272528657720146 |
Series |
Add QPIC SPI NAND driver support
|
|
Commit Message
Md Sadre Alam
Oct. 31, 2023, 12:03 p.m. UTC
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> --- drivers/mtd/nand/Kconfig | 7 ++ drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 drivers/mtd/nand/ecc-qcom.c
Comments
Hi, quic_mdalam@quicinc.com wrote on Tue, 31 Oct 2023 17:33:03 +0530: Commit log is missing. > Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> > Signed-off-by: Sricharan R <quic_srichara@quicinc.com> If Sricharan is a co developer you need to use the right tags. Please have a look at the documentation. Using the two SoB here does not mean anything. > --- > drivers/mtd/nand/Kconfig | 7 ++ > drivers/mtd/nand/Makefile | 1 + > drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 206 insertions(+) > create mode 100644 drivers/mtd/nand/ecc-qcom.c > > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig > index 5b0c2c95f10c..333cec8187c8 100644 > --- a/drivers/mtd/nand/Kconfig > +++ b/drivers/mtd/nand/Kconfig > @@ -61,6 +61,13 @@ config MTD_NAND_ECC_MEDIATEK > help > This enables support for the hardware ECC engine from Mediatek. > > +config MTD_NAND_ECC_QCOM > + tristate "Qualcomm hardware ECC engine" > + depends on ARCH_QCOM Same comment as Mark regarding COMPILE_TEST > + select MTD_NAND_ECC > + help > + This enables support for the hardware ECC engine from Qualcomm. > + > endmenu > > endmenu > diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile > index 19e1291ac4d5..c73b8a3456ec 100644 > --- a/drivers/mtd/nand/Makefile > +++ b/drivers/mtd/nand/Makefile > @@ -3,6 +3,7 @@ > nandcore-objs := core.o bbt.o > obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o > obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o > +obj-$(CONFIG_MTD_NAND_ECC_QCOM) += ecc-qcom.o qpic_common.o > > obj-y += onenand/ > obj-y += raw/ > diff --git a/drivers/mtd/nand/ecc-qcom.c b/drivers/mtd/nand/ecc-qcom.c > new file mode 100644 > index 000000000000..a85423ed368a > --- /dev/null > +++ b/drivers/mtd/nand/ecc-qcom.c > @@ -0,0 +1,198 @@ > +// SPDX-License-Identifier: GPL-2.0 OR MIT > +/* > + * QCOM ECC Engine Driver. > + * Copyright (C) 2023 Qualcomm Inc. > + * Authors: Md sadre Alam <quic_mdalam@quicinc.com> > + * Sricharan R <quic_srichara@quicinc.com> > + */ > + > +#include <linux/platform_device.h> > +#include <linux/dma-mapping.h> > +#include <linux/interrupt.h> > +#include <linux/clk.h> > +#include <linux/module.h> > +#include <linux/iopoll.h> > +#include <linux/of.h> > +#include <linux/of_platform.h> > +#include <linux/mutex.h> > +#include <linux/mtd/nand-qpic-common.h> > + > + > + > +/* ECC modes supported by the controller */ > +#define ECC_NONE BIT(0) > +#define ECC_RS_4BIT BIT(1) > +#define ECC_BCH_4BIT BIT(2) > +#define ECC_BCH_8BIT BIT(3) > + > +struct qpic_ecc_caps { > + u32 err_mask; > + u32 err_shift; > + const u8 *ecc_strength; > + const u32 *ecc_regs; > + u8 num_ecc_strength; > + u8 ecc_mode_shift; > + u32 parity_bits; > + int pg_irq_sel; > +}; > + > + > +struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) > +{ > + return container_of(chip, struct qcom_nand_host, chip); > +} > +EXPORT_SYMBOL(to_qcom_nand_host); > + > +struct qcom_nand_controller * > +get_qcom_nand_controller(struct nand_chip *chip) > +{ > + return container_of(chip->controller, struct qcom_nand_controller, > + controller); > +} > +EXPORT_SYMBOL(get_qcom_nand_controller); > + > +static struct qpic_ecc *qpic_ecc_get(struct device_node *np) > +{ > + struct platform_device *pdev; > + struct qpic_ecc *ecc; > + > + pdev = of_find_device_by_node(np); > + if (!pdev) > + return ERR_PTR(-EPROBE_DEFER); > + > + ecc = platform_get_drvdata(pdev); > + if (!ecc) { > + put_device(&pdev->dev); > + return ERR_PTR(-EPROBE_DEFER); > + } > + > + return ecc; > +} > + > +struct qpic_ecc *of_qpic_ecc_get(struct device_node *of_node) > +{ > + struct qpic_ecc *ecc = NULL; > + struct device_node *np; > + > + np = of_parse_phandle(of_node, "nand-ecc-engine", 0); > + /* for backward compatibility */ There is no backward compatibility to handle upstream > + if (!np) > + np = of_parse_phandle(of_node, "ecc-engine", 0); > + if (np) { > + ecc = qpic_ecc_get(np); > + of_node_put(np); > + } > + > + return ecc; > +} > +EXPORT_SYMBOL(of_qpic_ecc_get); > + > +int qcom_ecc_config(struct qpic_ecc *ecc, int ecc_strength, > + bool wide_bus) > +{ > + ecc->ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT); > + > + if (ecc_strength >= 8) { If your engine does not support more than an 8-bit strength this condition seems a bit strange. > + /* 8 bit ECC defaults to BCH ECC on all platforms */ > + ecc->bch_enabled = true; > + ecc->ecc_mode = 1; ecc_modes above, ecc_mode here, not very clear what this is. Please give meaningful names to your variables, not just the bit name that this is capturing because here it's unclear what this is. > + > + if (wide_bus) { > + ecc->ecc_bytes_hw = 14; > + ecc->spare_bytes = 0; Spare bytes depend on the flash, you can't use constant values like that. I also don't understand what wide_bus is and why it has an impact of only 1 on the number of ECC bytes. Please make all this more explicit. > + ecc->bbm_size = 2; > + } else { > + ecc->ecc_bytes_hw = 13; > + ecc->spare_bytes = 2; > + ecc->bbm_size = 1; > + } > + } else { > + /* > + * if the controller supports BCH for 4 bit ECC, the controller > + * uses lesser bytes for ECC. If RS is used, the ECC bytes is > + * always 10 bytes > + */ > + if (ecc->ecc_modes & ECC_BCH_4BIT) { > + /* BCH */ > + ecc->bch_enabled = true; > + ecc->ecc_mode = 0; > + if (wide_bus) { > + ecc->ecc_bytes_hw = 8; > + ecc->spare_bytes = 2; > + ecc->bbm_size = 2; > + } else { > + ecc->ecc_bytes_hw = 7; > + ecc->spare_bytes = 4; > + ecc->bbm_size = 1; > + } > + } else { > + /* RS */ > + ecc->ecc_bytes_hw = 10; > + if (wide_bus) { > + ecc->spare_bytes = 0; > + ecc->bbm_size = 2; > + } else { > + ecc->spare_bytes = 1; > + ecc->bbm_size = 1; > + } > + } > + } > + > + return 0; > +} > +EXPORT_SYMBOL(qcom_ecc_config); Thanks, Miquèl
On 31/10/2023 13:03, Md Sadre Alam wrote: Eh? Empty? > Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> > Signed-off-by: Sricharan R <quic_srichara@quicinc.com> > --- > drivers/mtd/nand/Kconfig | 7 ++ > drivers/mtd/nand/Makefile | 1 + > drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 206 insertions(+) > create mode 100644 drivers/mtd/nand/ecc-qcom.c > ... > + > + return 0; > +} > +EXPORT_SYMBOL(qcom_ecc_config); > + > +void qcom_ecc_enable(struct qcom_ecc *ecc) > +{ > + ecc->use_ecc = true; > +} > +EXPORT_SYMBOL(qcom_ecc_enable); Drop this and all other exports. Nothing here explains the need for them. > + > +void qcom_ecc_disable(struct qcom_ecc *ecc) > +{ > + ecc->use_ecc = false; > +} > +EXPORT_SYMBOL(qcom_ecc_disable); > + > +static const struct of_device_id qpic_ecc_dt_match[] = { > + { > + .compatible = "qcom,ipq9574-ecc", Please run scripts/checkpatch.pl and fix reported warnings. Some warnings can be ignored, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear. Checkpatch is preerquisite. Don't send patches which have obvious issues pointed out by checkpatch. It's a waste of reviewers time. > + }, > + {}, > +}; > + > +static int qpic_ecc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct qpic_ecc *ecc; > + u32 max_eccdata_size; > + > + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); > + if (!ecc) > + return -ENOMEM; > + > + ecc->caps = of_device_get_match_data(dev); > + > + ecc->dev = dev; > + platform_set_drvdata(pdev, ecc); > + dev_info(dev, "probed\n"); No, no such messages. Best regards, Krzysztof
On 10/31/2023 8:58 PM, Miquel Raynal wrote: > Hi, > > quic_mdalam@quicinc.com wrote on Tue, 31 Oct 2023 17:33:03 +0530: > > Commit log is missing. Having a separate device node for ECC was NAK-ed https://www.spinics.net/lists/linux-arm-msm/msg177596.html It is fine to drop this patch ? keep ECC support inlined in both raw nand and Serial nand driver. > >> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> >> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> > > If Sricharan is a co developer you need to use the right tags. Please > have a look at the documentation. Using the two SoB here does not mean > anything Ok will fix > >> --- >> drivers/mtd/nand/Kconfig | 7 ++ >> drivers/mtd/nand/Makefile | 1 + >> drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ >> 3 files changed, 206 insertions(+) >> create mode 100644 drivers/mtd/nand/ecc-qcom.c >> >> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig >> index 5b0c2c95f10c..333cec8187c8 100644 >> --- a/drivers/mtd/nand/Kconfig >> +++ b/drivers/mtd/nand/Kconfig >> @@ -61,6 +61,13 @@ config MTD_NAND_ECC_MEDIATEK >> help >> This enables support for the hardware ECC engine from Mediatek. >> >> +config MTD_NAND_ECC_QCOM >> + tristate "Qualcomm hardware ECC engine" >> + depends on ARCH_QCOM > > Same comment as Mark regarding COMPILE_TEST Ok > >> + select MTD_NAND_ECC >> + help >> + This enables support for the hardware ECC engine from Qualcomm. >> + >> endmenu >> >> endmenu >> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile >> index 19e1291ac4d5..c73b8a3456ec 100644 >> --- a/drivers/mtd/nand/Makefile >> +++ b/drivers/mtd/nand/Makefile >> @@ -3,6 +3,7 @@ >> nandcore-objs := core.o bbt.o >> obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o >> obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o >> +obj-$(CONFIG_MTD_NAND_ECC_QCOM) += ecc-qcom.o qpic_common.o >> >> obj-y += onenand/ >> obj-y += raw/ >> diff --git a/drivers/mtd/nand/ecc-qcom.c b/drivers/mtd/nand/ecc-qcom.c >> new file mode 100644 >> index 000000000000..a85423ed368a >> --- /dev/null >> +++ b/drivers/mtd/nand/ecc-qcom.c >> @@ -0,0 +1,198 @@ >> +// SPDX-License-Identifier: GPL-2.0 OR MIT >> +/* >> + * QCOM ECC Engine Driver. >> + * Copyright (C) 2023 Qualcomm Inc. >> + * Authors: Md sadre Alam <quic_mdalam@quicinc.com> >> + * Sricharan R <quic_srichara@quicinc.com> >> + */ >> + >> +#include <linux/platform_device.h> >> +#include <linux/dma-mapping.h> >> +#include <linux/interrupt.h> >> +#include <linux/clk.h> >> +#include <linux/module.h> >> +#include <linux/iopoll.h> >> +#include <linux/of.h> >> +#include <linux/of_platform.h> >> +#include <linux/mutex.h> >> +#include <linux/mtd/nand-qpic-common.h> >> + >> + >> + >> +/* ECC modes supported by the controller */ >> +#define ECC_NONE BIT(0) >> +#define ECC_RS_4BIT BIT(1) >> +#define ECC_BCH_4BIT BIT(2) >> +#define ECC_BCH_8BIT BIT(3) >> + >> +struct qpic_ecc_caps { >> + u32 err_mask; >> + u32 err_shift; >> + const u8 *ecc_strength; >> + const u32 *ecc_regs; >> + u8 num_ecc_strength; >> + u8 ecc_mode_shift; >> + u32 parity_bits; >> + int pg_irq_sel; >> +}; >> + >> + >> +struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) >> +{ >> + return container_of(chip, struct qcom_nand_host, chip); >> +} >> +EXPORT_SYMBOL(to_qcom_nand_host); >> + >> +struct qcom_nand_controller * >> +get_qcom_nand_controller(struct nand_chip *chip) >> +{ >> + return container_of(chip->controller, struct qcom_nand_controller, >> + controller); >> +} >> +EXPORT_SYMBOL(get_qcom_nand_controller); >> + >> +static struct qpic_ecc *qpic_ecc_get(struct device_node *np) >> +{ >> + struct platform_device *pdev; >> + struct qpic_ecc *ecc; >> + >> + pdev = of_find_device_by_node(np); >> + if (!pdev) >> + return ERR_PTR(-EPROBE_DEFER); >> + >> + ecc = platform_get_drvdata(pdev); >> + if (!ecc) { >> + put_device(&pdev->dev); >> + return ERR_PTR(-EPROBE_DEFER); >> + } >> + >> + return ecc; >> +} >> + >> +struct qpic_ecc *of_qpic_ecc_get(struct device_node *of_node) >> +{ >> + struct qpic_ecc *ecc = NULL; >> + struct device_node *np; >> + >> + np = of_parse_phandle(of_node, "nand-ecc-engine", 0); >> + /* for backward compatibility */ > > There is no backward compatibility to handle upstream Ok will fix in V1 > >> + if (!np) >> + np = of_parse_phandle(of_node, "ecc-engine", 0); >> + if (np) { >> + ecc = qpic_ecc_get(np); >> + of_node_put(np); >> + } >> + >> + return ecc; >> +} >> +EXPORT_SYMBOL(of_qpic_ecc_get); >> + >> +int qcom_ecc_config(struct qpic_ecc *ecc, int ecc_strength, >> + bool wide_bus) >> +{ >> + ecc->ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT); >> + >> + if (ecc_strength >= 8) { > > If your engine does not support more than an 8-bit strength this > condition seems a bit strange. Max ECC supported 8-bit only, forcing it to 8-bit. > >> + /* 8 bit ECC defaults to BCH ECC on all platforms */ >> + ecc->bch_enabled = true; >> + ecc->ecc_mode = 1; > > ecc_modes above, ecc_mode here, not very clear what this is. > Please give meaningful names to your variables, not just the bit name > that this is capturing because here it's unclear what this is. ok will fix in V1 > >> + >> + if (wide_bus) { >> + ecc->ecc_bytes_hw = 14; >> + ecc->spare_bytes = 0; > > Spare bytes depend on the flash, you can't use constant values like > that. Ok will fix in V1 > > I also don't understand what wide_bus is and why it has an impact of > only 1 on the number of ECC bytes. Please make all this more explicit. wide_bus 1 means 16-bit wide and wide_bus 0 means 8-bit wide. there different configuration for ecc config for 16-bit wide bus and 8-bit wide bus. This is recommended configuration by IP team, Will reconfirm this with IP folks and come back. Regards, Alam.
On 03/11/2023 13:06, Md Sadre Alam wrote: > > > On 10/31/2023 8:58 PM, Miquel Raynal wrote: >> Hi, >> >> quic_mdalam@quicinc.com wrote on Tue, 31 Oct 2023 17:33:03 +0530: >> >> Commit log is missing. > > Having a separate device node for ECC was NAK-ed > https://www.spinics.net/lists/linux-arm-msm/msg177596.html It was NAKed because it was not ready for submission. Please perform internal review, which will fix such trivial issues, before posting on mailing lists. Since you did not post any bindings, we could not have even discussion whether this is acceptable or not... Best regards, Krzysztof
On 03/11/2023 13:08, Krzysztof Kozlowski wrote: > On 03/11/2023 13:06, Md Sadre Alam wrote: >> >> >> On 10/31/2023 8:58 PM, Miquel Raynal wrote: >>> Hi, >>> >>> quic_mdalam@quicinc.com wrote on Tue, 31 Oct 2023 17:33:03 +0530: >>> >>> Commit log is missing. >> >> Having a separate device node for ECC was NAK-ed >> https://www.spinics.net/lists/linux-arm-msm/msg177596.html > > It was NAKed because it was not ready for submission. Please perform > internal review, which will fix such trivial issues, before posting on > mailing lists. To clarify: trivial issues including compile-like testing the code, not even on the hardware, but with automated, open-source tools like checkpatch, dtc and dtbs_check. It's like sending driver code which has obvious warnings. Best regards, Krzysztof
On 10/31/2023 10:41 PM, Krzysztof Kozlowski wrote: > On 31/10/2023 13:03, Md Sadre Alam wrote: > > Eh? Empty? QPIC controller has the ecc pipelined so will keep the ecc support inlined in both raw nand and serial nand driver. Droping this driver since device node was NAK-ed https://www.spinics.net/lists/linux-arm-msm/msg177596.html > >> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> >> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> >> --- >> drivers/mtd/nand/Kconfig | 7 ++ >> drivers/mtd/nand/Makefile | 1 + >> drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ >> 3 files changed, 206 insertions(+) >> create mode 100644 drivers/mtd/nand/ecc-qcom.c >> > > ... > >> + >> + return 0; >> +} >> +EXPORT_SYMBOL(qcom_ecc_config); >> + >> +void qcom_ecc_enable(struct qcom_ecc *ecc) >> +{ >> + ecc->use_ecc = true; >> +} >> +EXPORT_SYMBOL(qcom_ecc_enable); > > Drop this and all other exports. Nothing here explains the need for them. > >> + >> +void qcom_ecc_disable(struct qcom_ecc *ecc) >> +{ >> + ecc->use_ecc = false; >> +} >> +EXPORT_SYMBOL(qcom_ecc_disable); >> + >> +static const struct of_device_id qpic_ecc_dt_match[] = { >> + { >> + .compatible = "qcom,ipq9574-ecc", > > Please run scripts/checkpatch.pl and fix reported warnings. Some > warnings can be ignored, but the code here looks like it needs a fix. > Feel free to get in touch if the warning is not clear. > > Checkpatch is preerquisite. Don't send patches which have obvious issues > pointed out by checkpatch. It's a waste of reviewers time. > >> + }, >> + {}, >> +}; >> + >> +static int qpic_ecc_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct qpic_ecc *ecc; >> + u32 max_eccdata_size; >> + >> + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); >> + if (!ecc) >> + return -ENOMEM; >> + >> + ecc->caps = of_device_get_match_data(dev); >> + >> + ecc->dev = dev; >> + platform_set_drvdata(pdev, ecc); >> + dev_info(dev, "probed\n"); > > No, no such messages. > > > > Best regards, > Krzysztof >
On Fri, 3 Nov 2023 at 14:25, Md Sadre Alam <quic_mdalam@quicinc.com> wrote: > > > > On 10/31/2023 10:41 PM, Krzysztof Kozlowski wrote: > > On 31/10/2023 13:03, Md Sadre Alam wrote: > > > > Eh? Empty? > > QPIC controller has the ecc pipelined so will keep the ecc support > inlined in both raw nand and serial nand driver. > > Droping this driver since device node was NAK-ed > https://www.spinics.net/lists/linux-arm-msm/msg177596.html It seems, we have to repeat the same thing again and again: It was not the device node that was NAKed. It was the patch that was NAKed. Please read the emails carefully. And next time please perform dtbs_check, dt_binding_check and checkpatch before sending the patch. It is perfectly fine to ask questions 'like we are getting we are getting this and that issues with the bindings, please advise'. It is not fine to skip that step completely. > > > >> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> > >> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> > >> --- > >> drivers/mtd/nand/Kconfig | 7 ++ > >> drivers/mtd/nand/Makefile | 1 + > >> drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ > >> 3 files changed, 206 insertions(+) > >> create mode 100644 drivers/mtd/nand/ecc-qcom.c > >> > > > > ... > > > >> + > >> + return 0; > >> +} > >> +EXPORT_SYMBOL(qcom_ecc_config); > >> + > >> +void qcom_ecc_enable(struct qcom_ecc *ecc) > >> +{ > >> + ecc->use_ecc = true; > >> +} > >> +EXPORT_SYMBOL(qcom_ecc_enable); > > > > Drop this and all other exports. Nothing here explains the need for them. > > > >> + > >> +void qcom_ecc_disable(struct qcom_ecc *ecc) > >> +{ > >> + ecc->use_ecc = false; > >> +} > >> +EXPORT_SYMBOL(qcom_ecc_disable); > >> + > >> +static const struct of_device_id qpic_ecc_dt_match[] = { > >> + { > >> + .compatible = "qcom,ipq9574-ecc", > > > > Please run scripts/checkpatch.pl and fix reported warnings. Some > > warnings can be ignored, but the code here looks like it needs a fix. > > Feel free to get in touch if the warning is not clear. > > > > Checkpatch is preerquisite. Don't send patches which have obvious issues > > pointed out by checkpatch. It's a waste of reviewers time. > > > >> + }, > >> + {}, > >> +}; > >> + > >> +static int qpic_ecc_probe(struct platform_device *pdev) > >> +{ > >> + struct device *dev = &pdev->dev; > >> + struct qpic_ecc *ecc; > >> + u32 max_eccdata_size; > >> + > >> + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); > >> + if (!ecc) > >> + return -ENOMEM; > >> + > >> + ecc->caps = of_device_get_match_data(dev); > >> + > >> + ecc->dev = dev; > >> + platform_set_drvdata(pdev, ecc); > >> + dev_info(dev, "probed\n"); > > > > No, no such messages. > > > > > > > > Best regards, > > Krzysztof > >
On 11/3/2023 6:03 PM, Dmitry Baryshkov wrote: > On Fri, 3 Nov 2023 at 14:25, Md Sadre Alam <quic_mdalam@quicinc.com> wrote: >> >> >> >> On 10/31/2023 10:41 PM, Krzysztof Kozlowski wrote: >>> On 31/10/2023 13:03, Md Sadre Alam wrote: >>> >>> Eh? Empty? >> >> QPIC controller has the ecc pipelined so will keep the ecc support >> inlined in both raw nand and serial nand driver. >> >> Droping this driver since device node was NAK-ed >> https://www.spinics.net/lists/linux-arm-msm/msg177596.html > > It seems, we have to repeat the same thing again and again: > > It was not the device node that was NAKed. It was the patch that was > NAKed. Please read the emails carefully. > > And next time please perform dtbs_check, dt_binding_check and > checkpatch before sending the patch. > > It is perfectly fine to ask questions 'like we are getting we are > getting this and that issues with the bindings, please advise'. It is > not fine to skip that step completely. Sorry in V1 will run all basic checks. Based on below feedback [1] and NAK on the device node patch got idea of having separate device node for ECC is not acceptable. Could you please help to clarify that. Since ECC block is inlined with QPIC controller so is the below device node acceptable ? bch: qpic_ecc { compatible = "qcom,ipq9574-ecc"; status = "ok"; }; [1] https://www.spinics.net/lists/linux-arm-msm/msg177525.html > >>> >>>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> >>>> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> >>>> --- >>>> drivers/mtd/nand/Kconfig | 7 ++ >>>> drivers/mtd/nand/Makefile | 1 + >>>> drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ >>>> 3 files changed, 206 insertions(+) >>>> create mode 100644 drivers/mtd/nand/ecc-qcom.c >>>> >>> >>> ... >>> >>>> + >>>> + return 0; >>>> +} >>>> +EXPORT_SYMBOL(qcom_ecc_config); >>>> + >>>> +void qcom_ecc_enable(struct qcom_ecc *ecc) >>>> +{ >>>> + ecc->use_ecc = true; >>>> +} >>>> +EXPORT_SYMBOL(qcom_ecc_enable); >>> >>> Drop this and all other exports. Nothing here explains the need for them. >>> >>>> + >>>> +void qcom_ecc_disable(struct qcom_ecc *ecc) >>>> +{ >>>> + ecc->use_ecc = false; >>>> +} >>>> +EXPORT_SYMBOL(qcom_ecc_disable); >>>> + >>>> +static const struct of_device_id qpic_ecc_dt_match[] = { >>>> + { >>>> + .compatible = "qcom,ipq9574-ecc", >>> >>> Please run scripts/checkpatch.pl and fix reported warnings. Some >>> warnings can be ignored, but the code here looks like it needs a fix. >>> Feel free to get in touch if the warning is not clear. >>> >>> Checkpatch is preerquisite. Don't send patches which have obvious issues >>> pointed out by checkpatch. It's a waste of reviewers time. >>> >>>> + }, >>>> + {}, >>>> +}; >>>> + >>>> +static int qpic_ecc_probe(struct platform_device *pdev) >>>> +{ >>>> + struct device *dev = &pdev->dev; >>>> + struct qpic_ecc *ecc; >>>> + u32 max_eccdata_size; >>>> + >>>> + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); >>>> + if (!ecc) >>>> + return -ENOMEM; >>>> + >>>> + ecc->caps = of_device_get_match_data(dev); >>>> + >>>> + ecc->dev = dev; >>>> + platform_set_drvdata(pdev, ecc); >>>> + dev_info(dev, "probed\n"); >>> >>> No, no such messages. >>> >>> >>> >>> Best regards, >>> Krzysztof >>> > > >
Hello, > Based on below feedback [1] and NAK on the device node patch > got idea of having separate device node for ECC is not acceptable. > Could you please help to clarify that. If I may try to compare with the Macronix situation, the ECC engine was an independent hardware block, with its own mapping and its own registers, so it was described as an independent node in the DT. The type of ECC controller (pipelined or external) is described by the nand-ecc-engine property which either points at the parent node (pipelined) or an external node (external). The SPI host would itself point at the external ECC engine node with its own nand-ecc-engine property (see mtd/mxicy,nand-ecc-engine.yaml in the bindings). > Since ECC block is inlined with QPIC controller so is the below > device node acceptable ? > > bch: qpic_ecc { > compatible = "qcom,ipq9574-ecc"; > status = "ok"; > }; If it does not has its own mapping and if you access the ECC engine through the host registers then the controller should be part of the host node, but I am not sure it really needs to be described explicitly, most of them are not for historical reasons. Conceptually there is a problem with subnodes of each of these controllers having a signification already: SPI devices or NAND chips. Thanks, Miquèl
On Fri, 3 Nov 2023 at 15:24, Md Sadre Alam <quic_mdalam@quicinc.com> wrote: > > > > On 11/3/2023 6:03 PM, Dmitry Baryshkov wrote: > > On Fri, 3 Nov 2023 at 14:25, Md Sadre Alam <quic_mdalam@quicinc.com> wrote: > >> > >> > >> > >> On 10/31/2023 10:41 PM, Krzysztof Kozlowski wrote: > >>> On 31/10/2023 13:03, Md Sadre Alam wrote: > >>> > >>> Eh? Empty? > >> > >> QPIC controller has the ecc pipelined so will keep the ecc support > >> inlined in both raw nand and serial nand driver. > >> > >> Droping this driver since device node was NAK-ed > >> https://www.spinics.net/lists/linux-arm-msm/msg177596.html > > > > It seems, we have to repeat the same thing again and again: > > > > It was not the device node that was NAKed. It was the patch that was > > NAKed. Please read the emails carefully. > > > > And next time please perform dtbs_check, dt_binding_check and > > checkpatch before sending the patch. > > > > It is perfectly fine to ask questions 'like we are getting we are > > getting this and that issues with the bindings, please advise'. It is > > not fine to skip that step completely. > > Sorry in V1 will run all basic checks. > > Based on below feedback [1] and NAK on the device node patch > got idea of having separate device node for ECC is not acceptable. > Could you please help to clarify that. > > Since ECC block is inlined with QPIC controller so is the below > device node acceptable ? No, the node below is not acceptable. And you have already got two reasons for that. Let me repeat them for you: - it is "okay" not "ok" - no underscores in node names. If you want to have a more meaningful discussion, please provide full ECC + NAND + SPI DT bindings, only then we can discuss them. > bch: qpic_ecc { > compatible = "qcom,ipq9574-ecc"; > status = "ok"; > }; > > [1] https://www.spinics.net/lists/linux-arm-msm/msg177525.html > > > > >>> > >>>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> > >>>> Signed-off-by: Sricharan R <quic_srichara@quicinc.com> > >>>> --- > >>>> drivers/mtd/nand/Kconfig | 7 ++ > >>>> drivers/mtd/nand/Makefile | 1 + > >>>> drivers/mtd/nand/ecc-qcom.c | 198 ++++++++++++++++++++++++++++++++++++ > >>>> 3 files changed, 206 insertions(+) > >>>> create mode 100644 drivers/mtd/nand/ecc-qcom.c > >>>> > >>> > >>> ... > >>> > >>>> + > >>>> + return 0; > >>>> +} > >>>> +EXPORT_SYMBOL(qcom_ecc_config); > >>>> + > >>>> +void qcom_ecc_enable(struct qcom_ecc *ecc) > >>>> +{ > >>>> + ecc->use_ecc = true; > >>>> +} > >>>> +EXPORT_SYMBOL(qcom_ecc_enable); > >>> > >>> Drop this and all other exports. Nothing here explains the need for them. > >>> > >>>> + > >>>> +void qcom_ecc_disable(struct qcom_ecc *ecc) > >>>> +{ > >>>> + ecc->use_ecc = false; > >>>> +} > >>>> +EXPORT_SYMBOL(qcom_ecc_disable); > >>>> + > >>>> +static const struct of_device_id qpic_ecc_dt_match[] = { > >>>> + { > >>>> + .compatible = "qcom,ipq9574-ecc", > >>> > >>> Please run scripts/checkpatch.pl and fix reported warnings. Some > >>> warnings can be ignored, but the code here looks like it needs a fix. > >>> Feel free to get in touch if the warning is not clear. > >>> > >>> Checkpatch is preerquisite. Don't send patches which have obvious issues > >>> pointed out by checkpatch. It's a waste of reviewers time. > >>> > >>>> + }, > >>>> + {}, > >>>> +}; > >>>> + > >>>> +static int qpic_ecc_probe(struct platform_device *pdev) > >>>> +{ > >>>> + struct device *dev = &pdev->dev; > >>>> + struct qpic_ecc *ecc; > >>>> + u32 max_eccdata_size; > >>>> + > >>>> + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); > >>>> + if (!ecc) > >>>> + return -ENOMEM; > >>>> + > >>>> + ecc->caps = of_device_get_match_data(dev); > >>>> + > >>>> + ecc->dev = dev; > >>>> + platform_set_drvdata(pdev, ecc); > >>>> + dev_info(dev, "probed\n"); > >>> > >>> No, no such messages. > >>> > >>> > >>> > >>> Best regards, > >>> Krzysztof > >>> > > > > > >
On 11/3/2023 7:16 PM, Miquel Raynal wrote: > Hello, > >> Based on below feedback [1] and NAK on the device node patch >> got idea of having separate device node for ECC is not acceptable. >> Could you please help to clarify that. > > If I may try to compare with the Macronix situation, the ECC engine > was an independent hardware block, with its own mapping and its own > registers, so it was described as an independent node in the DT. The > type of ECC controller (pipelined or external) is described by the > nand-ecc-engine property which either points at the parent node > (pipelined) or an external node (external). The SPI host would itself > point at the external ECC engine node with its own nand-ecc-engine > property (see mtd/mxicy,nand-ecc-engine.yaml in the bindings). Sorry for late reply. Since QPIC controller ECC engine is not a separate HW block. To control ECC functionality there is only one register 4-bytes long.As you suggested above, ECC controller described by the property nand-ecc-engine.I have checked mtd/mxicy,nand-ecc-engine.yaml file and got to know I can use like nand-ecc-engine = <&qpic_nand>; in dts.Now additional ECC node not needed in DTS. Will clean up everything in next patch. > >> Since ECC block is inlined with QPIC controller so is the below >> device node acceptable ? >> >> bch: qpic_ecc { >> compatible = "qcom,ipq9574-ecc"; >> status = "ok"; >> }; > > If it does not has its own mapping and if you access the ECC engine > through the host registers then the controller should be part of the > host node, but I am not sure it really needs to be described > explicitly, most of them are not for historical reasons. Conceptually > there is a problem with subnodes of each of these controllers having > a signification already: SPI devices or NAND chips. New device node for spi nand looks like as below. &qpic_nand { status = "okay"; pinctrl-0 = <&qspi_nand_pins>; pinctrl-names = "default"; spi_nand: spi_nand@0 { compatible = "spi-nand"; reg = <0>; #address-cells = <1>; #size-cells = <1>; nand-ecc-engine = <&qpic_nand>; nand-ecc-strength = <4>; nand-ecc-step-size = <512>; spi-max-frequency = <8000000>; }; }; With the above device node I have tested the spi nand device enumeration its working fine. Will cleanup everything and post in next patch. > > Thanks, > Miquèl
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 5b0c2c95f10c..333cec8187c8 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -61,6 +61,13 @@ config MTD_NAND_ECC_MEDIATEK help This enables support for the hardware ECC engine from Mediatek. +config MTD_NAND_ECC_QCOM + tristate "Qualcomm hardware ECC engine" + depends on ARCH_QCOM + select MTD_NAND_ECC + help + This enables support for the hardware ECC engine from Qualcomm. + endmenu endmenu diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 19e1291ac4d5..c73b8a3456ec 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -3,6 +3,7 @@ nandcore-objs := core.o bbt.o obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o +obj-$(CONFIG_MTD_NAND_ECC_QCOM) += ecc-qcom.o qpic_common.o obj-y += onenand/ obj-y += raw/ diff --git a/drivers/mtd/nand/ecc-qcom.c b/drivers/mtd/nand/ecc-qcom.c new file mode 100644 index 000000000000..a85423ed368a --- /dev/null +++ b/drivers/mtd/nand/ecc-qcom.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * QCOM ECC Engine Driver. + * Copyright (C) 2023 Qualcomm Inc. + * Authors: Md sadre Alam <quic_mdalam@quicinc.com> + * Sricharan R <quic_srichara@quicinc.com> + */ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/iopoll.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/mutex.h> +#include <linux/mtd/nand-qpic-common.h> + + + +/* ECC modes supported by the controller */ +#define ECC_NONE BIT(0) +#define ECC_RS_4BIT BIT(1) +#define ECC_BCH_4BIT BIT(2) +#define ECC_BCH_8BIT BIT(3) + +struct qpic_ecc_caps { + u32 err_mask; + u32 err_shift; + const u8 *ecc_strength; + const u32 *ecc_regs; + u8 num_ecc_strength; + u8 ecc_mode_shift; + u32 parity_bits; + int pg_irq_sel; +}; + + +struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) +{ + return container_of(chip, struct qcom_nand_host, chip); +} +EXPORT_SYMBOL(to_qcom_nand_host); + +struct qcom_nand_controller * +get_qcom_nand_controller(struct nand_chip *chip) +{ + return container_of(chip->controller, struct qcom_nand_controller, + controller); +} +EXPORT_SYMBOL(get_qcom_nand_controller); + +static struct qpic_ecc *qpic_ecc_get(struct device_node *np) +{ + struct platform_device *pdev; + struct qpic_ecc *ecc; + + pdev = of_find_device_by_node(np); + if (!pdev) + return ERR_PTR(-EPROBE_DEFER); + + ecc = platform_get_drvdata(pdev); + if (!ecc) { + put_device(&pdev->dev); + return ERR_PTR(-EPROBE_DEFER); + } + + return ecc; +} + +struct qpic_ecc *of_qpic_ecc_get(struct device_node *of_node) +{ + struct qpic_ecc *ecc = NULL; + struct device_node *np; + + np = of_parse_phandle(of_node, "nand-ecc-engine", 0); + /* for backward compatibility */ + if (!np) + np = of_parse_phandle(of_node, "ecc-engine", 0); + if (np) { + ecc = qpic_ecc_get(np); + of_node_put(np); + } + + return ecc; +} +EXPORT_SYMBOL(of_qpic_ecc_get); + +int qcom_ecc_config(struct qpic_ecc *ecc, int ecc_strength, + bool wide_bus) +{ + ecc->ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT); + + if (ecc_strength >= 8) { + /* 8 bit ECC defaults to BCH ECC on all platforms */ + ecc->bch_enabled = true; + ecc->ecc_mode = 1; + + if (wide_bus) { + ecc->ecc_bytes_hw = 14; + ecc->spare_bytes = 0; + ecc->bbm_size = 2; + } else { + ecc->ecc_bytes_hw = 13; + ecc->spare_bytes = 2; + ecc->bbm_size = 1; + } + } else { + /* + * if the controller supports BCH for 4 bit ECC, the controller + * uses lesser bytes for ECC. If RS is used, the ECC bytes is + * always 10 bytes + */ + if (ecc->ecc_modes & ECC_BCH_4BIT) { + /* BCH */ + ecc->bch_enabled = true; + ecc->ecc_mode = 0; + if (wide_bus) { + ecc->ecc_bytes_hw = 8; + ecc->spare_bytes = 2; + ecc->bbm_size = 2; + } else { + ecc->ecc_bytes_hw = 7; + ecc->spare_bytes = 4; + ecc->bbm_size = 1; + } + } else { + /* RS */ + ecc->ecc_bytes_hw = 10; + if (wide_bus) { + ecc->spare_bytes = 0; + ecc->bbm_size = 2; + } else { + ecc->spare_bytes = 1; + ecc->bbm_size = 1; + } + } + } + + return 0; +} +EXPORT_SYMBOL(qcom_ecc_config); + +void qcom_ecc_enable(struct qcom_ecc *ecc) +{ + ecc->use_ecc = true; +} +EXPORT_SYMBOL(qcom_ecc_enable); + +void qcom_ecc_disable(struct qcom_ecc *ecc) +{ + ecc->use_ecc = false; +} +EXPORT_SYMBOL(qcom_ecc_disable); + +static const struct of_device_id qpic_ecc_dt_match[] = { + { + .compatible = "qcom,ipq9574-ecc", + }, + {}, +}; + +static int qpic_ecc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct qpic_ecc *ecc; + u32 max_eccdata_size; + + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); + if (!ecc) + return -ENOMEM; + + ecc->caps = of_device_get_match_data(dev); + + ecc->dev = dev; + platform_set_drvdata(pdev, ecc); + dev_info(dev, "probed\n"); + + return 0; +} + + +MODULE_DEVICE_TABLE(of, qpic_ecc_dt_match); + +static struct platform_driver qpic_ecc_driver = { + .probe = qpic_ecc_probe, + .driver = { + .name = "qpic-ecc", + .of_match_table = qpic_ecc_dt_match, + }, +}; + +module_platform_driver(qpic_ecc_driver); + +MODULE_AUTHOR("Md Sadre Alam <quic_mdalam@quicinc.com>"); +MODULE_DESCRIPTION("QPIC Nand ECC Driver"); +MODULE_LICENSE("Dual MIT/GPL");