phy: phy-mtk-tphy: add support new version
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Sat, 2 May 2020 09:35:16 +0000 (11:35 +0200)
committerMarek Vasut <marek.vasut+renesas@gmail.com>
Sat, 2 May 2020 10:32:28 +0000 (12:32 +0200)
The new version removes all shared banks between multi-phys

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
Reviewed-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/phy/phy-mtk-tphy.c

index 71bc706..20167fe 100644 (file)
 #define SSUSB_SIFSLV_V1_U3PHYD         0x000
 #define SSUSB_SIFSLV_V1_U3PHYA         0x200
 
+/* version V2 sub-banks offset base address */
+/* u2 phy banks */
+#define SSUSB_SIFSLV_V2_MISC           0x000
+#define SSUSB_SIFSLV_V2_U2FREQ         0x100
+#define SSUSB_SIFSLV_V2_U2PHY_COM      0x300
+/* u3/pcie/sata phy banks */
+#define SSUSB_SIFSLV_V2_SPLLC          0x000
+#define SSUSB_SIFSLV_V2_CHIP           0x100
+#define SSUSB_SIFSLV_V2_U3PHYD         0x200
+#define SSUSB_SIFSLV_V2_U3PHYA         0x400
+
 #define U3P_USBPHYACR0                 0x000
 #define PA0_RG_U2PLL_FORCE_ON          BIT(15)
 #define PA0_RG_USB20_INTR_EN           BIT(5)
 #define XC3_RG_U3_XTAL_RX_PWD          BIT(9)
 #define XC3_RG_U3_FRC_XTAL_RX_PWD      BIT(8)
 
+enum mtk_phy_version {
+       MTK_TPHY_V1 = 1,
+       MTK_TPHY_V2,
+};
+
 struct u2phy_banks {
        void __iomem *misc;
        void __iomem *fmreg;
@@ -192,6 +208,7 @@ struct mtk_phy_instance {
 struct mtk_tphy {
        struct udevice *dev;
        void __iomem *sif_base;
+       enum mtk_phy_version version;
        struct mtk_phy_instance **phys;
        int nphys;
 };
@@ -304,6 +321,9 @@ static void pcie_phy_instance_init(struct mtk_tphy *tphy,
 {
        struct u3phy_banks *u3_banks = &instance->u3_banks;
 
+       if (tphy->version != MTK_TPHY_V1)
+               return;
+
        clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
                        P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
                        P3A_RG_XTAL_EXT_PE1H_VAL(0x2) |
@@ -398,6 +418,31 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy,
        }
 }
 
+static void phy_v2_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 = instance->port_base + SSUSB_SIFSLV_V2_MISC;
+               u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
+               u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
+               break;
+       case PHY_TYPE_USB3:
+       case PHY_TYPE_PCIE:
+               u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
+               u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
+               u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
+               u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
+               break;
+       default:
+               dev_err(tphy->dev, "incompatible PHY type\n");
+               return;
+       }
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
        struct mtk_tphy *tphy = dev_get_priv(phy->dev);
@@ -500,7 +545,14 @@ static int mtk_phy_xlate(struct phy *phy,
                return -EINVAL;
        }
 
-       phy_v1_banks_init(tphy, instance);
+       if (tphy->version == MTK_TPHY_V1) {
+               phy_v1_banks_init(tphy, instance);
+       } else if (tphy->version == MTK_TPHY_V2) {
+               phy_v2_banks_init(tphy, instance);
+       } else {
+               dev_err(phy->dev, "phy version is not supported\n");
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -527,9 +579,14 @@ static int mtk_tphy_probe(struct udevice *dev)
                return -ENOMEM;
 
        tphy->dev = dev;
-       tphy->sif_base = dev_read_addr_ptr(dev);
-       if (!tphy->sif_base)
-               return -ENOENT;
+       tphy->version = dev_get_driver_data(dev);
+
+       /* v1 has shared banks */
+       if (tphy->version == MTK_TPHY_V1) {
+               tphy->sif_base = dev_read_addr_ptr(dev);
+               if (!tphy->sif_base)
+                       return -ENOENT;
+       }
 
        dev_for_each_subnode(subnode, dev) {
                struct mtk_phy_instance *instance;
@@ -560,7 +617,8 @@ static int mtk_tphy_probe(struct udevice *dev)
 }
 
 static const struct udevice_id mtk_tphy_id_table[] = {
-       { .compatible = "mediatek,generic-tphy-v1", },
+       { .compatible = "mediatek,generic-tphy-v1", .data = MTK_TPHY_V1, },
+       { .compatible = "mediatek,generic-tphy-v2", .data = MTK_TPHY_V2, },
        { }
 };