Commit 0471005e authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'add-support-for-qsgmii-mode-for-j721e-cpsw9g-to-am65-cpsw-driver'

Siddharth Vadapalli says:

====================
Add support for QSGMII mode for J721e CPSW9G to am65-cpsw driver

Add compatible to am65-cpsw driver for J721e CPSW9G, which contains 8
external ports and 1 internal host port.

Add support to power on and power off the SERDES PHY which is used by the
CPSW MAC.

=========
Changelog
=========
v5:
https://lore.kernel.org/r/20221109042203.375042-1-s-vadapalli@ti.com/
v4:
https://lore.kernel.org/r/20221108080606.124596-1-s-vadapalli@ti.com/
v3:
https://lore.kernel.org/r/20221026090957.180592-1-s-vadapalli@ti.com/
v2:
https://lore.kernel.org/r/20221018085810.151327-1-s-vadapalli@ti.com/
v1:
https://lore.kernel.org/r/20220914095053.189851-1-s-vadapalli@ti.com/
====================

Link: https://lore.kernel.org/r/20230104103432.1126403-1-s-vadapalli@ti.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents d75858ef dab2b265
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ properties:
      - ti,am654-cpsw-nuss
      - ti,j7200-cpswxg-nuss
      - ti,j721e-cpsw-nuss
      - ti,j721e-cpswxg-nuss
      - ti,am642-cpsw-nuss

  reg:
@@ -111,7 +112,7 @@ properties:
        const: 0

    patternProperties:
      "^port@[1-4]$":
      "^port@[1-8]$":
        type: object
        description: CPSWxG NUSS external ports

@@ -121,7 +122,7 @@ properties:
        properties:
          reg:
            minimum: 1
            maximum: 4
            maximum: 8
            description: CPSW port number

          phys:
@@ -186,12 +187,36 @@ allOf:
        properties:
          compatible:
            contains:
              const: ti,j7200-cpswxg-nuss
              const: ti,j721e-cpswxg-nuss
    then:
      properties:
        ethernet-ports:
          patternProperties:
            "^port@[5-8]$": false
            "^port@[1-4]$":
              properties:
                reg:
                  minimum: 1
                  maximum: 4

  - if:
      not:
        properties:
          compatible:
            contains:
              enum:
                - ti,j721e-cpswxg-nuss
                - ti,j7200-cpswxg-nuss
    then:
      properties:
        ethernet-ports:
          patternProperties:
            "^port@[3-4]$": false
            "^port@[3-8]$": false
            "^port@[1-2]$":
              properties:
                reg:
                  minimum: 1
                  maximum: 2

additionalProperties: false

+76 −0
Original line number Diff line number Diff line
@@ -1416,6 +1416,68 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops = {
	.ndo_setup_tc           = am65_cpsw_qos_ndo_setup_tc,
};

static void am65_cpsw_disable_phy(struct phy *phy)
{
	phy_power_off(phy);
	phy_exit(phy);
}

static int am65_cpsw_enable_phy(struct phy *phy)
{
	int ret;

	ret = phy_init(phy);
	if (ret < 0)
		return ret;

	ret = phy_power_on(phy);
	if (ret < 0) {
		phy_exit(phy);
		return ret;
	}

	return 0;
}

static void am65_cpsw_disable_serdes_phy(struct am65_cpsw_common *common)
{
	struct am65_cpsw_port *port;
	struct phy *phy;
	int i;

	for (i = 0; i < common->port_num; i++) {
		port = &common->ports[i];
		phy = port->slave.serdes_phy;
		if (phy)
			am65_cpsw_disable_phy(phy);
	}
}

static int am65_cpsw_init_serdes_phy(struct device *dev, struct device_node *port_np,
				     struct am65_cpsw_port *port)
{
	const char *name = "serdes-phy";
	struct phy *phy;
	int ret;

	phy = devm_of_phy_get(dev, port_np, name);
	if (PTR_ERR(phy) == -ENODEV)
		return 0;

	/* Serdes PHY exists. Store it. */
	port->slave.serdes_phy = phy;

	ret =  am65_cpsw_enable_phy(phy);
	if (ret < 0)
		goto err_phy;

	return 0;

err_phy:
	devm_phy_put(dev, phy);
	return ret;
}

static void am65_cpsw_nuss_mac_config(struct phylink_config *config, unsigned int mode,
				      const struct phylink_link_state *state)
{
@@ -1959,6 +2021,11 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
			goto of_node_put;
		}

		/* Initialize the Serdes PHY for the port */
		ret = am65_cpsw_init_serdes_phy(dev, port_np, port);
		if (ret)
			return ret;

		port->slave.mac_only =
				of_property_read_bool(port_np, "ti,mac-only");

@@ -2684,11 +2751,19 @@ static const struct am65_cpsw_pdata j7200_cpswxg_pdata = {
	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII),
};

static const struct am65_cpsw_pdata j721e_cpswxg_pdata = {
	.quirks = 0,
	.ale_dev_id = "am64-cpswxg",
	.fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII),
};

static const struct of_device_id am65_cpsw_nuss_of_mtable[] = {
	{ .compatible = "ti,am654-cpsw-nuss", .data = &am65x_sr1_0},
	{ .compatible = "ti,j721e-cpsw-nuss", .data = &j721e_pdata},
	{ .compatible = "ti,am642-cpsw-nuss", .data = &am64x_cpswxg_pdata},
	{ .compatible = "ti,j7200-cpswxg-nuss", .data = &j7200_cpswxg_pdata},
	{ .compatible = "ti,j721e-cpswxg-nuss", .data = &j721e_cpswxg_pdata},
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, am65_cpsw_nuss_of_mtable);
@@ -2870,6 +2945,7 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
	 */
	am65_cpsw_nuss_cleanup_ndev(common);
	am65_cpsw_nuss_phylink_cleanup(common);
	am65_cpsw_disable_serdes_phy(common);

	of_platform_device_destroy(common->mdio_dev, NULL);

+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct am65_cpsw_slave_data {
	struct device_node		*phy_node;
	phy_interface_t			phy_if;
	struct phy			*ifphy;
	struct phy			*serdes_phy;
	bool				rx_pause;
	bool				tx_pause;
	u8				mac_addr[ETH_ALEN];