OSDN Git Service

msm: pcie: expand PCIe boot option
authorTony Truong <truong@codeaurora.org>
Tue, 28 Feb 2017 23:02:27 +0000 (15:02 -0800)
committerTony Truong <truong@codeaurora.org>
Tue, 4 Apr 2017 23:28:08 +0000 (16:28 -0700)
PCIe clients and endpoints have different boot
sequence. Expand the boot options in PCIe bus
driver to meet their requirements.

Change-Id: Ia244fd402b784e511eefb550d9814d3b708879fd
Signed-off-by: Tony Truong <truong@codeaurora.org>
Documentation/devicetree/bindings/pci/msm_pcie.txt
arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
arch/arm/boot/dts/qcom/msm8996.dtsi
arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi
arch/arm/boot/dts/qcom/msm8998.dtsi
drivers/pci/host/pci-msm.c

index a50e0c2..fc019bd 100644 (file)
@@ -79,8 +79,12 @@ Optional Properties:
     PCIe port PHY.
     Should be specified in groups (offset, value, delay).
   - qcom,use-19p2mhz-aux-clk: The frequency of PCIe AUX clock is 19.2MHz.
-  - qcom,ep-wakeirq: The endpoint will issue wake signal when it is up, and the
-    root complex has the capability to enumerate the endpoint for this case.
+  - qcom,boot-option: Bits that alter PCIe bus driver boot sequence.
+    Below details what happens when each bit is set
+       BIT(0): PCIe bus driver will not start enumeration during its probe.
+               Clients will control when PCIe bus driver should do enumeration.
+       BIT(1): PCIe bus driver will not start enumeration if it receives a WAKE
+               interrupt.
   - qcom,msi-gicm-addr: MSI address for GICv2m.
   - qcom,msi-gicm-base: MSI IRQ base for GICv2m.
   - qcom,ext-ref-clk: The reference clock is external.
@@ -263,7 +267,7 @@ Example:
                qcom,aux-clk-sync;
                qcom,n-fts = <0x50>;
                qcom,pcie-phy-ver = <1>;
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
                qcom,msi-gicm-addr = <0xf9040040>;
                qcom,msi-gicm-base = <0x160>;
                qcom,ext-ref-clk;
index 84b4efd..3cdb399 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 };
 
 &pcie1 {
-       /delete-property/ qcom,ep-wakeirq;
+       /delete-property/ qcom,boot-option;
 };
 
 &pcie2 {
        perst-gpio = <&tlmm 90 0>;
        wake-gpio = <&tlmm 54 0>;
 
-       /delete-property/ qcom,ep-wakeirq;
+       /delete-property/ qcom,boot-option;
 };
 
 &wsa881x_211 {
index 49eafea..6f8f46f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 
                iommus = <&anoc0_smmu>;
 
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
 
                linux,pci-domain = <0>;
 
 
                iommus = <&anoc0_smmu>;
 
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
 
                qcom,ep-latency = <10>;
 
 
                iommus = <&anoc0_smmu>;
 
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
 
                qcom,ep-latency = <10>;
 
index cfb71e3..4a47942 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 
                qcom,ep-latency = <10>;
 
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
 
                linux,pci-domain = <0>;
 
index 02b7a44..33c92c0 100644 (file)
 
                qcom,ep-latency = <10>;
 
-               qcom,ep-wakeirq;
+               qcom,boot-option = <0x1>;
 
                linux,pci-domain = <0>;
 
index 6e9a864..53cb030 100644 (file)
@@ -480,6 +480,11 @@ enum msm_pcie_link_status {
        MSM_PCIE_LINK_DISABLED
 };
 
+enum msm_pcie_boot_option {
+       MSM_PCIE_NO_PROBE_ENUMERATION = BIT(0),
+       MSM_PCIE_NO_WAKE_ENUMERATION = BIT(1)
+};
+
 /* gpio info structure */
 struct msm_pcie_gpio_info_t {
        char    *name;
@@ -628,7 +633,7 @@ struct msm_pcie_dev_t {
        uint32_t                        perst_delay_us_max;
        uint32_t                        tlp_rd_size;
        bool                            linkdown_panic;
-       bool                             ep_wakeirq;
+       uint32_t                        boot_option;
 
        uint32_t                           rc_idx;
        uint32_t                        phy_ver;
@@ -1946,8 +1951,8 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
                dev->aer_enable ? "" : "not");
        PCIE_DBG_FS(dev, "ext_ref_clk is %d\n",
                dev->ext_ref_clk);
-       PCIE_DBG_FS(dev, "ep_wakeirq is %d\n",
-               dev->ep_wakeirq);
+       PCIE_DBG_FS(dev, "boot_option is 0x%x\n",
+               dev->boot_option);
        PCIE_DBG_FS(dev, "phy_ver is %d\n",
                dev->phy_ver);
        PCIE_DBG_FS(dev, "drv_ready is %d\n",
@@ -2562,7 +2567,7 @@ static struct dentry *dfile_linkdown_panic;
 static struct dentry *dfile_wr_offset;
 static struct dentry *dfile_wr_mask;
 static struct dentry *dfile_wr_value;
-static struct dentry *dfile_ep_wakeirq;
+static struct dentry *dfile_boot_option;
 static struct dentry *dfile_aer_enable;
 static struct dentry *dfile_corr_counter_limit;
 
@@ -2831,13 +2836,13 @@ const struct file_operations msm_pcie_wr_value_ops = {
        .write = msm_pcie_set_wr_value,
 };
 
-static ssize_t msm_pcie_set_ep_wakeirq(struct file *file,
+static ssize_t msm_pcie_set_boot_option(struct file *file,
                                const char __user *buf,
                                size_t count, loff_t *ppos)
 {
        unsigned long ret;
        char str[MAX_MSG_LEN];
-       u32 new_ep_wakeirq = 0;
+       u32 new_boot_option = 0;
        int i;
 
        memset(str, 0, sizeof(str));
@@ -2846,33 +2851,33 @@ static ssize_t msm_pcie_set_ep_wakeirq(struct file *file,
                return -EFAULT;
 
        for (i = 0; i < sizeof(str) && (str[i] >= '0') && (str[i] <= '9'); ++i)
-               new_ep_wakeirq = (new_ep_wakeirq * 10) + (str[i] - '0');
+               new_boot_option = (new_boot_option * 10) + (str[i] - '0');
 
-       if (new_ep_wakeirq <= 1) {
+       if (new_boot_option <= 1) {
                for (i = 0; i < MAX_RC_NUM; i++) {
                        if (!rc_sel) {
-                               msm_pcie_dev[0].ep_wakeirq = new_ep_wakeirq;
+                               msm_pcie_dev[0].boot_option = new_boot_option;
                                PCIE_DBG_FS(&msm_pcie_dev[0],
-                                       "PCIe: RC0: ep_wakeirq is now %d\n",
-                                       msm_pcie_dev[0].ep_wakeirq);
+                                       "PCIe: RC0: boot_option is now 0x%x\n",
+                                       msm_pcie_dev[0].boot_option);
                                break;
                        } else if (rc_sel & (1 << i)) {
-                               msm_pcie_dev[i].ep_wakeirq = new_ep_wakeirq;
+                               msm_pcie_dev[i].boot_option = new_boot_option;
                                PCIE_DBG_FS(&msm_pcie_dev[i],
-                                       "PCIe: RC%d: ep_wakeirq is now %d\n",
-                                       i, msm_pcie_dev[i].ep_wakeirq);
+                                       "PCIe: RC%d: boot_option is now 0x%x\n",
+                                       i, msm_pcie_dev[i].boot_option);
                        }
                }
        } else {
-               pr_err("PCIe: Invalid input for ep_wakeirq: %d. Please enter 0 or 1.\n",
-                       new_ep_wakeirq);
+               pr_err("PCIe: Invalid input for boot_option: 0x%x.\n",
+                       new_boot_option);
        }
 
        return count;
 }
 
-const struct file_operations msm_pcie_ep_wakeirq_ops = {
-       .write = msm_pcie_set_ep_wakeirq,
+const struct file_operations msm_pcie_boot_option_ops = {
+       .write = msm_pcie_set_boot_option,
 };
 
 static ssize_t msm_pcie_set_aer_enable(struct file *file,
@@ -3025,12 +3030,12 @@ static void msm_pcie_debugfs_init(void)
                goto wr_value_error;
        }
 
-       dfile_ep_wakeirq = debugfs_create_file("ep_wakeirq", 0664,
+       dfile_boot_option = debugfs_create_file("boot_option", 0664,
                                        dent_msm_pcie, 0,
-                                       &msm_pcie_ep_wakeirq_ops);
-       if (!dfile_ep_wakeirq || IS_ERR(dfile_ep_wakeirq)) {
-               pr_err("PCIe: fail to create the file for debug_fs ep_wakeirq.\n");
-               goto ep_wakeirq_error;
+                                       &msm_pcie_boot_option_ops);
+       if (!dfile_boot_option || IS_ERR(dfile_boot_option)) {
+               pr_err("PCIe: fail to create the file for debug_fs boot_option.\n");
+               goto boot_option_error;
        }
 
        dfile_aer_enable = debugfs_create_file("aer_enable", 0664,
@@ -3053,8 +3058,8 @@ static void msm_pcie_debugfs_init(void)
 corr_counter_limit_error:
        debugfs_remove(dfile_aer_enable);
 aer_enable_error:
-       debugfs_remove(dfile_ep_wakeirq);
-ep_wakeirq_error:
+       debugfs_remove(dfile_boot_option);
+boot_option_error:
        debugfs_remove(dfile_wr_value);
 wr_value_error:
        debugfs_remove(dfile_wr_mask);
@@ -3081,7 +3086,7 @@ static void msm_pcie_debugfs_exit(void)
        debugfs_remove(dfile_wr_offset);
        debugfs_remove(dfile_wr_mask);
        debugfs_remove(dfile_wr_value);
-       debugfs_remove(dfile_ep_wakeirq);
+       debugfs_remove(dfile_boot_option);
        debugfs_remove(dfile_aer_enable);
        debugfs_remove(dfile_corr_counter_limit);
 }
@@ -5408,14 +5413,10 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
        PCIE_DBG2(dev, "PCIe WAKE is asserted by Endpoint of RC%d\n",
                dev->rc_idx);
 
-       if (!dev->enumerated) {
-               PCIE_DBG(dev, "Start enumeating RC%d\n", dev->rc_idx);
-               if (dev->ep_wakeirq)
-                       schedule_work(&dev->handle_wake_work);
-               else
-                       PCIE_DBG(dev,
-                               "wake irq is received but ep_wakeirq is not supported for RC%d.\n",
-                               dev->rc_idx);
+       if (!dev->enumerated && !(dev->boot_option &
+               MSM_PCIE_NO_WAKE_ENUMERATION)) {
+               PCIE_DBG(dev, "Start enumerating RC%d\n", dev->rc_idx);
+               schedule_work(&dev->handle_wake_work);
        } else {
                PCIE_DBG2(dev, "Wake up RC%d\n", dev->rc_idx);
                __pm_stay_awake(&dev->ws);
@@ -6089,12 +6090,12 @@ static int msm_pcie_probe(struct platform_device *pdev)
                        msm_pcie_dev[rc_idx].rc_idx,
                        msm_pcie_dev[rc_idx].smmu_sid_base);
 
-       msm_pcie_dev[rc_idx].ep_wakeirq =
-               of_property_read_bool((&pdev->dev)->of_node,
-                               "qcom,ep-wakeirq");
+       msm_pcie_dev[rc_idx].boot_option = 0;
+       ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,boot-option",
+                               &msm_pcie_dev[rc_idx].boot_option);
        PCIE_DBG(&msm_pcie_dev[rc_idx],
-               "PCIe: EP of RC%d does %s assert wake when it is up.\n",
-               rc_idx, msm_pcie_dev[rc_idx].ep_wakeirq ? "" : "not");
+               "PCIe: RC%d boot option is 0x%x.\n",
+               rc_idx, msm_pcie_dev[rc_idx].boot_option);
 
        msm_pcie_dev[rc_idx].phy_ver = 1;
        ret = of_property_read_u32((&pdev->dev)->of_node,
@@ -6373,9 +6374,10 @@ static int msm_pcie_probe(struct platform_device *pdev)
 
        msm_pcie_dev[rc_idx].drv_ready = true;
 
-       if (msm_pcie_dev[rc_idx].ep_wakeirq) {
+       if (msm_pcie_dev[rc_idx].boot_option &
+                       MSM_PCIE_NO_PROBE_ENUMERATION) {
                PCIE_DBG(&msm_pcie_dev[rc_idx],
-                       "PCIe: RC%d will be enumerated upon WAKE signal from Endpoint.\n",
+                       "PCIe: RC%d will be enumerated by client or endpoint.\n",
                        rc_idx);
                mutex_unlock(&pcie_drv.drv_lock);
                return 0;