From patchwork Thu Jun 14 05:11:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 138514 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp1637702lji; Wed, 13 Jun 2018 22:12:42 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKV7zJuRKz2hon1ZvKpBiKtCVSKANU3vbCRbblz3uvjqOs6HbKZITdnh+3KJGcj6pDyaDlV X-Received: by 2002:aa7:808f:: with SMTP id v15-v6mr7964172pff.38.1528953162018; Wed, 13 Jun 2018 22:12:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528953162; cv=none; d=google.com; s=arc-20160816; b=G9RrmsEaSH67LKd26VxHtsqGIbyFaGoaixlFZQbTIzWLfIn9gzgmWt32zkAUTDgzMx x3W4fSl5MaqNACXGO9HOEUi0XIC7j9HBiqrRsoKeaTD/8J75FSeCY6CwZvCYiPS0NKD8 ZQbbpDXXB6ROTHCg8nznkVUYax4xuLOUb+CzTC1pQkJTbVzT6d5oJnkV2laepSWKVxsf YA9/Kh8lUlckbcD6yCHYU33W60AcCroLqA++Sfm8G4W/acPf6jxLtvGBihMIrpZVyDZ+ +vOmF9VxKIeqdt9dQbdLE8Pd+aNOyehDWPMgLzdDPIl8N9tARujYMJ4K+vhjsXlGUi98 0rgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=X3DhfdMz2UrORpTRRwDywUHRm5minlJm2DI1VLiwVaE=; b=D8UqKfJ9RN7sCcpu4loXcyh7MP5tKc3ARk/NJnZf6Bp+COu0Q6dJSXPifq0msDCLyZ PgPtuf8ZdgVINXagXiIleBGrvSUDExrYSbc07uLOkrqW51j+SU6g8AhDHbjMbEqWct/3 By/cOV+ktGXki5x5eGWyKHkZT+mzW4F2fkcmwfbhub/LfHKGaouOy9ECZNnldstEFeiN DKd5shenYw+fLSL8+B7ZXgKtmOp2aVVOwjNINFw54JY/6dsnQ/8xBlWQFGaoI+tqAgas uXQ9GvywgVotS5a1p32VbHmgNQV2X9Wx8dDO79bnDcT7TLL2cdgP+mBamBg3ZnVphpSS YNFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20170209 header.b=b0g4s52c; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=L4InzDQ6; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom="linux-mtd-bounces+patch=linaro.org@lists.infradead.org" Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2607:7c80:54:e::133]) by mx.google.com with ESMTPS id p8-v6si3858911pgs.239.2018.06.13.22.12.41 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Jun 2018 22:12:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) client-ip=2607:7c80:54:e::133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20170209 header.b=b0g4s52c; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=L4InzDQ6; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom="linux-mtd-bounces+patch=linaro.org@lists.infradead.org" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=X3DhfdMz2UrORpTRRwDywUHRm5minlJm2DI1VLiwVaE=; b=b0g4s52cBr1t89TIkn4jMrM3Ix nX+yI9XjSJxTCIltqzLI1TcohXe83iIRhFRZYJdsRwQU8hAM6cGDl4RNlKv9Y3f0O7Lm+RUQMdTyy GFIVpn03MyJM1ICalAoiDX4RIpkHzOTdZzqBdFZRFNpAjJct9MBjWvapUI6oTR20gxTw0ZUSRu1ED TDUIpd7B0kWsK4ePmNywjT+WjF3feEM1W9db6bcKUsKaqVp1DFLyHdnlswLnrZWAAmp0tmto7LTD1 93reJCy/Gv08ofUjAHA4spEI6LWnVB/xLvQ5qJ+swEykMWC3isDh9zPoHaMFLTraL2Jzssfh+Gka5 DYecJiMA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fTKYe-0005Lk-5B; Thu, 14 Jun 2018 05:12:28 +0000 Received: from conuserg-10.nifty.com ([210.131.2.77]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fTKYB-0004u5-3x for linux-mtd@lists.infradead.org; Thu, 14 Jun 2018 05:12:12 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-10.nifty.com with ESMTP id w5E5BB4e003441; Thu, 14 Jun 2018 14:11:15 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-10.nifty.com w5E5BB4e003441 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1528953076; bh=pm+4FyH/gYp1HZyuH+lEvzm6vmk1locPJsAuPPRhnNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L4InzDQ63YxHKf+qtTN0PcrfROTW8Lv8neSvkn3Sc622+BvRx1Ph/VdpFXteQbdq+ kZ+cVGHFbUQhtLzxahwUGsZp72PqIauzBjslxSe3KvvvYLLkKYd2ueTwItH+Zlxt+X eFzXkRJ2HMAqFyLwGVsDfgHoDvMW/YUeJkYokitpC4KEIKFooELSkaKLBppJWMqJOh 3mjvrM6I0mv5z0tCKJjrpplbJlOA0DokjIyKQ48PywZF4gIiXTVNKq4wU9ocMMbE6Y rxGo5DtmOUkXW/kAQFVDmsxDq5ZP1BMfMwziwmWHcqIwGZNfbK5wfuqFVfyxdSiyP4 Xz1Ku8eemBrCw== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org, Boris Brezillon Subject: [PATCH v2 3/3] mtd: rawnand: denali: optimize timing parameters for data interface Date: Thu, 14 Jun 2018 14:11:07 +0900 Message-Id: <1528953067-24324-4-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1528953067-24324-1-git-send-email-yamada.masahiro@socionext.com> References: <1528953067-24324-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180613_221159_461740_AECE5175 X-CRM114-Status: GOOD ( 18.11 ) X-Spam-Score: 1.0 (+) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (1.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [210.131.2.77 listed in list.dnswl.org] 1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 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.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Brian Norris , Marek Vasut , Richard Weinberger , linux-kernel@vger.kernel.org, Masahiro Yamada , Miquel Raynal , Philipp Rosenberger , Richard Weinberger , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org This commit improves the ->setup_data_interface() hook. The denali_setup_data_interface() needs the frequency of clk_x and the ratio of clk_x / clk. The latter is currently hardcoded in the driver, like this: #define DENALI_CLK_X_MULT 6 The IP datasheet requires that clk_x / clk be 4, 5, or 6. I just chose 6 because it is the most defensive value, but it is not optimal. By getting the clock rate of both "clk" and "clk_x", the driver can compute the timing values more precisely. To not break the existing platforms, the fallback value, 50 MHz is provided. It is true for all upstreamed platforms. Signed-off-by: Masahiro Yamada --- Changes in v2: - Split patches into sensible chunks drivers/mtd/nand/raw/denali.c | 49 +++++++++++++++++++-------------------- drivers/mtd/nand/raw/denali.h | 1 + drivers/mtd/nand/raw/denali_dt.c | 2 ++ drivers/mtd/nand/raw/denali_pci.c | 1 + 4 files changed, 28 insertions(+), 25 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 2a302a1..2de46d4 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -51,14 +51,6 @@ MODULE_LICENSE("GPL"); #define DENALI_INVALID_BANK -1 #define DENALI_NR_BANKS 4 -/* - * The bus interface clock, clk_x, is phase aligned with the core clock. The - * clk_x is an integral multiple N of the core clk. The value N is configured - * at IP delivery time, and its available value is 4, 5, or 6. We need to align - * to the largest value to make it work with any possible configuration. - */ -#define DENALI_CLK_X_MULT 6 - static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) { return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand); @@ -954,7 +946,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, { struct denali_nand_info *denali = mtd_to_denali(mtd); const struct nand_sdr_timings *timings; - unsigned long t_clk; + unsigned long t_x, mult_x; int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data; int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup; int addr_2_data_mask; @@ -965,15 +957,24 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, return PTR_ERR(timings); /* clk_x period in picoseconds */ - t_clk = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate); - if (!t_clk) + t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate); + if (!t_x) + return -EINVAL; + + /* + * The bus interface clock, clk_x, is phase aligned with the core clock. + * The clk_x is an integral multiple N of the core clk. The value N is + * configured at IP delivery time, and its available value is 4, 5, 6. + */ + mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate); + if (mult_x < 4 || mult_x > 6) return -EINVAL; if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) return 0; /* tREA -> ACC_CLKS */ - acc_clks = DIV_ROUND_UP(timings->tREA_max, t_clk); + acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x); acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE); tmp = ioread32(denali->reg + ACC_CLKS); @@ -982,7 +983,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + ACC_CLKS); /* tRWH -> RE_2_WE */ - re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_clk); + re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x); re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE); tmp = ioread32(denali->reg + RE_2_WE); @@ -991,7 +992,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RE_2_WE); /* tRHZ -> RE_2_RE */ - re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_clk); + re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x); re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE); tmp = ioread32(denali->reg + RE_2_RE); @@ -1005,8 +1006,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, * With WE_2_RE properly set, the Denali controller automatically takes * care of the delay; the driver need not set NAND_WAIT_TCCS. */ - we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), - t_clk); + we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x); we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE); tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE); @@ -1021,7 +1021,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, if (denali->revision < 0x0501) addr_2_data_mask >>= 1; - addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_clk); + addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x); addr_2_data = min_t(int, addr_2_data, addr_2_data_mask); tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA); @@ -1031,7 +1031,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, /* tREH, tWH -> RDWR_EN_HI_CNT */ rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min), - t_clk); + t_x); rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE); tmp = ioread32(denali->reg + RDWR_EN_HI_CNT); @@ -1040,11 +1040,10 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT); /* tRP, tWP -> RDWR_EN_LO_CNT */ - rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), - t_clk); + rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x); rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min), - t_clk); - rdwr_en_lo_hi = max(rdwr_en_lo_hi, DENALI_CLK_X_MULT); + t_x); + rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x); rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi); rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE); @@ -1054,8 +1053,8 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT); /* tCS, tCEA -> CS_SETUP_CNT */ - cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_clk) - rdwr_en_lo, - (int)DIV_ROUND_UP(timings->tCEA_max, t_clk) - acc_clks, + cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo, + (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks, 0); cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE); @@ -1282,7 +1281,7 @@ int denali_init(struct denali_nand_info *denali) } /* clk rate info is needed for setup_data_interface */ - if (denali->clk_x_rate) + if (denali->clk_rate && denali->clk_x_rate) chip->setup_data_interface = denali_setup_data_interface; ret = nand_scan_ident(mtd, denali->max_banks, NULL); diff --git a/drivers/mtd/nand/raw/denali.h b/drivers/mtd/nand/raw/denali.h index 9ad33d2..1f8feaf 100644 --- a/drivers/mtd/nand/raw/denali.h +++ b/drivers/mtd/nand/raw/denali.h @@ -300,6 +300,7 @@ struct denali_nand_info { struct nand_chip nand; + unsigned long clk_rate; /* core clock rate */ unsigned long clk_x_rate; /* bus interface clock rate */ int active_bank; /* currently selected bank */ struct device *dev; diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index afaae37..0faaad0 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -150,6 +150,7 @@ static int denali_dt_probe(struct platform_device *pdev) goto out_disable_clk_x; if (dt->clk_x) { + denali->clk_rate = clk_get_rate(dt->clk); denali->clk_x_rate = clk_get_rate(dt->clk_x); } else { /* @@ -158,6 +159,7 @@ static int denali_dt_probe(struct platform_device *pdev) */ dev_notice(dev, "necessary clock is missing. default clock rates are used.\n"); + denali->clk_rate = 50000000; denali->clk_x_rate = 200000000; } diff --git a/drivers/mtd/nand/raw/denali_pci.c b/drivers/mtd/nand/raw/denali_pci.c index 49cb3e1..7c8efc4 100644 --- a/drivers/mtd/nand/raw/denali_pci.c +++ b/drivers/mtd/nand/raw/denali_pci.c @@ -73,6 +73,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) denali->irq = dev->irq; denali->ecc_caps = &denali_pci_ecc_caps; denali->nand.ecc.options |= NAND_ECC_MAXIMIZE; + denali->clk_rate = 50000000; /* 50 MHz */ denali->clk_x_rate = 200000000; /* 200 MHz */ ret = pci_request_regions(dev, DENALI_NAND_NAME);