[PATCH] net: zynq_gem: Don't hardcode the MDC clock divisor
Michal Simek
michal.simek at amd.com
Fri Jun 23 14:55:47 CEST 2023
On 6/19/23 05:49, Venkatesh Yadav Abbarapu wrote:
> As per spec MDC must not exceed 2.5MHz, read the pclk clock
> from the device tree and update the MDC clock divisor.
> GEM devices support larger clock divisors and have a different
> range of divisors. Program the MDIO clock divisors based on
> the clock rate of the pclk clock.
>
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
> ---
> drivers/net/zynq_gem.c | 57 ++++++++++++++++++++++++++++++++++++------
> 1 file changed, 49 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
> index 211b2c6e55..f3cdfb0275 100644
> --- a/drivers/net/zynq_gem.c
> +++ b/drivers/net/zynq_gem.c
> @@ -30,6 +30,7 @@
> #include <asm/arch/hardware.h>
> #include <asm/arch/sys_proto.h>
> #include <dm/device_compat.h>
> +#include <linux/bitfield.h>
> #include <linux/bitops.h>
> #include <linux/err.h>
> #include <linux/errno.h>
> @@ -67,11 +68,6 @@
> #define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */
> #define ZYNQ_GEM_NWCFG_SGMII_ENBL 0x08000000 /* SGMII Enable */
> #define ZYNQ_GEM_NWCFG_PCS_SEL 0x00000800 /* PCS select */
> -#ifdef CONFIG_ARM64
> -#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x00100000 /* Div pclk by 64, max 160MHz */
> -#else
> -#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000c0000 /* Div pclk by 48, max 120MHz */
> -#endif
>
> #ifdef CONFIG_ARM64
> # define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
> @@ -81,8 +77,7 @@
>
> #define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_DBUS_WIDTH | \
> ZYNQ_GEM_NWCFG_FDEN | \
> - ZYNQ_GEM_NWCFG_FSREM | \
> - ZYNQ_GEM_NWCFG_MDCCLKDIV)
> + ZYNQ_GEM_NWCFG_FSREM)
>
> #define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */
>
> @@ -141,6 +136,18 @@
>
> #define RXCLK_EN BIT(0)
>
> +/* GEM specific constants for CLK. */
> +#define GEM_CLK_DIV8 0
> +#define GEM_CLK_DIV16 1
> +#define GEM_CLK_DIV32 2
> +#define GEM_CLK_DIV48 3
> +#define GEM_CLK_DIV64 4
> +#define GEM_CLK_DIV96 5
> +#define GEM_CLK_DIV128 6
> +#define GEM_CLK_DIV224 7
> +
> +#define GEM_MDC_SET(val) FIELD_PREP(GENMASK(20, 18), val)
> +
> /* Device registers */
> struct zynq_gem_regs {
> u32 nwctrl; /* 0x0 - Network Control reg */
> @@ -220,6 +227,7 @@ struct zynq_gem_priv {
> struct mii_dev *bus;
> struct clk rx_clk;
> struct clk tx_clk;
> + struct clk pclk;
> u32 max_speed;
> bool int_pcs;
> bool dma_64bit;
> @@ -352,6 +360,32 @@ static int zynq_phy_init(struct udevice *dev)
> return phy_config(priv->phydev);
> }
>
> +static u32 gem_mdc_clk_div(struct zynq_gem_priv *priv)
> +{
> + u32 config;
> + unsigned long pclk_hz;
> +
> + pclk_hz = clk_get_rate(&priv->pclk);
> + if (pclk_hz <= 20000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV8);
> + else if (pclk_hz <= 40000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV16);
> + else if (pclk_hz <= 80000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV32);
> + else if (pclk_hz <= 120000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV48);
> + else if (pclk_hz <= 160000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV64);
> + else if (pclk_hz <= 240000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV96);
> + else if (pclk_hz <= 320000000)
> + config = GEM_MDC_SET(GEM_CLK_DIV128);
> + else
> + config = GEM_MDC_SET(GEM_CLK_DIV224);
> +
> + return config;
> +}
> +
> static int zynq_gem_init(struct udevice *dev)
> {
> u32 i, nwconfig;
> @@ -460,7 +494,8 @@ static int zynq_gem_init(struct udevice *dev)
> return -1;
> }
>
> - nwconfig = ZYNQ_GEM_NWCFG_INIT;
> + nwconfig = gem_mdc_clk_div(priv);
> + nwconfig |= ZYNQ_GEM_NWCFG_INIT;
>
> /*
> * Set SGMII enable PCS selection only if internal PCS/PMA
> @@ -828,6 +863,12 @@ static int zynq_gem_probe(struct udevice *dev)
> }
> }
>
> + ret = clk_get_by_name(dev, "pclk", &priv->pclk);
> + if (ret < 0) {
> + dev_err(dev, "failed to get pclk clock\n");
> + goto err2;
> + }
> +
> if (IS_ENABLED(CONFIG_DM_ETH_PHY))
> priv->bus = eth_phy_get_mdio_bus(dev);
>
Applied.
M
More information about the U-Boot
mailing list