drivers: phy: integrate the mt8183 phy driver to U-Boot

The driver is coming from Linux kernel.
This updates it to work with U-Boot

Note that the driver has a lost support of all phy but USB device.
In addition, the integration has lost support of platform other
than mt8183 and mt2712 (untested).
This was required to simplify the integration and bring up USB support
quickly.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 9ebe648..55c430c 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -206,12 +206,11 @@
 	  This PHY is found on MT76x8 devices supporting USB.
 
 config PHY_MTK_TPHY
-    tristate "MediaTek T-PHY Driver"
-    depends on ARCH_MEDIATEK && OF
-    select GENERIC_PHY
-    help
-      Say 'Y' here to add support for MediaTek T-PHY driver,
-      it supports multiple usb2.0, usb3.0 ports, PCIe and
+	tristate "MediaTek T-PHY Driver"
+	depends on PHY
+	help
+	Say 'Y' here to add support for MediaTek T-PHY driver,
+	it supports multiple usb2.0, usb3.0 ports, PCIe and
 	  SATA, and meanwhile supports two version T-PHY which have
 	  different banks layout, the T-PHY with shared banks between
 	  multi-ports is first version, otherwise is second veriosn,
diff --git a/drivers/phy/phy-mtk-tphy.c b/drivers/phy/phy-mtk-tphy.c
index 3eb8e1b..21d59e8 100644
--- a/drivers/phy/phy-mtk-tphy.c
+++ b/drivers/phy/phy-mtk-tphy.c
@@ -5,16 +5,19 @@
  *
  */
 
+#include <clk.h>
+#include <dm/device.h>
+#include <dm/of_addr.h>
 #include <dt-bindings/phy/phy.h>
-#include <linux/clk.h>
+#include <generic-phy.h>
+
+#include <linux/compat.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/bitops.h>
+
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -288,13 +291,13 @@
 };
 
 struct mtk_phy_instance {
+	ofnode node;
 	struct phy *phy;
 	void __iomem *port_base;
 	union {
 		struct u2phy_banks u2_banks;
 		struct u3phy_banks u3_banks;
 	};
-	struct clk *ref_clk;	/* reference clock of anolog phy */
 	u32 index;
 	u8 type;
 	int eye_src;
@@ -304,10 +307,8 @@
 };
 
 struct mtk_tphy {
-	struct device *dev;
+	struct udevice *dev;
 	void __iomem *sif_base;	/* only shared sif */
-	/* deprecated, use @ref_clk instead in phy instance */
-	struct clk *u3phya_ref;	/* reference clock of usb3 anolog phy */
 	const struct mtk_phy_pdata *pdata;
 	struct mtk_phy_instance **phys;
 	int nphys;
@@ -344,8 +345,6 @@
 	tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
 	tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL);
 	tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT);
-	if (tphy->pdata->version == MTK_PHY_V1)
-		tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index >> 1);
 
 	writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
 
@@ -356,7 +355,7 @@
 
 	/* ignore return value */
 	readl_poll_timeout(fmreg + U3P_U2FREQ_FMMONR1, tmp,
-			   (tmp & P2F_USB_FM_VALID), 10, 200);
+			   (tmp & P2F_USB_FM_VALID), 200);
 
 	fm_out = readl(fmreg + U3P_U2FREQ_VALUE);
 
@@ -607,209 +606,12 @@
 	case PHY_MODE_USB_DEVICE:
 		tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
 		break;
-	case PHY_MODE_USB_HOST:
-		tmp |= P2C_FORCE_IDDIG;
-		tmp &= ~P2C_RG_IDDIG;
-		break;
-	case PHY_MODE_USB_OTG:
-		tmp &= ~(P2C_FORCE_IDDIG | P2C_RG_IDDIG);
-		break;
 	default:
 		return;
 	}
 	writel(tmp, u2_banks->com + U3P_U2PHYDTM1);
 }
 
-static void pcie_phy_instance_init(struct mtk_tphy *tphy,
-	struct mtk_phy_instance *instance)
-{
-	struct u3phy_banks *u3_banks = &instance->u3_banks;
-	u32 tmp;
-
-	if (tphy->pdata->version != MTK_PHY_V1)
-		return;
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
-	tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H);
-	tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0);
-
-	/* ref clk drive */
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG1);
-	tmp &= ~P3A_RG_CLKDRV_AMP;
-	tmp |= P3A_RG_CLKDRV_AMP_VAL(0x4);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG1);
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
-	tmp &= ~P3A_RG_CLKDRV_OFF;
-	tmp |= P3A_RG_CLKDRV_OFF_VAL(0x1);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
-
-	/* SSC delta -5000ppm */
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG20);
-	tmp &= ~P3A_RG_PLL_DELTA1_PE2H;
-	tmp |= P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG20);
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG25);
-	tmp &= ~P3A_RG_PLL_DELTA_PE2H;
-	tmp |= P3A_RG_PLL_DELTA_PE2H_VAL(0x36);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG25);
-
-	/* change pll BW 0.6M */
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG5);
-	tmp &= ~(P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H);
-	tmp |= P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG5);
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG4);
-	tmp &= ~(P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H);
-	tmp |= P3A_RG_PLL_BC_PE2H_VAL(0x3);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG4);
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG6);
-	tmp &= ~P3A_RG_PLL_IR_PE2H;
-	tmp |= P3A_RG_PLL_IR_PE2H_VAL(0x2);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG6);
-
-	tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG7);
-	tmp &= ~P3A_RG_PLL_BP_PE2H;
-	tmp |= P3A_RG_PLL_BP_PE2H_VAL(0xa);
-	writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG7);
-
-	/* Tx Detect Rx Timing: 10us -> 5us */
-	tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1);
-	tmp &= ~P3D_RG_RXDET_STB2_SET;
-	tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10);
-	writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1);
-
-	tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2);
-	tmp &= ~P3D_RG_RXDET_STB2_SET_P3;
-	tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
-	writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
-
-	/* wait for PCIe subsys register to active */
-	usleep_range(2500, 3000);
-	dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
-}
-
-static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
-	struct mtk_phy_instance *instance)
-{
-	struct u3phy_banks *bank = &instance->u3_banks;
-	u32 tmp;
-
-	tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
-	tmp &= ~(P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
-	writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
-
-	tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
-	tmp &= ~(P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
-	writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
-}
-
-static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
-	struct mtk_phy_instance *instance)
-
-{
-	struct u3phy_banks *bank = &instance->u3_banks;
-	u32 tmp;
-
-	tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
-	tmp |= P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST;
-	writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
-
-	tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
-	tmp |= P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD;
-	writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
-}
-
-static void sata_phy_instance_init(struct mtk_tphy *tphy,
-	struct mtk_phy_instance *instance)
-{
-	struct u3phy_banks *u3_banks = &instance->u3_banks;
-	void __iomem *phyd = u3_banks->phyd;
-	u32 tmp;
-
-	/* charge current adjustment */
-	tmp = readl(phyd + ANA_RG_CTRL_SIGNAL6);
-	tmp &= ~(RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK);
-	tmp |= RG_CDR_BIRLTR_GEN1_VAL(0x6) | RG_CDR_BC_GEN1_VAL(0x1a);
-	writel(tmp, phyd + ANA_RG_CTRL_SIGNAL6);
-
-	tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL4);
-	tmp &= ~RG_CDR_BIRLTD0_GEN1_MSK;
-	tmp |= RG_CDR_BIRLTD0_GEN1_VAL(0x18);
-	writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL4);
-
-	tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL5);
-	tmp &= ~RG_CDR_BIRLTD0_GEN3_MSK;
-	tmp |= RG_CDR_BIRLTD0_GEN3_VAL(0x06);
-	writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL5);
-
-	tmp = readl(phyd + ANA_RG_CTRL_SIGNAL4);
-	tmp &= ~(RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK);
-	tmp |= RG_CDR_BICLTR_GEN1_VAL(0x0c) | RG_CDR_BR_GEN2_VAL(0x07);
-	writel(tmp, phyd + ANA_RG_CTRL_SIGNAL4);
-
-	tmp = readl(phyd + PHYD_CTRL_SIGNAL_MODE4);
-	tmp &= ~(RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK);
-	tmp |= RG_CDR_BICLTD0_GEN1_VAL(0x08) | RG_CDR_BICLTD1_GEN1_VAL(0x02);
-	writel(tmp, phyd + PHYD_CTRL_SIGNAL_MODE4);
-
-	tmp = readl(phyd + PHYD_DESIGN_OPTION2);
-	tmp &= ~RG_LOCK_CNT_SEL_MSK;
-	tmp |= RG_LOCK_CNT_SEL_VAL(0x02);
-	writel(tmp, phyd + PHYD_DESIGN_OPTION2);
-
-	tmp = readl(phyd + PHYD_DESIGN_OPTION9);
-	tmp &= ~(RG_T2_MIN_MSK | RG_TG_MIN_MSK |
-		 RG_T2_MAX_MSK | RG_TG_MAX_MSK);
-	tmp |= RG_T2_MIN_VAL(0x12) | RG_TG_MIN_VAL(0x04) |
-	       RG_T2_MAX_VAL(0x31) | RG_TG_MAX_VAL(0x0e);
-	writel(tmp, phyd + PHYD_DESIGN_OPTION9);
-
-	tmp = readl(phyd + ANA_RG_CTRL_SIGNAL1);
-	tmp &= ~RG_IDRV_0DB_GEN1_MSK;
-	tmp |= RG_IDRV_0DB_GEN1_VAL(0x20);
-	writel(tmp, phyd + ANA_RG_CTRL_SIGNAL1);
-
-	tmp = readl(phyd + ANA_EQ_EYE_CTRL_SIGNAL1);
-	tmp &= ~RG_EQ_DLEQ_LFI_GEN1_MSK;
-	tmp |= RG_EQ_DLEQ_LFI_GEN1_VAL(0x03);
-	writel(tmp, phyd + ANA_EQ_EYE_CTRL_SIGNAL1);
-
-	dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
-}
-
-static void phy_v1_banks_init(struct mtk_tphy *tphy,
-			      struct mtk_phy_instance *instance)
-{
-	struct u2phy_banks *u2_banks = &instance->u2_banks;
-	struct u3phy_banks *u3_banks = &instance->u3_banks;
-
-	switch (instance->type) {
-	case PHY_TYPE_USB2:
-		u2_banks->misc = NULL;
-		u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
-		u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
-		break;
-	case PHY_TYPE_USB3:
-	case PHY_TYPE_PCIE:
-		u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
-		u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
-		u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
-		u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
-		break;
-	case PHY_TYPE_SATA:
-		u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
-		break;
-	default:
-		dev_err(tphy->dev, "incompatible PHY type\n");
-		return;
-	}
-}
-
 static void phy_v2_banks_init(struct mtk_tphy *tphy,
 			      struct mtk_phy_instance *instance)
 {
@@ -838,18 +640,18 @@
 static void phy_parse_property(struct mtk_tphy *tphy,
 				struct mtk_phy_instance *instance)
 {
-	struct device *dev = &instance->phy->dev;
+	struct udevice *dev = instance->phy->dev;
 
 	if (instance->type != PHY_TYPE_USB2)
 		return;
 
-	instance->bc12_en = device_property_read_bool(dev, "mediatek,bc12");
-	device_property_read_u32(dev, "mediatek,eye-src",
-				 &instance->eye_src);
-	device_property_read_u32(dev, "mediatek,eye-vrt",
-				 &instance->eye_vrt);
-	device_property_read_u32(dev, "mediatek,eye-term",
-				 &instance->eye_term);
+	instance->bc12_en = ofnode_read_bool(dev->node, "mediatek,bc12");
+	ofnode_read_u32(dev->node, "mediatek,eye-src",
+			(u32 *)&instance->eye_src);
+	ofnode_read_u32(dev->node, "mediatek,eye-vrt",
+			(u32 *)&instance->eye_vrt);
+	ofnode_read_u32(dev->node, "mediatek,eye-term",
+			(u32 *)&instance->eye_term);
 	dev_dbg(dev, "bc12:%d, src:%d, vrt:%d, term:%d\n",
 		instance->bc12_en, instance->eye_src,
 		instance->eye_vrt, instance->eye_term);
@@ -890,23 +692,31 @@
 	}
 }
 
+static inline void phy_set_drvdata(struct phy *phy, void *data)
+{
+	phy->dev->platdata = data;
+}
+
+static inline void *phy_get_drvdata(struct phy *phy)
+{
+	return dev_get_platdata(phy->dev);
+}
+
+static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+	struct mtk_tphy *tphy = dev_get_priv(phy->dev);
+
+	if (instance->type == PHY_TYPE_USB2)
+		u2_phy_instance_set_mode(tphy, instance, mode);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
-	int ret;
-
-	ret = clk_prepare_enable(tphy->u3phya_ref);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable u3phya_ref\n");
-		return ret;
-	}
-
-	ret = clk_prepare_enable(instance->ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable ref_clk\n");
-		return ret;
-	}
+	struct mtk_tphy *tphy = dev_get_priv(phy->dev);
 
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
@@ -916,12 +726,6 @@
 	case PHY_TYPE_USB3:
 		u3_phy_instance_init(tphy, instance);
 		break;
-	case PHY_TYPE_PCIE:
-		pcie_phy_instance_init(tphy, instance);
-		break;
-	case PHY_TYPE_SATA:
-		sata_phy_instance_init(tphy, instance);
-		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
 		return -EINVAL;
@@ -933,14 +737,15 @@
 static int mtk_phy_power_on(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+	struct mtk_tphy *tphy = dev_get_priv(phy->dev);
+
+	mtk_phy_set_mode(phy, PHY_MODE_USB_DEVICE);
 
 	if (instance->type == PHY_TYPE_USB2) {
 		u2_phy_instance_power_on(tphy, instance);
 		hs_slew_rate_calibrate(tphy, instance);
-	} else if (instance->type == PHY_TYPE_PCIE) {
-		pcie_phy_instance_power_on(tphy, instance);
-	}
+	} else
+		return -EIO;
 
 	return 0;
 }
@@ -948,12 +753,12 @@
 static int mtk_phy_power_off(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+	struct mtk_tphy *tphy = dev_get_priv(phy->dev);
 
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_power_off(tphy, instance);
-	else if (instance->type == PHY_TYPE_PCIE)
-		pcie_phy_instance_power_off(tphy, instance);
+	else
+		return -EIO;
 
 	return 0;
 }
@@ -961,72 +766,71 @@
 static int mtk_phy_exit(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+	struct mtk_tphy *tphy = dev_get_priv(phy->dev);
 
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_exit(tphy, instance);
-
-	clk_disable_unprepare(instance->ref_clk);
-	clk_disable_unprepare(tphy->u3phya_ref);
 	return 0;
 }
 
-static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode)
+static int mtk_phy_xlate(struct phy *phy, struct ofnode_phandle_args *args)
 {
-	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
-
-	if (instance->type == PHY_TYPE_USB2)
-		u2_phy_instance_set_mode(tphy, instance, mode);
-
-	return 0;
-}
-
-static struct phy *mtk_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
-{
-	struct mtk_tphy *tphy = dev_get_drvdata(dev);
+	struct resource res;
+	struct udevice *dev = phy->dev;
+	struct mtk_tphy *tphy = dev_get_priv(dev);
 	struct mtk_phy_instance *instance = NULL;
-	struct device_node *phy_np = args->np;
 	int index;
+	int ret;
 
-	if (args->args_count != 1) {
+	if (args->args_count != 2) {
 		dev_err(dev, "invalid number of cells in 'phy' property\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	for (index = 0; index < tphy->nphys; index++)
-		if (phy_np == tphy->phys[index]->phy->dev.of_node) {
+		if (ofnode_to_np(args->node) == ofnode_to_np(tphy->phys[index]->node)) {
 			instance = tphy->phys[index];
 			break;
 		}
 
 	if (!instance) {
 		dev_err(dev, "failed to find appropriate phy\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	instance->type = args->args[0];
+	instance->phy = phy;
+	instance->type = args->args[1];
 	if (!(instance->type == PHY_TYPE_USB2 ||
-	      instance->type == PHY_TYPE_USB3 ||
-	      instance->type == PHY_TYPE_PCIE ||
-	      instance->type == PHY_TYPE_SATA)) {
+	      instance->type == PHY_TYPE_USB3)) {
 		dev_err(dev, "unsupported device type: %d\n", instance->type);
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	if (tphy->pdata->version == MTK_PHY_V1) {
-		phy_v1_banks_init(tphy, instance);
-	} else if (tphy->pdata->version == MTK_PHY_V2) {
+	ret = of_address_to_resource(ofnode_to_np(args->node), 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to get address resource\n");
+		return ret;
+	}
+
+	instance->port_base = devm_ioremap(&phy->dev, res.start,
+					   resource_size(&res));
+	if (IS_ERR(instance->port_base)) {
+		dev_err(dev, "failed to remap phy regs\n");
+		return PTR_ERR(instance->port_base);
+	}
+
+	if (tphy->pdata->version == MTK_PHY_V2) {
 		phy_v2_banks_init(tphy, instance);
 	} else {
 		dev_err(dev, "phy version is not supported\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
-
 	phy_parse_property(tphy, instance);
 
-	return instance->phy;
+	instance->phy = phy;
+	phy_set_drvdata(phy, instance);
+
+	return 0;
 }
 
 static const struct phy_ops mtk_tphy_ops = {
@@ -1034,13 +838,7 @@
 	.exit		= mtk_phy_exit,
 	.power_on	= mtk_phy_power_on,
 	.power_off	= mtk_phy_power_off,
-	.set_mode	= mtk_phy_set_mode,
-	.owner		= THIS_MODULE,
-};
-
-static const struct mtk_phy_pdata tphy_v1_pdata = {
-	.avoid_rx_sen_degradation = false,
-	.version = MTK_PHY_V1,
+	.of_xlate		= mtk_phy_xlate,
 };
 
 static const struct mtk_phy_pdata tphy_v2_pdata = {
@@ -1048,145 +846,74 @@
 	.version = MTK_PHY_V2,
 };
 
-static const struct mtk_phy_pdata mt8173_pdata = {
-	.avoid_rx_sen_degradation = true,
-	.version = MTK_PHY_V1,
-};
-
-static const struct of_device_id mtk_tphy_id_table[] = {
-	{ .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
-	{ .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
-	{ .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
-	{ .compatible = "mediatek,generic-tphy-v1", .data = &tphy_v1_pdata },
-	{ .compatible = "mediatek,generic-tphy-v2", .data = &tphy_v2_pdata },
+static const struct udevice_id mtk_tphy_id_table[] = {
+	{ .compatible = "mediatek,mt2712-u3phy", .data = (ulong)&tphy_v2_pdata },
+	{ .compatible = "mediatek,generic-tphy-v2", .data = (ulong)&tphy_v2_pdata },
 	{ },
 };
-MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
 
-static int mtk_tphy_probe(struct platform_device *pdev)
+int ofnode_subnode_count(ofnode node) {
+	ofnode child_node;
+	int count = 0;
+
+	ofnode_for_each_subnode(child_node, node)
+		count++;
+
+	return count;
+};
+
+static int mtk_tphy_probe(struct udevice *dev)
 {
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct device_node *child_np;
-	struct phy_provider *provider;
-	struct resource *sif_res;
+	ofnode child_node;
 	struct mtk_tphy *tphy;
-	struct resource res;
 	int port, retval;
+	ofnode node = dev->node;
 
-	tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
-	if (!tphy)
-		return -ENOMEM;
-
-	tphy->pdata = of_device_get_match_data(dev);
+	tphy = dev_get_priv(dev);
+	tphy->pdata = (const struct mtk_phy_pdata *) dev_get_driver_data(dev);
 	if (!tphy->pdata)
 		return -EINVAL;
 
-	tphy->nphys = of_get_child_count(np);
+	tphy->nphys = ofnode_subnode_count(node);
 	tphy->phys = devm_kcalloc(dev, tphy->nphys,
 				       sizeof(*tphy->phys), GFP_KERNEL);
 	if (!tphy->phys)
 		return -ENOMEM;
-
 	tphy->dev = dev;
-	platform_set_drvdata(pdev, tphy);
-
-	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	/* SATA phy of V1 needn't it if not shared with PCIe or USB */
-	if (sif_res && tphy->pdata->version == MTK_PHY_V1) {
-		/* get banks shared by multiple phys */
-		tphy->sif_base = devm_ioremap_resource(dev, sif_res);
-		if (IS_ERR(tphy->sif_base)) {
-			dev_err(dev, "failed to remap sif regs\n");
-			return PTR_ERR(tphy->sif_base);
-		}
-	}
-
-	/* it's deprecated, make it optional for backward compatibility */
-	tphy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
-	if (IS_ERR(tphy->u3phya_ref)) {
-		if (PTR_ERR(tphy->u3phya_ref) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-
-		tphy->u3phya_ref = NULL;
-	}
 
 	tphy->src_ref_clk = U3P_REF_CLK;
 	tphy->src_coef = U3P_SLEW_RATE_COEF;
 	/* update parameters of slew rate calibrate if exist */
-	device_property_read_u32(dev, "mediatek,src-ref-clk-mhz",
-		&tphy->src_ref_clk);
-	device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef);
+	ofnode_read_u32(node, "mediatek,src-ref-clk-mhz",
+			(u32 *)&tphy->src_ref_clk);
+	ofnode_read_u32(node, "mediatek,src-coef", (u32 *)&tphy->src_coef);
 
 	port = 0;
-	for_each_child_of_node(np, child_np) {
+	ofnode_for_each_subnode(child_node, node) {
 		struct mtk_phy_instance *instance;
-		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
 		if (!instance) {
 			retval = -ENOMEM;
 			goto put_child;
 		}
-
+		instance->node = child_node;
 		tphy->phys[port] = instance;
 
-		phy = devm_phy_create(dev, child_np, &mtk_tphy_ops);
-		if (IS_ERR(phy)) {
-			dev_err(dev, "failed to create phy\n");
-			retval = PTR_ERR(phy);
-			goto put_child;
-		}
-
-		retval = of_address_to_resource(child_np, 0, &res);
-		if (retval) {
-			dev_err(dev, "failed to get address resource(id-%d)\n",
-				port);
-			goto put_child;
-		}
-
-		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
-		if (IS_ERR(instance->port_base)) {
-			dev_err(dev, "failed to remap phy regs\n");
-			retval = PTR_ERR(instance->port_base);
-			goto put_child;
-		}
-
-		instance->phy = phy;
 		instance->index = port;
-		phy_set_drvdata(phy, instance);
 		port++;
-
-		/* if deprecated clock is provided, ignore instance's one */
-		if (tphy->u3phya_ref)
-			continue;
-
-		instance->ref_clk = devm_clk_get(&phy->dev, "ref");
-		if (IS_ERR(instance->ref_clk)) {
-			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->ref_clk);
-			goto put_child;
-		}
 	}
 
-	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-
-	return PTR_ERR_OR_ZERO(provider);
+	return 0;
 put_child:
-	of_node_put(child_np);
 	return retval;
 }
 
-static struct platform_driver mtk_tphy_driver = {
-	.probe		= mtk_tphy_probe,
-	.driver		= {
-		.name	= "mtk-tphy",
-		.of_match_table = mtk_tphy_id_table,
-	},
+U_BOOT_DRIVER(phy_mtk_tphy) = {
+	.name   = "phy_mtk_tphy",
+	.id     = UCLASS_PHY,
+	.of_match = mtk_tphy_id_table,
+	.probe = mtk_tphy_probe,
+	.ops = &mtk_tphy_ops,
+	.priv_auto_alloc_size = sizeof(struct mtk_tphy),
 };
-
-module_platform_driver(mtk_tphy_driver);
-
-MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
-MODULE_DESCRIPTION("MediaTek T-PHY driver");
-MODULE_LICENSE("GPL v2");