From patchwork Wed Jan 29 06:00:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 314918 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id AEE092C0079 for ; Wed, 29 Jan 2014 17:01:17 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755963AbaA2GAz (ORCPT ); Wed, 29 Jan 2014 01:00:55 -0500 Received: from mail-la0-f52.google.com ([209.85.215.52]:43544 "EHLO mail-la0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755467AbaA2GAu (ORCPT ); Wed, 29 Jan 2014 01:00:50 -0500 Received: by mail-la0-f52.google.com with SMTP id c6so1117512lan.39 for ; Tue, 28 Jan 2014 22:00:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=K57RhjrpBiXvm5jR89v+1D55fRSVQhesYdm6jnS0snc=; b=rXb8Hyh9+Aq9+9EVRGYJskrxlDCLnW2mcqD0bO2GCw9O9Pcn0siE0hoLwKtX/iKA+V LQGsf7nP6zMqYWeyhLiNwtLth/PZ3ObcwfDLLnduSuPoC/SZDupAPWZy0Zg50NefD5z1 QWtajSbO5v3l2kGQ6fWi0IP7pfSadf1dfmmVkzWJVzhWtjm9Ja+zsYSq4QMydEsgdDC4 n6PsVFLKjiPd6oPNluP4uwVByvRY6FtuT3Zay7PdYA8+imNo4S2GLYo6vvw4qrPAWaoH T3vlLDlrge7PyaDyJDQBBTJVQnb44MPTvdNouGsm39bsaSzPQoOP55FW6/Rcswj/FnFs bIjw== X-Received: by 10.112.158.131 with SMTP id wu3mr3839494lbb.6.1390975248780; Tue, 28 Jan 2014 22:00:48 -0800 (PST) Received: from octofox.metropolis ([188.134.19.124]) by mx.google.com with ESMTPSA id h7sm1263226lbj.1.2014.01.28.22.00.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jan 2014 22:00:48 -0800 (PST) From: Max Filippov To: linux-xtensa@linux-xtensa.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Chris Zankel , Marc Gauthier , "David S. Miller" , Ben Hutchings , Florian Fainelli , Max Filippov Subject: [PATCH v2 3/4] net: ethoc: set up MII management bus clock Date: Wed, 29 Jan 2014 10:00:17 +0400 Message-Id: <1390975218-13863-4-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1390975218-13863-1-git-send-email-jcmvbkbc@gmail.com> References: <1390975218-13863-1-git-send-email-jcmvbkbc@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org MII management bus clock is derived from the MAC clock by dividing it by MIIMODER register CLKDIV field value. This value may need to be set up in case it is undefined or its default value is too high (and communication with PHY is too slow) or too low (and communication with PHY is impossible). The value of CLKDIV is not specified directly, but is derived from the MAC clock for the default MII management bus frequency of 2.5MHz. The MAC clock may be specified in the platform data, or as either 'clock-frequency' or 'clocks' device tree attribute. Signed-off-by: Max Filippov --- Changes v1->v2: - drop MDIO bus frequency configurability, always configure for standard 2.5MHz; - allow using common clock framework to provide ethoc clock. drivers/net/ethernet/ethoc.c | 37 +++++++++++++++++++++++++++++++++++-- include/net/ethoc.h | 1 + 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 5643b2d..5854d41 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -216,6 +217,7 @@ struct ethoc { struct phy_device *phy; struct mii_bus *mdio; + struct clk *clk; s8 phy_id; }; @@ -925,6 +927,8 @@ static int ethoc_probe(struct platform_device *pdev) int num_bd; int ret = 0; bool random_mac = false; + u32 eth_clkfreq = 0; + struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); /* allocate networking device */ netdev = alloc_etherdev(sizeof(struct ethoc)); @@ -1038,8 +1042,7 @@ static int ethoc_probe(struct platform_device *pdev) } /* Allow the platform setup code to pass in a MAC address. */ - if (dev_get_platdata(&pdev->dev)) { - struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); + if (pdata) { memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); priv->phy_id = pdata->phy_id; } else { @@ -1077,6 +1080,32 @@ static int ethoc_probe(struct platform_device *pdev) if (random_mac) netdev->addr_assign_type = NET_ADDR_RANDOM; + /* Allow the platform setup code to adjust MII management bus clock. */ + if (pdata) + eth_clkfreq = pdata->eth_clkfreq; + else + of_property_read_u32(pdev->dev.of_node, + "clock-frequency", ð_clkfreq); + if (!eth_clkfreq) { + struct clk *clk = clk_get(&pdev->dev, NULL); + + if (!IS_ERR(clk)) { + priv->clk = clk; + clk_prepare_enable(clk); + eth_clkfreq = clk_get_rate(clk); + } + } + if (eth_clkfreq) { + u32 clkdiv = MIIMODER_CLKDIV(eth_clkfreq / 2500000 + 1); + + if (!clkdiv) + clkdiv = 2; + dev_dbg(&pdev->dev, "setting MII clkdiv to %u\n", clkdiv); + ethoc_write(priv, MIIMODER, + (ethoc_read(priv, MIIMODER) & MIIMODER_NOPRE) | + clkdiv); + } + /* register MII bus */ priv->mdio = mdiobus_alloc(); if (!priv->mdio) { @@ -1141,6 +1170,8 @@ free_mdio: kfree(priv->mdio->irq); mdiobus_free(priv->mdio); free: + if (priv->clk) + clk_disable_unprepare(priv->clk); free_netdev(netdev); out: return ret; @@ -1165,6 +1196,8 @@ static int ethoc_remove(struct platform_device *pdev) kfree(priv->mdio->irq); mdiobus_free(priv->mdio); } + if (priv->clk) + clk_disable_unprepare(priv->clk); unregister_netdev(netdev); free_netdev(netdev); } diff --git a/include/net/ethoc.h b/include/net/ethoc.h index 96f3789..2a2d6bb 100644 --- a/include/net/ethoc.h +++ b/include/net/ethoc.h @@ -16,6 +16,7 @@ struct ethoc_platform_data { u8 hwaddr[IFHWADDRLEN]; s8 phy_id; + u32 eth_clkfreq; }; #endif /* !LINUX_NET_ETHOC_H */