net: stmmac: dwmac-qcom-ethqos: add support for SGMII
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Mon, 19 Jun 2023 09:23:59 +0000 (11:23 +0200)
committerJakub Kicinski <kuba@kernel.org>
Wed, 21 Jun 2023 03:44:38 +0000 (20:44 -0700)
On sa8775p the MAC is connected to the external PHY over SGMII so add
support for it to the driver.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c

index 0ececc951528efaef00190344e3d3fed279c26ee..bdf59a179f87ebaee5e1ae69c778c759606c44e2 100644 (file)
 #define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL      BIT(6)
 #define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN    BIT(5)
 
+/* MAC_CTRL_REG bits */
+#define ETHQOS_MAC_CTRL_SPEED_MODE             BIT(14)
+#define ETHQOS_MAC_CTRL_PORT_SEL               BIT(15)
+
 struct ethqos_emac_por {
        unsigned int offset;
        unsigned int value;
@@ -92,6 +96,7 @@ struct ethqos_emac_driver_data {
 struct qcom_ethqos {
        struct platform_device *pdev;
        void __iomem *rgmii_base;
+       void __iomem *mac_base;
        int (*configure_func)(struct qcom_ethqos *ethqos);
 
        unsigned int link_clk_rate;
@@ -559,6 +564,33 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)
        return 0;
 }
 
+static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
+{
+       int val;
+
+       val = readl(ethqos->mac_base + MAC_CTRL_REG);
+
+       switch (ethqos->speed) {
+       case SPEED_1000:
+               val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
+               rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+                             RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+                             RGMII_IO_MACRO_CONFIG2);
+               break;
+       case SPEED_100:
+               val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
+               break;
+       case SPEED_10:
+               val |= ETHQOS_MAC_CTRL_PORT_SEL;
+               val &= ~ETHQOS_MAC_CTRL_SPEED_MODE;
+               break;
+       }
+
+       writel(val, ethqos->mac_base + MAC_CTRL_REG);
+
+       return val;
+}
+
 static int ethqos_configure(struct qcom_ethqos *ethqos)
 {
        return ethqos->configure_func(ethqos);
@@ -663,6 +695,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
        case PHY_INTERFACE_MODE_RGMII_TXID:
                ethqos->configure_func = ethqos_configure_rgmii;
                break;
+       case PHY_INTERFACE_MODE_SGMII:
+               ethqos->configure_func = ethqos_configure_sgmii;
+               break;
        case -ENODEV:
                ret = -ENODEV;
                goto out_config_dt;
@@ -678,6 +713,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
                goto out_config_dt;
        }
 
+       ethqos->mac_base = stmmac_res.addr;
+
        data = of_device_get_match_data(dev);
        ethqos->por = data->por;
        ethqos->num_por = data->num_por;