]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
phy: zynqmp: Use eemi framework for performing ULPI reset sequence
authorAnurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Thu, 1 Mar 2018 18:25:06 +0000 (23:55 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 9 Mar 2018 12:17:41 +0000 (13:17 +0100)
This patch modifies the phy-zynqmp.c driver to use eemi framework
for performing ULPI reset sequence.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Documentation/devicetree/bindings/phy/phy-zynqmp.txt
drivers/phy/phy-zynqmp.c

index e2aa61fe26b0b36a743034e6769e90631535c6b4..ed080df891a46658dd0ac90a5218308e2c58556d 100644 (file)
@@ -5,7 +5,8 @@ High Speed Gigabit Transceiver(GT). ZynqMP PS GTR provides four lanes
 and are used by USB, SATA, PCIE, Display port and Ethernet SGMMI controllers.
 
 Required properties (controller (parent) node):
-- compatible    : Should be "xlnx,zynqmp-psgtr"
+- compatible   : Can be "xlnx,zynqmp-psgtr-v1.1" or "xlnx,zynqmp-psgtr"
+                 "xlnx,zynqmp-psgtr-v1.1" has the lpd address mapping removed
 
 - reg           : Address and length of register sets for each device in
                   "reg-names"
index e91584388215da6d77bea376ae006ab616836435..059a9546dca2a187825a114b32739598996f1b30 100644 (file)
 
 #define MAX_LANES                      4
 
-#define RST_ULPI                       0x0250
-#define RST_ULPI_HI                    0x202
-#define RST_ULPI_LOW                   0x02
-
-#define RST_ULPI_TIMEOUT               10
 #define RST_TIMEOUT                    1000
 
 #define ICM_CFG0                       0x10010
@@ -278,7 +273,6 @@ static struct xpsgtr_ssc ssc_lookup[] = {
  * @siou: siou base address
  * @gtr_mutex: mutex for locking
  * @phys: pointer to all the lanes
- * @lpd: base address for low power domain devices reset control
  * @tx_term_fix: fix for GT issue
  * @saved_icm_cfg0: stored value of ICM CFG0 register
  * @saved_icm_cfg1: stored value of ICM CFG1 register
@@ -301,7 +295,6 @@ struct xpsgtr_dev {
        void __iomem *siou;
        struct mutex gtr_mutex;
        struct xpsgtr_phy **phys;
-       void __iomem *lpd;
        bool tx_term_fix;
        unsigned int saved_icm_cfg0;
        unsigned int saved_icm_cfg1;
@@ -902,32 +895,38 @@ static void xpsgtr_misc_sata(struct xpsgtr_phy *gtr_phy)
 }
 
 /**
- * xpsgtr_ulpi_reset - This function does ULPI reset.
+ * xpsgtr_ulpi_reset - This function perform's ULPI reset sequence.
  * @gtr_phy: pointer to lane
+ *
+ * Return: 0 on success, -EINVAL on non existing USB type or error from
+ * communication with firmware
  */
-static void xpsgtr_ulpi_reset(struct xpsgtr_phy *gtr_phy)
+static int xpsgtr_ulpi_reset(struct xpsgtr_phy *gtr_phy)
 {
+       u32 node_id;
+       int ret = 0;
        struct xpsgtr_dev *gtr_dev = gtr_phy->data;
-       unsigned long loop_time = msecs_to_jiffies(RST_ULPI_TIMEOUT);
-       unsigned long timeout;
-
-       writel(RST_ULPI_HI, gtr_dev->lpd + RST_ULPI);
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
 
-       /* wait for some time */
-       timeout = jiffies + loop_time;
-       do {
-               cpu_relax();
-       } while (!time_after_eq(jiffies, timeout));
+       if (!eemi_ops || !eemi_ops->ioctl)
+               return -ENOTSUPP;
 
-       writel(RST_ULPI_LOW, gtr_dev->lpd + RST_ULPI);
+       switch (gtr_phy->type) {
+       case XPSGTR_TYPE_USB0:
+               node_id = NODE_USB_0;
+               break;
+       case XPSGTR_TYPE_USB1:
+               node_id = NODE_USB_1;
+               break;
+       default:
+               return -EINVAL;
+       }
 
-       /* wait for some time */
-       timeout = jiffies + loop_time;
-       do {
-               cpu_relax();
-       } while (!time_after_eq(jiffies, timeout));
+       ret = eemi_ops->ioctl(node_id, IOCTL_ULPI_RESET, 0, 0, NULL);
+       if (ret < 0)
+               dev_err(gtr_dev->dev, "failed to perform ULPI reset\n");
 
-       writel(RST_ULPI_HI, gtr_dev->lpd + RST_ULPI);
+       return ret;
 }
 
 /**
@@ -1142,7 +1141,7 @@ static int xpsgtr_phy_init(struct phy *phy)
 
        /* Do ULPI reset for usb */
        if (gtr_phy->protocol == ICM_PROTOCOL_USB)
-               xpsgtr_ulpi_reset(gtr_phy);
+               ret = xpsgtr_ulpi_reset(gtr_phy);
 
        /* Select SGMII Mode for GEM and set the PCS Signal detect*/
        if (gtr_phy->protocol == ICM_PROTOCOL_SGMII)
@@ -1438,6 +1437,9 @@ static int xpsgtr_probe(struct platform_device *pdev)
        int lanecount, port = 0, index = 0;
        int err;
 
+       if (of_device_is_compatible(np, "xlnx,zynqmp-psgtr"))
+               dev_warn(&pdev->dev, "This binding is deprecated, please use new compatible binding\n");
+
        gtr_dev = devm_kzalloc(&pdev->dev, sizeof(*gtr_dev), GFP_KERNEL);
        if (!gtr_dev)
                return -ENOMEM;
@@ -1452,11 +1454,6 @@ static int xpsgtr_probe(struct platform_device *pdev)
        if (IS_ERR(gtr_dev->siou))
                return PTR_ERR(gtr_dev->siou);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpd");
-       gtr_dev->lpd = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(gtr_dev->lpd))
-               return PTR_ERR(gtr_dev->lpd);
-
        lanecount = of_get_child_count(np);
        if (lanecount > MAX_LANES || lanecount == 0)
                return -EINVAL;
@@ -1569,6 +1566,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = {
 /* Match table for of_platform binding */
 static const struct of_device_id xpsgtr_of_match[] = {
        { .compatible = "xlnx,zynqmp-psgtr", },
+       { .compatible = "xlnx,zynqmp-psgtr-v1.1", },
        {},
 };
 MODULE_DEVICE_TABLE(of, xpsgtr_of_match);