aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2012-04-04 00:33:27 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-04 18:39:24 -0400
commitcd7201f477b965f6c0220b798813c7000bc603c5 (patch)
tree0b5ac87d64a90efc1ddfca8620019c13fd0acad8 /drivers/net
parent18f05d64ec36e27892cc0f55be707762aae053a1 (diff)
stmmac: MDC clock dynamically based on the csr clock input
If a specific clk_csr value is passed from the platform this means that the CSR Clock Range selection cannot be changed at run-time and it is fixed (as reported in the driver documentation). Viceversa the driver will try to set the MDC clock dynamically according to the actual clock input. Signed-off-by: Deepak Sikri <deepak.sikri@st.com> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Reviewed-by: Francesco Virlinzi <francesco.virlinzi@st.com> Reviewed-by: David Laight <david.laight@aculab.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h10
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c40
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c4
4 files changed, 53 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index b14829f8085d..9e42b5d32cff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -97,6 +97,16 @@ struct stmmac_extra_stats {
97 unsigned long normal_irq_n; 97 unsigned long normal_irq_n;
98}; 98};
99 99
100/* CSR Frequency Access Defines*/
101#define CSR_F_35M 35000000
102#define CSR_F_60M 60000000
103#define CSR_F_100M 100000000
104#define CSR_F_150M 150000000
105#define CSR_F_250M 250000000
106#define CSR_F_300M 300000000
107
108#define MAC_CSR_H_FRQ_MASK 0x20
109
100#define HASH_TABLE_SIZE 64 110#define HASH_TABLE_SIZE 64
101#define PAUSE_TIME 0x200 111#define PAUSE_TIME 0x200
102 112
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 7182f159c2c9..ddd07691cef1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -84,6 +84,7 @@ struct stmmac_priv {
84#ifdef CONFIG_HAVE_CLK 84#ifdef CONFIG_HAVE_CLK
85 struct clk *stmmac_clk; 85 struct clk *stmmac_clk;
86#endif 86#endif
87 int clk_csr;
87}; 88};
88 89
89extern int phyaddr; 90extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ddb47e147f70..90d5c4c75d25 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -163,6 +163,35 @@ static void stmmac_verify_args(void)
163 pause = PAUSE_TIME; 163 pause = PAUSE_TIME;
164} 164}
165 165
166static void stmmac_clk_csr_set(struct stmmac_priv *priv)
167{
168#ifdef CONFIG_HAVE_CLK
169 u32 clk_rate;
170
171 clk_rate = clk_get_rate(priv->stmmac_clk);
172
173 /* Platform provided default clk_csr would be assumed valid
174 * for all other cases except for the below mentioned ones. */
175 if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
176 if (clk_rate < CSR_F_35M)
177 priv->clk_csr = STMMAC_CSR_20_35M;
178 else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
179 priv->clk_csr = STMMAC_CSR_35_60M;
180 else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
181 priv->clk_csr = STMMAC_CSR_60_100M;
182 else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
183 priv->clk_csr = STMMAC_CSR_100_150M;
184 else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
185 priv->clk_csr = STMMAC_CSR_150_250M;
186 else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
187 priv->clk_csr = STMMAC_CSR_250_300M;
188 } /* For values higher than the IEEE 802.3 specified frequency
189 * we can not estimate the proper divider as it is not known
190 * the frequency of clk_csr_i. So we do not change the default
191 * divider. */
192#endif
193}
194
166#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 195#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
167static void print_pkt(unsigned char *buf, int len) 196static void print_pkt(unsigned char *buf, int len)
168{ 197{
@@ -1890,6 +1919,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
1890 if (stmmac_clk_get(priv)) 1919 if (stmmac_clk_get(priv))
1891 goto error; 1920 goto error;
1892 1921
1922 /* If a specific clk_csr value is passed from the platform
1923 * this means that the CSR Clock Range selection cannot be
1924 * changed at run-time and it is fixed. Viceversa the driver'll try to
1925 * set the MDC clock dynamically according to the csr actual
1926 * clock input.
1927 */
1928 if (!priv->plat->clk_csr)
1929 stmmac_clk_csr_set(priv);
1930 else
1931 priv->clk_csr = priv->plat->clk_csr;
1932
1893 return priv; 1933 return priv;
1894 1934
1895error: 1935error:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 1a420142f6ac..ade108232048 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
70 int data; 70 int data;
71 u16 regValue = (((phyaddr << 11) & (0x0000F800)) | 71 u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
72 ((phyreg << 6) & (0x000007C0))); 72 ((phyreg << 6) & (0x000007C0)));
73 regValue |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2); 73 regValue |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
74 74
75 if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 75 if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
76 return -EBUSY; 76 return -EBUSY;
@@ -106,7 +106,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
106 (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) 106 (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
107 | MII_WRITE; 107 | MII_WRITE;
108 108
109 value |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2); 109 value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
110 110
111 /* Wait until any existing MII operation is complete */ 111 /* Wait until any existing MII operation is complete */
112 if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) 112 if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))