From patchwork Thu Jan 6 03:25:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liang Yang X-Patchwork-Id: 1575930 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=q7eQXUWb; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JTsGN6nyhz9sPC for ; Thu, 6 Jan 2022 14:26:52 +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: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:In-Reply-To:References: List-Owner; bh=LKrjKTdqrpmG3wrwv3hdc2RwBI3bcTY+L0ZdYoTXLrY=; b=q7eQXUWbaDwWSr hH5WOzShHGDDJrx1v8jcsD7Ap5sB+NN6A1PiLGTNIFVKaMIEwkeA0r3ceMTe9jKyqK0fw0TzGqkPg svXMx5lfhyE1QoeaOKofjNyGCKQp6fu/mLC/y7OBKfiqsGo+4v/RBDwAnI6xiMFKVV8I+QjjoDh8N dp9Joq7hhqDCW35NhXLSZiBMmlPpfUS4KJRFXLz2W7TKx0015gXF731rZjKkAerZdx7zxVQldiXcF pwhivHOSHH6m1vH1Ynbjrvm69PXNwt0umAqI/fyiED9LpZ1xn84CbubitUAjR6lWqBJ4PwojfIx6h WW4QnSpJTfgNEwM0llDg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1n5JPc-00GICd-Lx; Thu, 06 Jan 2022 03:26:00 +0000 Received: from mail-sz.amlogic.com ([211.162.65.117]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1n5JP6-00GHjr-DD; Thu, 06 Jan 2022 03:25:30 +0000 Received: from droid11-sz.amlogic.com (10.28.8.21) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.2176.2; Thu, 6 Jan 2022 11:25:18 +0800 From: Liang Yang To: Miquel Raynal , CC: Liang Yang , Richard Weinberger , Jerome Brunet , Neil Armstrong , Martin Blumenstingl , Kevin Hilman , Jianxin Pan , Victor Wan , XianWei Zhao , Kelvin Zhang , BiChao Zheng , YongHui Yu , , , , Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding sd_emmc_c_clkc Date: Thu, 6 Jan 2022 11:25:04 +0800 Message-ID: <20220106032504.23310-1-liang.yang@amlogic.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Originating-IP: [10.28.8.21] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220105_192528_506244_6ABB6E30 X-CRM114-Status: GOOD ( 18.25 ) X-Spam-Score: 0.0 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.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: Because EMMC and NAND have the same control clock register, so we implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below: sd_emmc_c_clkc: mmc@7000 { compatible = "amlogic,meson-axg-mmc-clkc", "syscon"; reg = <0x0 0x7000 0x0 0x800>; }; Content analysis details: (0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 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 Because EMMC and NAND have the same control clock register, so we implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below: sd_emmc_c_clkc: mmc@7000 { compatible = "amlogic,meson-axg-mmc-clkc", "syscon"; reg = <0x0 0x7000 0x0 0x800>; }; nand-controller@7800 { ...... clocks = <&clkc CLKID_SD_EMMC_C>, <&sd_emmc_c_clkc CLKID_MMC_DIV>, <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>, <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>; clock-names = "core", "device", "rx", "tx"; amlogic,mmc-syscon = <&sd_emmc_c_clkc>; ...... } but in fact, above implementation is rejected. so now registering a nand_divider. Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997 Signed-off-by: Liang Yang Reported-by: kernel test robot Reported-by: kernel test robot Reported-by: kernel test robot --- drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++-------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index ac3be92872d0..4472363059c2 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -2,7 +2,7 @@ /* * Amlogic Meson Nand Flash Controller Driver * - * Copyright (c) 2018 Amlogic, inc. + * Copyright (c) 2018-2021 Amlogic, inc. * Author: Liang Yang */ @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ #define NFC_REG_VER 0x38 #define NFC_RB_IRQ_EN BIT(21) +#define NFC_CMD_FIFO_RESET BIT(31) #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \ ( \ @@ -104,6 +106,9 @@ #define PER_INFO_BYTE 8 +#define CLK_DIV_SHIFT 0 +#define CLK_DIV_WIDTH 6 + struct meson_nfc_nand_chip { struct list_head node; struct nand_chip nand; @@ -151,15 +156,15 @@ struct meson_nfc { struct nand_controller controller; struct clk *core_clk; struct clk *device_clk; - struct clk *phase_tx; - struct clk *phase_rx; + struct clk *nand_clk; + struct clk_divider nand_divider; unsigned long clk_rate; u32 bus_timing; struct device *dev; void __iomem *reg_base; - struct regmap *reg_clk; + void __iomem *reg_clk; struct completion completion; struct list_head chips; const struct meson_nfc_data *data; @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms) cmd = NFC_CMD_RB | NFC_CMD_RB_INT | nfc->param.chip_select | nfc->timing.tbers_max; writel(cmd, nfc->reg_base + NFC_REG_CMD); - + meson_nfc_drain_cmd(nfc); ret = wait_for_completion_timeout(&nfc->completion, msecs_to_jiffies(timeout_ms)); if (ret == 0) ret = -1; + /* reset command fifo to avoid lock */ + writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD); return ret; } @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = { static int meson_nfc_clk_init(struct meson_nfc *nfc) { int ret; + struct clk_init_data init = {0}; + const char *fix_div2_pll_name[1]; - /* request core clock */ nfc->core_clk = devm_clk_get(nfc->dev, "core"); if (IS_ERR(nfc->core_clk)) { dev_err(nfc->dev, "failed to get core clock\n"); @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) return PTR_ERR(nfc->device_clk); } - nfc->phase_tx = devm_clk_get(nfc->dev, "tx"); - if (IS_ERR(nfc->phase_tx)) { - dev_err(nfc->dev, "failed to get TX clk\n"); - return PTR_ERR(nfc->phase_tx); - } - - nfc->phase_rx = devm_clk_get(nfc->dev, "rx"); - if (IS_ERR(nfc->phase_rx)) { - dev_err(nfc->dev, "failed to get RX clk\n"); - return PTR_ERR(nfc->phase_rx); - } + init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL); + init.ops = &clk_divider_ops; + fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk); + init.parent_names = fix_div2_pll_name; + init.num_parents = 1; + nfc->nand_divider.reg = nfc->reg_clk; + nfc->nand_divider.shift = CLK_DIV_SHIFT; + nfc->nand_divider.width = CLK_DIV_WIDTH; + nfc->nand_divider.hw.init = &init; + nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ROUND_CLOSEST | + CLK_DIVIDER_ALLOW_ZERO; + + nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw); + if (IS_ERR(nfc->nand_clk)) + return PTR_ERR(nfc->nand_clk); /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ - regmap_update_bits(nfc->reg_clk, - 0, CLK_SELECT_NAND, CLK_SELECT_NAND); + writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk); ret = clk_prepare_enable(nfc->core_clk); if (ret) { @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) goto err_device_clk; } - ret = clk_prepare_enable(nfc->phase_tx); + ret = clk_prepare_enable(nfc->nand_clk); if (ret) { - dev_err(nfc->dev, "failed to enable TX clock\n"); - goto err_phase_tx; - } - - ret = clk_prepare_enable(nfc->phase_rx); - if (ret) { - dev_err(nfc->dev, "failed to enable RX clock\n"); - goto err_phase_rx; + dev_err(nfc->dev, "pre enable NFC divider fail\n"); + goto err_nand_clk; } ret = clk_set_rate(nfc->device_clk, 24000000); if (ret) - goto err_disable_rx; + goto err_disable_clk; return 0; -err_disable_rx: - clk_disable_unprepare(nfc->phase_rx); -err_phase_rx: - clk_disable_unprepare(nfc->phase_tx); -err_phase_tx: +err_disable_clk: + clk_disable_unprepare(nfc->nand_clk); +err_nand_clk: clk_disable_unprepare(nfc->device_clk); err_device_clk: clk_disable_unprepare(nfc->core_clk); @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) static void meson_nfc_disable_clk(struct meson_nfc *nfc) { - clk_disable_unprepare(nfc->phase_rx); - clk_disable_unprepare(nfc->phase_tx); + clk_disable_unprepare(nfc->nand_clk); clk_disable_unprepare(nfc->device_clk); clk_disable_unprepare(nfc->core_clk); } @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct meson_nfc *nfc; struct resource *res; + u32 ext_clk_reg; int ret, irq; nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev) if (IS_ERR(nfc->reg_base)) return PTR_ERR(nfc->reg_base); - nfc->reg_clk = - syscon_regmap_lookup_by_phandle(dev->of_node, - "amlogic,mmc-syscon"); + ret = of_property_read_u32(pdev->dev.of_node, + "sd_emmc_c_clkc", + &ext_clk_reg); + if (ret) { + dev_err(dev, "failed to get NAND external clock register\n"); + return ret; + } + + nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int)); if (IS_ERR(nfc->reg_clk)) { dev_err(dev, "Failed to lookup clock base\n"); return PTR_ERR(nfc->reg_clk);