OSDN Git Service

msm_11ad: disbale L1 for 11ad device
authorMaya Erez <merez@codeaurora.org>
Fri, 11 Nov 2016 21:38:22 +0000 (23:38 +0200)
committerMaya Erez <merez@codeaurora.org>
Fri, 11 Nov 2016 21:38:22 +0000 (23:38 +0200)
Enabling L1 / L1SS for 11ad device causes PCIe
link down or PCIe NOC read/write timeouts.
To prevent that, disable L1 for 11ad devices after
PCIe enumeration and resume.

Change-Id: I5061c95855d462879c2f5237ded80131de4d215d
Signed-off-by: Maya Erez <merez@codeaurora.org>
drivers/platform/msm/msm_11ad/msm_11ad.c

index 45fedfa..5810f7b 100644 (file)
@@ -51,6 +51,9 @@
 #define VDDIO_MAX_UV   2040000
 #define VDDIO_MAX_UA   70300
 
+#define DISABLE_PCIE_L1_MASK 0xFFFFFFFD
+#define PCIE20_CAP_LINKCTRLSTATUS 0x80
+
 struct device;
 
 static const char * const gpio_en_name = "qcom,wigig-en";
@@ -505,6 +508,7 @@ static int ops_resume(void *handle)
        int rc;
        struct msm11ad_ctx *ctx = handle;
        struct pci_dev *pcidev;
+       u32 val;
 
        pr_info("%s(%p)\n", __func__, handle);
        if (!ctx) {
@@ -548,6 +552,27 @@ static int ops_resume(void *handle)
                goto err_suspend_rc;
        }
 
+       /* Disable L1 */
+       rc = pci_read_config_dword(ctx->pcidev,
+                                  PCIE20_CAP_LINKCTRLSTATUS, &val);
+       if (rc) {
+               dev_err(ctx->dev,
+                       "reading PCIE20_CAP_LINKCTRLSTATUS failed:%d\n",
+                       rc);
+               goto err_suspend_rc;
+       }
+       val &= DISABLE_PCIE_L1_MASK; /* disable bit 1 */
+       dev_dbg(ctx->dev, "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x)\n",
+               val);
+       rc = pci_write_config_dword(ctx->pcidev,
+                                   PCIE20_CAP_LINKCTRLSTATUS, val);
+       if (rc) {
+               dev_err(ctx->dev,
+                       "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x) failed:%d\n",
+                       val, rc);
+               goto err_suspend_rc;
+       }
+
        return 0;
 
 err_suspend_rc:
@@ -792,6 +817,7 @@ static int msm_11ad_probe(struct platform_device *pdev)
        struct device_node *rc_node;
        struct pci_dev *pcidev = NULL;
        int rc;
+       u32 val;
 
        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
@@ -907,6 +933,28 @@ static int msm_11ad_probe(struct platform_device *pdev)
                goto out_rc;
        }
        ctx->pcidev = pcidev;
+
+       /* Disable L1 */
+       rc = pci_read_config_dword(ctx->pcidev,
+                                  PCIE20_CAP_LINKCTRLSTATUS, &val);
+       if (rc) {
+               dev_err(ctx->dev,
+                       "reading PCIE20_CAP_LINKCTRLSTATUS failed:%d\n",
+                       rc);
+               goto out_rc;
+       }
+       val &= DISABLE_PCIE_L1_MASK; /* disable bit 1 */
+       dev_dbg(ctx->dev, "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x)\n",
+                val);
+       rc = pci_write_config_dword(ctx->pcidev,
+                                   PCIE20_CAP_LINKCTRLSTATUS, val);
+       if (rc) {
+               dev_err(ctx->dev,
+                       "writing PCIE20_CAP_LINKCTRLSTATUS (val 0x%x) failed:%d\n",
+                       val, rc);
+               goto out_rc;
+       }
+
        rc = pci_save_state(pcidev);
        if (rc) {
                dev_err(ctx->dev, "pci_save_state failed :%d\n", rc);