phy: hisilicon: Add inno-usb2-phy driver for Hi3798MV100
authorDavid Yang <mmyangfl@gmail.com>
Tue, 9 May 2023 06:04:44 +0000 (14:04 +0800)
committerVinod Koul <vkoul@kernel.org>
Tue, 16 May 2023 14:14:29 +0000 (19:44 +0530)
Adopt existing phy-hisi-inno-usb2 driver to Hi3798MV100, with a slightly
different TEST register convention.

Signed-off-by: David Yang <mmyangfl@gmail.com>
Link: https://lore.kernel.org/r/20230509060449.1151113-2-mmyangfl@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/hisilicon/phy-hisi-inno-usb2.c

index b133ae0..15dafe3 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
+#include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/reset.h>
 
 #define PHY_CLK_STABLE_TIME    2       /* unit:ms */
 #define UTMI_RST_COMPLETE_TIME 2       /* unit:ms */
 #define POR_RST_COMPLETE_TIME  300     /* unit:us */
+
+#define PHY_TYPE_0     0
+#define PHY_TYPE_1     1
+
 #define PHY_TEST_DATA          GENMASK(7, 0)
-#define PHY_TEST_ADDR          GENMASK(15, 8)
-#define PHY_TEST_PORT          GENMASK(18, 16)
-#define PHY_TEST_WREN          BIT(21)
-#define PHY_TEST_CLK           BIT(22) /* rising edge active */
-#define PHY_TEST_RST           BIT(23) /* low active */
+#define PHY_TEST_ADDR_OFFSET   8
+#define PHY0_TEST_ADDR         GENMASK(15, 8)
+#define PHY0_TEST_PORT_OFFSET  16
+#define PHY0_TEST_PORT         GENMASK(18, 16)
+#define PHY0_TEST_WREN         BIT(21)
+#define PHY0_TEST_CLK          BIT(22) /* rising edge active */
+#define PHY0_TEST_RST          BIT(23) /* low active */
+#define PHY1_TEST_ADDR         GENMASK(11, 8)
+#define PHY1_TEST_PORT_OFFSET  12
+#define PHY1_TEST_PORT         BIT(12)
+#define PHY1_TEST_WREN         BIT(13)
+#define PHY1_TEST_CLK          BIT(14) /* rising edge active */
+#define PHY1_TEST_RST          BIT(15) /* low active */
+
 #define PHY_CLK_ENABLE         BIT(2)
 
 struct hisi_inno_phy_port {
@@ -37,6 +50,7 @@ struct hisi_inno_phy_priv {
        void __iomem *mmio;
        struct clk *ref_clk;
        struct reset_control *por_rst;
+       unsigned int type;
        struct hisi_inno_phy_port ports[INNO_PHY_PORT_NUM];
 };
 
@@ -45,17 +59,27 @@ static void hisi_inno_phy_write_reg(struct hisi_inno_phy_priv *priv,
 {
        void __iomem *reg = priv->mmio;
        u32 val;
-
-       val = (data & PHY_TEST_DATA) |
-             ((addr << 8) & PHY_TEST_ADDR) |
-             ((port << 16) & PHY_TEST_PORT) |
-             PHY_TEST_WREN | PHY_TEST_RST;
+       u32 value;
+
+       if (priv->type == PHY_TYPE_0)
+               val = (data & PHY_TEST_DATA) |
+                     ((addr << PHY_TEST_ADDR_OFFSET) & PHY0_TEST_ADDR) |
+                     ((port << PHY0_TEST_PORT_OFFSET) & PHY0_TEST_PORT) |
+                     PHY0_TEST_WREN | PHY0_TEST_RST;
+       else
+               val = (data & PHY_TEST_DATA) |
+                     ((addr << PHY_TEST_ADDR_OFFSET) & PHY1_TEST_ADDR) |
+                     ((port << PHY1_TEST_PORT_OFFSET) & PHY1_TEST_PORT) |
+                     PHY1_TEST_WREN | PHY1_TEST_RST;
        writel(val, reg);
 
-       val |= PHY_TEST_CLK;
-       writel(val, reg);
+       value = val;
+       if (priv->type == PHY_TYPE_0)
+               value |= PHY0_TEST_CLK;
+       else
+               value |= PHY1_TEST_CLK;
+       writel(value, reg);
 
-       val &= ~PHY_TEST_CLK;
        writel(val, reg);
 }
 
@@ -135,6 +159,8 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
        if (IS_ERR(priv->por_rst))
                return PTR_ERR(priv->por_rst);
 
+       priv->type = (uintptr_t) of_device_get_match_data(dev);
+
        for_each_child_of_node(np, child) {
                struct reset_control *rst;
                struct phy *phy;
@@ -170,8 +196,12 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id hisi_inno_phy_of_match[] = {
-       { .compatible = "hisilicon,inno-usb2-phy", },
-       { .compatible = "hisilicon,hi3798cv200-usb2-phy", },
+       { .compatible = "hisilicon,inno-usb2-phy",
+         .data = (void *) PHY_TYPE_0 },
+       { .compatible = "hisilicon,hi3798cv200-usb2-phy",
+         .data = (void *) PHY_TYPE_0 },
+       { .compatible = "hisilicon,hi3798mv100-usb2-phy",
+         .data = (void *) PHY_TYPE_1 },
        { },
 };
 MODULE_DEVICE_TABLE(of, hisi_inno_phy_of_match);