mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
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>
This commit is contained in:
parent
18f05d64ec
commit
cd7201f477
@ -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 {
|
|||||||
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 {
|
|||||||
#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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
(((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))
|
||||||
|
Loading…
Reference in New Issue
Block a user