Commit cd7201f4 authored by Giuseppe CAVALLARO's avatar Giuseppe CAVALLARO Committed by David S. Miller

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: default avatarDeepak Sikri <deepak.sikri@st.com>
Signed-off-by: default avatarGiuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: default avatarFrancesco Virlinzi <francesco.virlinzi@st.com>
Reviewed-by: default avatarDavid Laight <david.laight@aculab.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 18f05d64
...@@ -137,7 +137,7 @@ Where: ...@@ -137,7 +137,7 @@ Where:
o pbl: the Programmable Burst Length is maximum number of beats to o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction. be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default. GMAC also enables the 4xPBL by default.
o clk_csr: CSR Clock range selection. o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core. o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure. o enh_desc: if sets the MAC will use the enhanced descriptor structure.
o tx_coe: core is able to perform the tx csum in HW. o tx_coe: core is able to perform the tx csum in HW.
......
...@@ -97,6 +97,16 @@ struct stmmac_extra_stats { ...@@ -97,6 +97,16 @@ struct stmmac_extra_stats {
unsigned long normal_irq_n; unsigned long normal_irq_n;
}; };
/* CSR Frequency Access Defines*/
#define CSR_F_35M 35000000
#define CSR_F_60M 60000000
#define CSR_F_100M 100000000
#define CSR_F_150M 150000000
#define CSR_F_250M 250000000
#define CSR_F_300M 300000000
#define MAC_CSR_H_FRQ_MASK 0x20
#define HASH_TABLE_SIZE 64 #define HASH_TABLE_SIZE 64
#define PAUSE_TIME 0x200 #define PAUSE_TIME 0x200
......
...@@ -84,6 +84,7 @@ struct stmmac_priv { ...@@ -84,6 +84,7 @@ struct stmmac_priv {
#ifdef CONFIG_HAVE_CLK #ifdef CONFIG_HAVE_CLK
struct clk *stmmac_clk; struct clk *stmmac_clk;
#endif #endif
int clk_csr;
}; };
extern int phyaddr; extern int phyaddr;
......
...@@ -163,6 +163,35 @@ static void stmmac_verify_args(void) ...@@ -163,6 +163,35 @@ static void stmmac_verify_args(void)
pause = PAUSE_TIME; pause = PAUSE_TIME;
} }
static void stmmac_clk_csr_set(struct stmmac_priv *priv)
{
#ifdef CONFIG_HAVE_CLK
u32 clk_rate;
clk_rate = clk_get_rate(priv->stmmac_clk);
/* Platform provided default clk_csr would be assumed valid
* for all other cases except for the below mentioned ones. */
if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
if (clk_rate < CSR_F_35M)
priv->clk_csr = STMMAC_CSR_20_35M;
else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
priv->clk_csr = STMMAC_CSR_35_60M;
else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
priv->clk_csr = STMMAC_CSR_60_100M;
else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
priv->clk_csr = STMMAC_CSR_100_150M;
else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
priv->clk_csr = STMMAC_CSR_150_250M;
else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
priv->clk_csr = STMMAC_CSR_250_300M;
} /* For values higher than the IEEE 802.3 specified frequency
* we can not estimate the proper divider as it is not known
* the frequency of clk_csr_i. So we do not change the default
* divider. */
#endif
}
#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
static void print_pkt(unsigned char *buf, int len) static void print_pkt(unsigned char *buf, int len)
{ {
...@@ -1890,6 +1919,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ...@@ -1890,6 +1919,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
if (stmmac_clk_get(priv)) if (stmmac_clk_get(priv))
goto error; goto error;
/* 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. Viceversa the driver'll try to
* set the MDC clock dynamically according to the csr actual
* clock input.
*/
if (!priv->plat->clk_csr)
stmmac_clk_csr_set(priv);
else
priv->clk_csr = priv->plat->clk_csr;
return priv; return priv;
error: error:
......
...@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) ...@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
int data; int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) | u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0))); ((phyreg << 6) & (0x000007C0)));
regValue |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2); regValue |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
return -EBUSY; return -EBUSY;
...@@ -106,7 +106,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, ...@@ -106,7 +106,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE; | MII_WRITE;
value |= MII_BUSY | ((priv->plat->clk_csr & 0xF) << 2); value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
/* Wait until any existing MII operation is complete */ /* Wait until any existing MII operation is complete */
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address)) if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment