Commit 9ec092d2 authored by Christian 'Ansuel' Marangi's avatar Christian 'Ansuel' Marangi Committed by Paolo Abeni

net: ethernet: stmmac: add missing sgmii configure for ipq806x

The different gmacid require different configuration based on the soc
and on the gmac id. Add these missing configuration taken from the
original driver.
Signed-off-by: default avatarChristian 'Ansuel' Marangi <ansuelsmth@gmail.com>
Link: https://lore.kernel.org/r/20220614112228.1998-1-ansuelsmth@gmail.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent cfbc80e3
......@@ -83,6 +83,7 @@ config DWMAC_IPQ806X
default ARCH_QCOM
depends on OF && (ARCH_QCOM || COMPILE_TEST)
select MFD_SYSCON
select QCOM_SOCINFO
help
Support for QCA IPQ806X DWMAC Ethernet.
......
......@@ -27,6 +27,8 @@
#include <linux/stmmac.h>
#include <linux/of_mdio.h>
#include <linux/module.h>
#include <linux/sys_soc.h>
#include <linux/bitfield.h>
#include "stmmac_platform.h"
......@@ -75,11 +77,20 @@
#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
#define QSGMII_PHY_QSGMII_EN BIT(7)
#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
#define QSGMII_PHY_DEEMPHASIS_LVL_MASK GENMASK(11, 10)
#define QSGMII_PHY_DEEMPHASIS_LVL(x) FIELD_PREP(QSGMII_PHY_DEEMPHASIS_LVL_MASK, (x))
#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK GENMASK(14, 12)
#define QSGMII_PHY_PHASE_LOOP_GAIN(x) FIELD_PREP(QSGMII_PHY_PHASE_LOOP_GAIN_MASK, (x))
#define QSGMII_PHY_RX_DC_BIAS_MASK GENMASK(19, 18)
#define QSGMII_PHY_RX_DC_BIAS(x) FIELD_PREP(QSGMII_PHY_RX_DC_BIAS_MASK, (x))
#define QSGMII_PHY_RX_INPUT_EQU_MASK GENMASK(21, 20)
#define QSGMII_PHY_RX_INPUT_EQU(x) FIELD_PREP(QSGMII_PHY_RX_INPUT_EQU_MASK, (x))
#define QSGMII_PHY_CDR_PI_SLEW_MASK GENMASK(23, 22)
#define QSGMII_PHY_CDR_PI_SLEW(x) FIELD_PREP(QSGMII_PHY_CDR_PI_SLEW_MASK, (x))
#define QSGMII_PHY_TX_SLEW_MASK GENMASK(27, 26)
#define QSGMII_PHY_TX_SLEW(x) FIELD_PREP(QSGMII_PHY_TX_SLEW_MASK, (x))
#define QSGMII_PHY_TX_DRV_AMP_MASK GENMASK(31, 28)
#define QSGMII_PHY_TX_DRV_AMP(x) FIELD_PREP(QSGMII_PHY_TX_DRV_AMP_MASK, (x))
struct ipq806x_gmac {
struct platform_device *pdev;
......@@ -242,6 +253,64 @@ static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
ipq806x_gmac_set_speed(gmac, speed);
}
static const struct soc_device_attribute ipq806x_gmac_soc_v1[] = {
{
.revision = "1.*",
},
{
/* sentinel */
}
};
static int
ipq806x_gmac_configure_qsgmii_params(struct ipq806x_gmac *gmac)
{
struct platform_device *pdev = gmac->pdev;
const struct soc_device_attribute *soc;
struct device *dev = &pdev->dev;
u32 qsgmii_param;
switch (gmac->id) {
case 1:
soc = soc_device_match(ipq806x_gmac_soc_v1);
if (soc)
qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xc) |
QSGMII_PHY_TX_SLEW(0x2) |
QSGMII_PHY_DEEMPHASIS_LVL(0x2);
else
qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xd) |
QSGMII_PHY_TX_SLEW(0x0) |
QSGMII_PHY_DEEMPHASIS_LVL(0x0);
qsgmii_param |= QSGMII_PHY_RX_DC_BIAS(0x2);
break;
case 2:
case 3:
qsgmii_param = QSGMII_PHY_RX_DC_BIAS(0x3) |
QSGMII_PHY_TX_DRV_AMP(0xc);
break;
default: /* gmac 0 can't be set in SGMII mode */
dev_err(dev, "gmac id %d can't be in SGMII mode", gmac->id);
return -EINVAL;
}
/* Common params across all gmac id */
qsgmii_param |= QSGMII_PHY_CDR_EN |
QSGMII_PHY_RX_FRONT_EN |
QSGMII_PHY_RX_SIGNAL_DETECT_EN |
QSGMII_PHY_TX_DRIVER_EN |
QSGMII_PHY_QSGMII_EN |
QSGMII_PHY_PHASE_LOOP_GAIN(0x4) |
QSGMII_PHY_RX_INPUT_EQU(0x1) |
QSGMII_PHY_CDR_PI_SLEW(0x2);
regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
qsgmii_param);
return 0;
}
static int ipq806x_gmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
......@@ -328,17 +397,9 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
QSGMII_PHY_CDR_EN |
QSGMII_PHY_RX_FRONT_EN |
QSGMII_PHY_RX_SIGNAL_DETECT_EN |
QSGMII_PHY_TX_DRIVER_EN |
QSGMII_PHY_QSGMII_EN |
0x4ul << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
0x3ul << QSGMII_PHY_RX_DC_BIAS_OFFSET |
0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET);
err = ipq806x_gmac_configure_qsgmii_params(gmac);
if (err)
goto err_remove_config_dt;
}
plat_dat->has_gmac = true;
......
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