Skip to content

Commit

Permalink
phy: ti: gmii-sel: Add support for CPSW5G GMII SEL in J7200
Browse files Browse the repository at this point in the history
Each of the CPSW5G ports in J7200 support additional modes like QSGMII.
Add a new compatible for J7200 to support the additional modes.

In TI's J7200, each of the CPSW5G ethernet interfaces can act as a
QSGMII or QSGMII-SUB port. The QSGMII interface is responsible for
performing auto-negotiation between the MAC and the PHY while the rest of
the interfaces are designated as QSGMII-SUB interfaces, indicating that
they will not be taking part in the auto-negotiation process.

To indicate the interface which will serve as the main QSGMII interface,
add a property "ti,qsgmii-main-ports", whose value indicates the
port number of the interface which shall serve as the main QSGMII
interface. The rest of the interfaces are then assigned QSGMII-SUB mode by
default. The property "ti,qsgmii-main-ports" is used to configure the
CTRLMMR_ENETx_CTRL register.

Depending on the device, it is possible for more than one QSGMII main port
to exist. Thus, the property "ti,qsgmii-main-ports" is defined as an array
of values in order to reuse the property for other devices.

Signed-off-by: Siddharth Vadapalli <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Vinod Koul <[email protected]>
  • Loading branch information
Siddharth-Vadapalli-at-TI authored and vinodkoul committed Sep 13, 2022
1 parent bd76037 commit af96579
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions drivers/phy/ti/phy-gmii-sel.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
#define AM33XX_GMII_SEL_MODE_RMII 1
#define AM33XX_GMII_SEL_MODE_RGMII 2

/* J72xx SoC specific definitions for the CONTROL port */
#define J72XX_GMII_SEL_MODE_QSGMII 4
#define J72XX_GMII_SEL_MODE_QSGMII_SUB 6

#define PHY_GMII_PORT(n) BIT((n) - 1)

enum {
PHY_GMII_SEL_PORT_MODE = 0,
PHY_GMII_SEL_RGMII_ID_MODE,
Expand All @@ -43,6 +49,7 @@ struct phy_gmii_sel_soc_data {
u32 features;
const struct reg_field (*regfields)[PHY_GMII_SEL_LAST];
bool use_of_data;
u64 extra_modes;
};

struct phy_gmii_sel_priv {
Expand All @@ -53,6 +60,7 @@ struct phy_gmii_sel_priv {
struct phy_gmii_sel_phy_priv *if_phys;
u32 num_ports;
u32 reg_offset;
u32 qsgmii_main_ports;
};

static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
Expand Down Expand Up @@ -88,10 +96,17 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII;
break;

case PHY_INTERFACE_MODE_QSGMII:
if (!(soc_data->extra_modes & BIT(PHY_INTERFACE_MODE_QSGMII)))
goto unsupported;
if (if_phy->priv->qsgmii_main_ports & BIT(if_phy->id - 1))
gmii_sel_mode = J72XX_GMII_SEL_MODE_QSGMII;
else
gmii_sel_mode = J72XX_GMII_SEL_MODE_QSGMII_SUB;
break;

default:
dev_warn(dev, "port%u: unsupported mode: \"%s\"\n",
if_phy->id, phy_modes(submode));
return -EINVAL;
goto unsupported;
}

if_phy->phy_if_mode = submode;
Expand Down Expand Up @@ -123,6 +138,11 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
}

return 0;

unsupported:
dev_warn(dev, "port%u: unsupported mode: \"%s\"\n",
if_phy->id, phy_modes(submode));
return -EINVAL;
}

static const
Expand Down Expand Up @@ -188,6 +208,13 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
.regfields = phy_gmii_sel_fields_am654,
};

static const
struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
.use_of_data = true,
.regfields = phy_gmii_sel_fields_am654,
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII),
};

static const struct of_device_id phy_gmii_sel_id_table[] = {
{
.compatible = "ti,am3352-phy-gmii-sel",
Expand All @@ -209,6 +236,10 @@ static const struct of_device_id phy_gmii_sel_id_table[] = {
.compatible = "ti,am654-phy-gmii-sel",
.data = &phy_gmii_sel_soc_am654,
},
{
.compatible = "ti,j7200-cpsw5g-phy-gmii-sel",
.data = &phy_gmii_sel_cpsw5g_soc_j7200,
},
{}
};
MODULE_DEVICE_TABLE(of, phy_gmii_sel_id_table);
Expand Down Expand Up @@ -350,6 +381,7 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
struct device_node *node = dev->of_node;
const struct of_device_id *of_id;
struct phy_gmii_sel_priv *priv;
u32 main_ports = 1;
int ret;

of_id = of_match_node(phy_gmii_sel_id_table, pdev->dev.of_node);
Expand All @@ -363,6 +395,15 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
priv->soc_data = of_id->data;
priv->num_ports = priv->soc_data->num_ports;
of_property_read_u32(node, "ti,qsgmii-main-ports", &main_ports);
/*
* Ensure that main_ports is within bounds. If the property
* ti,qsgmii-main-ports is not mentioned, or the value mentioned
* is out of bounds, default to 1.
*/
if (main_ports < 1 || main_ports > 4)
main_ports = 1;
priv->qsgmii_main_ports = PHY_GMII_PORT(main_ports);

priv->regmap = syscon_node_to_regmap(node->parent);
if (IS_ERR(priv->regmap)) {
Expand Down

0 comments on commit af96579

Please sign in to comment.