Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Documentation/devicetree/bindings/net/qcom,ethqos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ properties:
phy-names:
const: serdes

qcom,rx-prog-swap:
type: boolean
description:
Swap the sampling occasion on the RX side. This can be used for
tuning when connected to a third-party PHY.

required:
- compatible
- clocks
Expand Down
55 changes: 34 additions & 21 deletions drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct qcom_ethqos {
bool rgmii_config_loopback_en;
bool has_emac_ge_3;
bool needs_sgmii_loopback;
bool needs_rx_prog_swap;
};

static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
Expand Down Expand Up @@ -387,14 +388,12 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
{
struct device *dev = &ethqos->pdev->dev;
int phase_shift;
int rx_prog_swap = 0;
int phase_shift = 0;
int loopback;

/* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */
if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID ||
ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
phase_shift = 0;
else
if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID)
phase_shift = RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN;

/* Disable loopback mode */
Expand All @@ -407,6 +406,9 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
else
loopback = 0;

if (ethqos->needs_rx_prog_swap)
rx_prog_swap = RGMII_CONFIG2_RX_PROG_SWAP;

/* Select RGMII, write 0 to interface select */
rgmii_updatel(ethqos, RGMII_CONFIG_INTF_SEL,
0, RGMII_IO_MACRO_CONFIG);
Expand Down Expand Up @@ -470,14 +472,8 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
BIT(6), RGMII_IO_MACRO_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
0, RGMII_IO_MACRO_CONFIG2);

if (ethqos->has_emac_ge_3)
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
else
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, rx_prog_swap,
RGMII_IO_MACRO_CONFIG2);

/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
Expand Down Expand Up @@ -511,13 +507,9 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
RGMII_IO_MACRO_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
0, RGMII_IO_MACRO_CONFIG2);
if (ethqos->has_emac_ge_3)
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
else
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, rx_prog_swap,
RGMII_IO_MACRO_CONFIG2);

/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
(BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
Expand Down Expand Up @@ -759,7 +751,7 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)

static int qcom_ethqos_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *np = pdev->dev.of_node, *root;
const struct ethqos_emac_driver_data *data;
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
Expand All @@ -785,6 +777,27 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
return -ENOMEM;

ethqos->phy_mode = plat_dat->phy_interface;

root = of_find_node_by_path("/");
if (!root)
return dev_err_probe(dev, ret, "Failed to get root node\n");

if (of_device_is_compatible(root, "qcom,sa8540p-ride"))
ethqos->needs_rx_prog_swap = true;
else
ethqos->needs_rx_prog_swap =
of_property_read_bool(np, "qcom,rx-prog-swap");

if (of_device_is_compatible(root, "qcom,qcs404-evb-4000"))
ethqos->phy_mode = PHY_INTERFACE_MODE_RGMII_ID;
else if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII)
return dev_err_probe(dev, -EINVAL, "Invalid phy-mode rgmii\n");

of_node_put(root);

if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RGMII_ID)
plat_dat->phy_interface = PHY_INTERFACE_MODE_RGMII;

switch (ethqos->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
Expand Down
Loading