From patchwork Thu Dec 28 22:21:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Blumenstingl X-Patchwork-Id: 10135957 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2C18860388 for ; Thu, 28 Dec 2017 22:22:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E54A2D50B for ; Thu, 28 Dec 2017 22:22:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 133082D52C; Thu, 28 Dec 2017 22:22:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 421FD2D50B for ; Thu, 28 Dec 2017 22:22:26 +0000 (UTC) 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=lO7JVPxlBFjWmyTgx2rvlaGCN539tyD2VDz9yaCuZoc=; b=N5hr+kvzSzFQ4287DbbdZxBLeL 5yDJ1UaagyaWRY1ejwOG+NFQ2sBWsRkgqmdNWt6vLKV1NoLdlzYwr8WSnmueBF+AOU9J8e/M1050X 5ETQRGfKsqVaHfRfgrKmq9cty07eoepUCpIFyatThGKcr3NhhTMggzN70StbgL4F0Mz9wWeaa+4eC Zlevvpd4ays8OQAL0WLofxvhhqOShrRSoBLZzo/vPidPlSuMZ3CmooLSkeoTqvi19NrJU+zR8fCfq huca/L49AXtYQq94XPtnVAGlNh2dd9CHhHashJpV9ghkxWlYGMVttcwN3BwIUKVa16jyz1xctzlqs fhr3/PxA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eUgZ8-0004cG-47; Thu, 28 Dec 2017 22:22:18 +0000 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eUgYp-0004RL-Iu for linux-amlogic@lists.infradead.org; Thu, 28 Dec 2017 22:22:04 +0000 Received: by mail-wm0-x244.google.com with SMTP id f140so45615524wmd.2 for ; Thu, 28 Dec 2017 14:21:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iSumI8VvnXPr5PYfxGfSpBjLr1Veh+YLwInGgUhRN28=; b=m8D2O2JKSHfnsrZWQWJ2i89W6V6euHxmQUFCIy8v/NU4hTQ58A86qoPYCDJQD0tX1f qh8wmrbAlovgvOOV1UThzAiRepG/SPGDuopgNMSVlSubs8v3UtCFOItfxLm0D2aEbXcp VU05jdkav0lBrGRn/XXQiDaddd63VMi9fwuouZjZJjrkqy5Vq/TSJZRA3UP/dFyXWeXP 0C0gWv5skFJKfNsizmo65K8o5GOvHUHpDhY7FxC4ww6DJ9BBt2677kGeEI/N3Zu/hRyj 29eZpSiinUTocTiXe46L/J3veXZ7/iFAcqOdbZ49dc/SbyIBYsZSk6qe4GRckvywL/zH 3xPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iSumI8VvnXPr5PYfxGfSpBjLr1Veh+YLwInGgUhRN28=; b=sVQ7bmPe36DtheJUsY2yG1qG6rFaLq9WNXpBM8Rtm5vEDNAfzYYnzojhKnzpjiabV6 vQakbv4J2FwG8IXADAw8CVorEX2rhDFVw6x+AJz/NdR9L+RypjxT8YPvP7TR2LLbiWtg SnFHvm7Ue+xQiok1CD9XmfDUe2N6eWyd6hJs2Ypfsm9XcELzqcvhQzZ2WnZ0tNhs9vmS 3YE5OFe3lC89xPHfhG3MDYv2ve1dcPjj5G/pQwkd0Sc5sjx26Th1rT/p4JfKDAt7qtlm efbyJzJQxtfrAwBdbBNaNM9YZkw+zlUWuTCel0IcO4SpO54mUVZWf5J8jjUKtHcxbge+ ZdyQ== X-Gm-Message-State: AKGB3mI7Vhc4YI5I5m/RXWVjXpzlvMi2sJ5+QtQS/Rdi9yZtKJyY09AC r9NvbBGHEiawK/x1H3lmVz10zQ3i X-Google-Smtp-Source: ACJfBovOf/s5LFrSqJp+Tg7zNhy3PExDjAQz9iSgm3vd9DdWASQnE4UQJIsRpTpwMLmwlAfW/12pOw== X-Received: by 10.28.60.8 with SMTP id j8mr27242790wma.136.1514499707725; Thu, 28 Dec 2017 14:21:47 -0800 (PST) Received: from blackbox.darklights.net (p5DD9B1AC.dip0.t-ipconnect.de. [93.217.177.172]) by smtp.googlemail.com with ESMTPSA id o16sm25843679wmi.29.2017.12.28.14.21.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Dec 2017 14:21:47 -0800 (PST) From: Martin Blumenstingl To: netdev@vger.kernel.org, ingrassia@epigenesys.com Subject: [RFT net-next v3 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration Date: Thu, 28 Dec 2017 23:21:26 +0100 Message-Id: <20171228222128.15215-4-martin.blumenstingl@googlemail.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171228222128.15215-1-martin.blumenstingl@googlemail.com> References: <20171228222128.15215-1-martin.blumenstingl@googlemail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171228_142159_650360_77830E5B X-CRM114-Status: GOOD ( 18.93 ) X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linus.luessing@c0d3.blue, narmstrong@baylibre.com, Martin Blumenstingl , khilman@baylibre.com, alexandre.torgue@st.com, linux-amlogic@lists.infradead.org, peppe.cavallaro@st.com, jbrunet@baylibre.com MIME-Version: 1.0 Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+patchwork-linux-amlogic=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP While testing the dwmac-meson8b with an RGMII PHY on Meson8b we discovered that the m25_div is not actually a divider but rather a gate. This matches with the datasheet which describes bit 10 as "Generate 25MHz clock for PHY". Back when the driver was written it was assumed that this was a divider (which could divide by 5 or 10) because other clock bits in the datasheet were documented incorrectly. Tests have shown that without bit 10 set the RTL8211F RGMII PHY on Odroid-C1 (using a Meson8b SoC) does not work. On GXBB and newer SoCs (where the driver was initially tested with RGMII PHYs) this is not a problem because the input clock is running at 1GHz. The m250_div clock's biggest possible divider is 7 (3-bit divider, with value 0 being reserved). Thus we end up with a m250_div of 4 and a "m25_div" of 10 (= register value 1). Instead it turns out that the Ethernet IP block seems to have a fixed "divide by 10" clock internally. This means that bit 10 is a gate clock which enables the RGMII clock output. This replaces the "m25_div" clock with a clock gate called "m25_en" which ensures that we can set this bit to 1 whenever we enable RGMII mode. This however means that we are now missing a "divide by 10" after the m250_div (and before our new m25_en), otherwise the common clock framework thinks that the rate of the m25_en clock is 10-times higher than it is in the actual hardware. That is solved by adding a fixed-factor clock which divides the m250_div output by 10. Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b / GXBB DWMAC") Reported-by: Emiliano Ingrassia Signed-off-by: Martin Blumenstingl --- .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 66 +++++++++++++--------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c index 1c14210df465..7199e8c08536 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c @@ -40,9 +40,7 @@ #define PRG_ETH0_CLK_M250_DIV_SHIFT 7 #define PRG_ETH0_CLK_M250_DIV_WIDTH 3 -/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */ -#define PRG_ETH0_CLK_M25_DIV_SHIFT 10 -#define PRG_ETH0_CLK_M25_DIV_WIDTH 1 +#define PRG_ETH0_GENERATE_25M_PHY_CLOCK 10 #define PRG_ETH0_INVERTED_RMII_CLK BIT(11) #define PRG_ETH0_TX_AND_PHY_REF_CLK BIT(12) @@ -63,8 +61,11 @@ struct meson8b_dwmac { struct clk_divider m250_div; struct clk *m250_div_clk; - struct clk_divider m25_div; - struct clk *m25_div_clk; + struct clk_fixed_factor fixed_div10; + struct clk *fixed_div10_clk; + + struct clk_gate m25_en; + struct clk *m25_en_clk; u32 tx_delay_ns; }; @@ -88,11 +89,6 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac *dwmac) struct device *dev = &dwmac->pdev->dev; const char *clk_div_parents[1]; const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; - static const struct clk_div_table clk_25m_div_table[] = { - { .val = 0, .div = 5 }, - { .val = 1, .div = 10 }, - { /* sentinel */ }, - }; /* get the mux parents from DT */ for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { @@ -149,25 +145,39 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac *dwmac) if (WARN_ON(IS_ERR(dwmac->m250_div_clk))) return PTR_ERR(dwmac->m250_div_clk); - /* create the m25_div */ - init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_div", + /* create the fixed_div10 */ + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#fixed_div10", dev_name(dev)); - init.ops = &clk_divider_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.ops = &clk_fixed_factor_ops; + init.flags = CLK_SET_RATE_PARENT; clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk); init.parent_names = clk_div_parents; init.num_parents = ARRAY_SIZE(clk_div_parents); - dwmac->m25_div.reg = dwmac->regs + PRG_ETH0; - dwmac->m25_div.shift = PRG_ETH0_CLK_M25_DIV_SHIFT; - dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH; - dwmac->m25_div.table = clk_25m_div_table; - dwmac->m25_div.hw.init = &init; - dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO; + dwmac->fixed_div10.mult = 1; + dwmac->fixed_div10.div = 10; + dwmac->fixed_div10.hw.init = &init; + + dwmac->fixed_div10_clk = devm_clk_register(dev, &dwmac->fixed_div10.hw); + if (WARN_ON(IS_ERR(dwmac->fixed_div10_clk))) + return PTR_ERR(dwmac->fixed_div10_clk); + + /* create the m25_en */ + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_en", + dev_name(dev)); + init.ops = &clk_gate_ops; + init.flags = CLK_SET_RATE_PARENT; + clk_div_parents[0] = __clk_get_name(dwmac->fixed_div10_clk); + init.parent_names = clk_div_parents; + init.num_parents = ARRAY_SIZE(clk_div_parents); + + dwmac->m25_en.reg = dwmac->regs + PRG_ETH0; + dwmac->m25_en.bit_idx = PRG_ETH0_GENERATE_25M_PHY_CLOCK; + dwmac->m25_en.hw.init = &init; - dwmac->m25_div_clk = devm_clk_register(dev, &dwmac->m25_div.hw); - if (WARN_ON(IS_ERR(dwmac->m25_div_clk))) - return PTR_ERR(dwmac->m25_div_clk); + dwmac->m25_en_clk = devm_clk_register(dev, &dwmac->m25_en.hw); + if (WARN_ON(IS_ERR(dwmac->m25_en_clk))) + return PTR_ERR(dwmac->m25_en_clk); return 0; } @@ -200,16 +210,16 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, tx_dly_val << PRG_ETH0_TXDLY_SHIFT); - ret = clk_prepare_enable(dwmac->m25_div_clk); + ret = clk_prepare_enable(dwmac->m25_en_clk); if (ret) { dev_err(&dwmac->pdev->dev, "failed to enable the PHY clock\n"); return ret; } /* Generate the 25MHz RGMII clock for the PHY */ - ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000); + ret = clk_set_rate(dwmac->m25_en_clk, 25 * 1000 * 1000); if (ret) { - clk_disable_unprepare(dwmac->m25_div_clk); + clk_disable_unprepare(dwmac->m25_en_clk); dev_err(&dwmac->pdev->dev, "failed to set PHY clock\n"); return ret; @@ -305,7 +315,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev) err_clk_disable: if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) - clk_disable_unprepare(dwmac->m25_div_clk); + clk_disable_unprepare(dwmac->m25_en_clk); err_remove_config_dt: stmmac_remove_config_dt(pdev, plat_dat); @@ -317,7 +327,7 @@ static int meson8b_dwmac_remove(struct platform_device *pdev) struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) - clk_disable_unprepare(dwmac->m25_div_clk); + clk_disable_unprepare(dwmac->m25_en_clk); return stmmac_pltfr_remove(pdev); }