Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ Where:
 o pbl: the Programmable Burst Length is maximum number of beats to
       be transferred in one DMA transaction.
       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 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.
+10 −0
Original line number Diff line number Diff line
@@ -97,6 +97,16 @@ struct stmmac_extra_stats {
	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 PAUSE_TIME 0x200

+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ struct stmmac_priv {
#ifdef CONFIG_HAVE_CLK
	struct clk *stmmac_clk;
#endif
	int clk_csr;
};

extern int phyaddr;
+40 −0
Original line number Diff line number Diff line
@@ -163,6 +163,35 @@ static void stmmac_verify_args(void)
		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)
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))
		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;

error:
+2 −2
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
	int data;
	u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
			((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))
		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)))
	    | 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 */
	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))