From patchwork Wed Nov 13 09:49:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bastien Curutchet X-Patchwork-Id: 2010682 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=hvUx9qw9; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=OqpTYiuB; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256 header.s=gm1 header.b=PWh73TkX; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XpJf23NDzz1xyT for ; Wed, 13 Nov 2024 20:59:06 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=a/XPU8GohASXX/gh8V5hFVEvYsk50wtquPGKsX4ffa0=; b=hvUx9qw96bV4FZ kzx5BmrxW3cGP1g4ZpHhccCYMIXcH4pJkmRrUD7ksnxFeD+4v3k4E0NDWa2rm3rcFHo8LoDC+sDi6 da8HWl6XdwIZx2n5O7jjucwTPVnSli3E37FY+DpglcN9POkoyXjLyG6AOeK/ncrqrnKmnzekH2Zq9 02UwfKNWVkCqDnU51WebcDrm3FxkN94wJdyAG6LDVbXmXWMjIMwMYwDwtfq/15uKJW10JPRP0Wxmm odJUb46c3N6neO21OjYqQa00bCvqwQsW+mUZh1ZzkyRGK16l2jzt2dJn+982zP/6IknO0TluFShxN 8RsuqxQFpL05LP3PWOAw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tBA9E-00000006LSp-2naN; Wed, 13 Nov 2024 09:58:53 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tBA0X-00000006Iay-1yw3 for linux-mtd@bombadil.infradead.org; Wed, 13 Nov 2024 09:49:53 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:Content-Type :MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Sender:Reply-To:Content-ID:Content-Description; bh=iaf75RKxvR9hDjbOf8OF/9PhJbQC3X5yKc/JDdimNdQ=; b=OqpTYiuBsDKFKckWXOUT1Lx14h lY9Nm/6agiNpDaGaj97NfNUkvhLiF06ImUKTfYNSoj4OC1+oLbvGai3zkHfs/AfVCS/N4GLEQ/9tg gCOdfYyARwztgXwyepobYs1dNHI88aRhWF1io4dbLMC4Y7G7KFXTHp3qp79b9p+aJodIwKIU83lwz 5UHwjY+DL7Oacfy8MJF7Imb1TCMAYxeOuTWVfEW3apSoqMlV8xAYhqyYpsmUZu7Q+/i1SIX+K8nTw fqWwe2i2thGUxJh2apWxxuWwzZqUPsiY9gbUC6T6AHB+Oo242g0TFmt/3WwJIvSqQsngyW+RKoi70 gMKwVecg==; Received: from relay6-d.mail.gandi.net ([2001:4b98:dc4:8::226]) by desiato.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tBA0S-0000000DE6Y-1OG6 for linux-mtd@lists.infradead.org; Wed, 13 Nov 2024 09:49:52 +0000 Received: by mail.gandi.net (Postfix) with ESMTPA id 0841DC0014; Wed, 13 Nov 2024 09:49:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1731491386; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iaf75RKxvR9hDjbOf8OF/9PhJbQC3X5yKc/JDdimNdQ=; b=PWh73TkXzIlF6hnNs1QIev1z5a0k70PCKg8O5rG3fqtH9+kpiqlOIAB3iwJfYrsJSDpAPj atjVKpSu9FnR8sIdMYIvgPjDm9/FW5as+VVBp2t66Jz4O4sIiwS958u6qnHhOpSLl5VvJO JKRdsNA3p4fQGqiNFt5Hwi8gvJbQZyy/8vyMQwEGIOqzkNtjVB9DuD64DKgw0E0RYqRRiu 7kU3eBeS7JY88rgxYRdGyCwuZCn7I80hOYwvRfLgiygP5A6QCMvB+Utq+5wQ/sj4tnXLKN POX6BnLboUm77Ivequb+dVqdkDZyv07509n0CCrB7FDn5yvpBa2TCf9I+XuzUw== From: Bastien Curutchet To: Santosh Shilimkar , Krzysztof Kozlowski , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra Cc: linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, Thomas Petazzoni , Herve Codina , Christopher Cordahi , Bastien Curutchet Subject: [PATCH v3 7/7] mtd: rawnand: davinci: Implement setup_interface() operation Date: Wed, 13 Nov 2024 10:49:38 +0100 Message-ID: <20241113094938.44817-8-bastien.curutchet@bootlin.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241113094938.44817-1-bastien.curutchet@bootlin.com> References: <20241113094938.44817-1-bastien.curutchet@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: bastien.curutchet@bootlin.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241113_094949_050192_7351A379 X-CRM114-Status: GOOD ( 14.54 ) X-Spam-Score: -0.9 (/) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: The setup_interface() operation isn't implemented. It forces the driver to use the ONFI mode 0, though it could use more optimal modes. Implement the setup_interface() operation. It uses the aemif_set_cs_timings() function from the AEMIF driver to update the chip select timings. The calculation of the register's contents is directly e [...] Content analysis details: (-0.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [2001:4b98:dc4:8:0:0:0:226 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The setup_interface() operation isn't implemented. It forces the driver to use the ONFI mode 0, though it could use more optimal modes. Implement the setup_interface() operation. It uses the aemif_set_cs_timings() function from the AEMIF driver to update the chip select timings. The calculation of the register's contents is directly extracted from ยง20.3.2.3 of the DaVinci TRM [1] MAX_TH_PS and MAX_TSU_PS are the worst case timings based on the Keystone2 and DaVinci datasheets. [1] : https://www.ti.com/lit/ug/spruh77c/spruh77c.pdf Signed-off-by: Bastien Curutchet --- drivers/mtd/nand/raw/davinci_nand.c | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c index 563045c7ce08..00627c2783f8 100644 --- a/drivers/mtd/nand/raw/davinci_nand.c +++ b/drivers/mtd/nand/raw/davinci_nand.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,9 @@ #define MASK_ALE 0x08 #define MASK_CLE 0x10 +#define MAX_TSU_PS 3000 /* Input setup time in ps */ +#define MAX_TH_PS 1600 /* Input hold time in ps */ + struct davinci_nand_pdata { uint32_t mask_ale; uint32_t mask_cle; @@ -120,6 +124,7 @@ struct davinci_nand_info { uint32_t core_chipsel; struct clk *clk; + struct aemif_device *aemif; }; static DEFINE_SPINLOCK(davinci_nand_lock); @@ -767,9 +772,82 @@ static int davinci_nand_exec_op(struct nand_chip *chip, return 0; } +#define TO_CYCLES(ps, period_ns) (DIV_ROUND_UP((ps) / 1000, (period_ns))) + +static int davinci_nand_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) +{ + struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip)); + const struct nand_sdr_timings *sdr; + struct aemif_cs_timings timings; + s32 cfg, min, cyc_ns; + int ret; + + cyc_ns = 1000000000 / clk_get_rate(info->clk); + + sdr = nand_get_sdr_timings(conf); + if (IS_ERR(sdr)) + return PTR_ERR(sdr); + + cfg = TO_CYCLES(sdr->tCLR_min, cyc_ns) - 1; + timings.rsetup = cfg > 0 ? cfg : 0; + + cfg = max_t(s32, TO_CYCLES(sdr->tREA_max + MAX_TSU_PS, cyc_ns), + TO_CYCLES(sdr->tRP_min, cyc_ns)) - 1; + timings.rstrobe = cfg > 0 ? cfg : 0; + + min = TO_CYCLES(sdr->tCEA_max + MAX_TSU_PS, cyc_ns) - 2; + while ((s32)(timings.rsetup + timings.rstrobe) < min) + timings.rstrobe++; + + cfg = TO_CYCLES((s32)(MAX_TH_PS - sdr->tCHZ_max), cyc_ns) - 1; + timings.rhold = cfg > 0 ? cfg : 0; + + min = TO_CYCLES(sdr->tRC_min, cyc_ns) - 3; + while ((s32)(timings.rsetup + timings.rstrobe + timings.rhold) < min) + timings.rhold++; + + cfg = TO_CYCLES((s32)(sdr->tRHZ_max - (timings.rhold + 1) * cyc_ns * 1000), cyc_ns); + cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCHZ_max, cyc_ns)) - 1; + timings.ta = cfg > 0 ? cfg : 0; + + cfg = TO_CYCLES(sdr->tWP_min, cyc_ns) - 1; + timings.wstrobe = cfg > 0 ? cfg : 0; + + cfg = max_t(s32, TO_CYCLES(sdr->tCLS_min, cyc_ns), TO_CYCLES(sdr->tALS_min, cyc_ns)); + cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCS_min, cyc_ns)) - 1; + timings.wsetup = cfg > 0 ? cfg : 0; + + min = TO_CYCLES(sdr->tDS_min, cyc_ns) - 2; + while ((s32)(timings.wsetup + timings.wstrobe) < min) + timings.wstrobe++; + + cfg = max_t(s32, TO_CYCLES(sdr->tCLH_min, cyc_ns), TO_CYCLES(sdr->tALH_min, cyc_ns)); + cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCH_min, cyc_ns)); + cfg = max_t(s32, cfg, TO_CYCLES(sdr->tDH_min, cyc_ns)) - 1; + timings.whold = cfg > 0 ? cfg : 0; + + min = TO_CYCLES(sdr->tWC_min, cyc_ns) - 2; + while ((s32)(timings.wsetup + timings.wstrobe + timings.whold) < min) + timings.whold++; + + dev_dbg(&info->pdev->dev, "RSETUP %x RSTROBE %x RHOLD %x\n", + timings.rsetup, timings.rstrobe, timings.rhold); + dev_dbg(&info->pdev->dev, "TA %x\n", timings.ta); + dev_dbg(&info->pdev->dev, "WSETUP %x WSTROBE %x WHOLD %x\n", + timings.wsetup, timings.wstrobe, timings.whold); + + ret = aemif_check_cs_timings(&timings); + if (ret || chipnr == NAND_DATA_IFACE_CHECK_ONLY) + return ret; + + return aemif_set_cs_timings(info->aemif, info->core_chipsel, &timings); +} + static const struct nand_controller_ops davinci_nand_controller_ops = { .attach_chip = davinci_nand_attach_chip, .exec_op = davinci_nand_exec_op, + .setup_interface = davinci_nand_setup_interface, }; static int nand_davinci_probe(struct platform_device *pdev) @@ -832,6 +910,7 @@ static int nand_davinci_probe(struct platform_device *pdev) info->pdev = pdev; info->base = base; info->vaddr = vaddr; + info->aemif = dev_get_drvdata(pdev->dev.parent); mtd = nand_to_mtd(&info->chip); mtd->dev.parent = &pdev->dev;