Merge "msm: pcie: expand PCIe boot option"

This commit is contained in:
Linux Build Service Account 2017-04-06 14:33:14 -07:00 committed by Gerrit - the friendly Code Review server
commit 61bae6eff7
6 changed files with 58 additions and 52 deletions

View file

@ -79,8 +79,12 @@ Optional Properties:
PCIe port PHY. PCIe port PHY.
Should be specified in groups (offset, value, delay). Should be specified in groups (offset, value, delay).
- qcom,use-19p2mhz-aux-clk: The frequency of PCIe AUX clock is 19.2MHz. - 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 - qcom,boot-option: Bits that alter PCIe bus driver boot sequence.
root complex has the capability to enumerate the endpoint for this case. 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-addr: MSI address for GICv2m.
- qcom,msi-gicm-base: MSI IRQ base for GICv2m. - qcom,msi-gicm-base: MSI IRQ base for GICv2m.
- qcom,ext-ref-clk: The reference clock is external. - qcom,ext-ref-clk: The reference clock is external.
@ -263,7 +267,7 @@ Example:
qcom,aux-clk-sync; qcom,aux-clk-sync;
qcom,n-fts = <0x50>; qcom,n-fts = <0x50>;
qcom,pcie-phy-ver = <1>; qcom,pcie-phy-ver = <1>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
qcom,msi-gicm-addr = <0xf9040040>; qcom,msi-gicm-addr = <0xf9040040>;
qcom,msi-gicm-base = <0x160>; qcom,msi-gicm-base = <0x160>;
qcom,ext-ref-clk; qcom,ext-ref-clk;

View file

@ -974,14 +974,14 @@
}; };
&pcie1 { &pcie1 {
/delete-property/ qcom,ep-wakeirq; /delete-property/ qcom,boot-option;
}; };
&pcie2 { &pcie2 {
perst-gpio = <&tlmm 90 0>; perst-gpio = <&tlmm 90 0>;
wake-gpio = <&tlmm 54 0>; wake-gpio = <&tlmm 54 0>;
/delete-property/ qcom,ep-wakeirq; /delete-property/ qcom,boot-option;
}; };
&wsa881x_211 { &wsa881x_211 {

View file

@ -1371,7 +1371,7 @@
iommus = <&anoc0_smmu>; iommus = <&anoc0_smmu>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
linux,pci-domain = <0>; linux,pci-domain = <0>;
@ -1524,7 +1524,7 @@
iommus = <&anoc0_smmu>; iommus = <&anoc0_smmu>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
qcom,ep-latency = <10>; qcom,ep-latency = <10>;
@ -1677,7 +1677,7 @@
iommus = <&anoc0_smmu>; iommus = <&anoc0_smmu>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
qcom,ep-latency = <10>; qcom,ep-latency = <10>;

View 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 * 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 * it under the terms of the GNU General Public License version 2 and
@ -1590,7 +1590,7 @@
qcom,ep-latency = <10>; qcom,ep-latency = <10>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
linux,pci-domain = <0>; linux,pci-domain = <0>;

View file

@ -2678,7 +2678,7 @@
qcom,ep-latency = <10>; qcom,ep-latency = <10>;
qcom,ep-wakeirq; qcom,boot-option = <0x1>;
linux,pci-domain = <0>; linux,pci-domain = <0>;

View file

@ -481,6 +481,11 @@ enum msm_pcie_link_status {
MSM_PCIE_LINK_DISABLED 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 */ /* gpio info structure */
struct msm_pcie_gpio_info_t { struct msm_pcie_gpio_info_t {
char *name; char *name;
@ -629,7 +634,7 @@ struct msm_pcie_dev_t {
uint32_t perst_delay_us_max; uint32_t perst_delay_us_max;
uint32_t tlp_rd_size; uint32_t tlp_rd_size;
bool linkdown_panic; bool linkdown_panic;
bool ep_wakeirq; uint32_t boot_option;
uint32_t rc_idx; uint32_t rc_idx;
uint32_t phy_ver; uint32_t phy_ver;
@ -1947,8 +1952,8 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
dev->aer_enable ? "" : "not"); dev->aer_enable ? "" : "not");
PCIE_DBG_FS(dev, "ext_ref_clk is %d\n", PCIE_DBG_FS(dev, "ext_ref_clk is %d\n",
dev->ext_ref_clk); dev->ext_ref_clk);
PCIE_DBG_FS(dev, "ep_wakeirq is %d\n", PCIE_DBG_FS(dev, "boot_option is 0x%x\n",
dev->ep_wakeirq); dev->boot_option);
PCIE_DBG_FS(dev, "phy_ver is %d\n", PCIE_DBG_FS(dev, "phy_ver is %d\n",
dev->phy_ver); dev->phy_ver);
PCIE_DBG_FS(dev, "drv_ready is %d\n", PCIE_DBG_FS(dev, "drv_ready is %d\n",
@ -2563,7 +2568,7 @@ static struct dentry *dfile_linkdown_panic;
static struct dentry *dfile_wr_offset; static struct dentry *dfile_wr_offset;
static struct dentry *dfile_wr_mask; static struct dentry *dfile_wr_mask;
static struct dentry *dfile_wr_value; 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_aer_enable;
static struct dentry *dfile_corr_counter_limit; static struct dentry *dfile_corr_counter_limit;
@ -2832,13 +2837,13 @@ const struct file_operations msm_pcie_wr_value_ops = {
.write = msm_pcie_set_wr_value, .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, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
unsigned long ret; unsigned long ret;
char str[MAX_MSG_LEN]; char str[MAX_MSG_LEN];
u32 new_ep_wakeirq = 0; u32 new_boot_option = 0;
int i; int i;
memset(str, 0, sizeof(str)); memset(str, 0, sizeof(str));
@ -2847,33 +2852,33 @@ static ssize_t msm_pcie_set_ep_wakeirq(struct file *file,
return -EFAULT; return -EFAULT;
for (i = 0; i < sizeof(str) && (str[i] >= '0') && (str[i] <= '9'); ++i) 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++) { for (i = 0; i < MAX_RC_NUM; i++) {
if (!rc_sel) { 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_DBG_FS(&msm_pcie_dev[0],
"PCIe: RC0: ep_wakeirq is now %d\n", "PCIe: RC0: boot_option is now 0x%x\n",
msm_pcie_dev[0].ep_wakeirq); msm_pcie_dev[0].boot_option);
break; break;
} else if (rc_sel & (1 << i)) { } 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_DBG_FS(&msm_pcie_dev[i],
"PCIe: RC%d: ep_wakeirq is now %d\n", "PCIe: RC%d: boot_option is now 0x%x\n",
i, msm_pcie_dev[i].ep_wakeirq); i, msm_pcie_dev[i].boot_option);
} }
} }
} else { } else {
pr_err("PCIe: Invalid input for ep_wakeirq: %d. Please enter 0 or 1.\n", pr_err("PCIe: Invalid input for boot_option: 0x%x.\n",
new_ep_wakeirq); new_boot_option);
} }
return count; return count;
} }
const struct file_operations msm_pcie_ep_wakeirq_ops = { const struct file_operations msm_pcie_boot_option_ops = {
.write = msm_pcie_set_ep_wakeirq, .write = msm_pcie_set_boot_option,
}; };
static ssize_t msm_pcie_set_aer_enable(struct file *file, static ssize_t msm_pcie_set_aer_enable(struct file *file,
@ -3026,12 +3031,12 @@ static void msm_pcie_debugfs_init(void)
goto wr_value_error; 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, dent_msm_pcie, 0,
&msm_pcie_ep_wakeirq_ops); &msm_pcie_boot_option_ops);
if (!dfile_ep_wakeirq || IS_ERR(dfile_ep_wakeirq)) { if (!dfile_boot_option || IS_ERR(dfile_boot_option)) {
pr_err("PCIe: fail to create the file for debug_fs ep_wakeirq.\n"); pr_err("PCIe: fail to create the file for debug_fs boot_option.\n");
goto ep_wakeirq_error; goto boot_option_error;
} }
dfile_aer_enable = debugfs_create_file("aer_enable", 0664, dfile_aer_enable = debugfs_create_file("aer_enable", 0664,
@ -3054,8 +3059,8 @@ static void msm_pcie_debugfs_init(void)
corr_counter_limit_error: corr_counter_limit_error:
debugfs_remove(dfile_aer_enable); debugfs_remove(dfile_aer_enable);
aer_enable_error: aer_enable_error:
debugfs_remove(dfile_ep_wakeirq); debugfs_remove(dfile_boot_option);
ep_wakeirq_error: boot_option_error:
debugfs_remove(dfile_wr_value); debugfs_remove(dfile_wr_value);
wr_value_error: wr_value_error:
debugfs_remove(dfile_wr_mask); debugfs_remove(dfile_wr_mask);
@ -3082,7 +3087,7 @@ static void msm_pcie_debugfs_exit(void)
debugfs_remove(dfile_wr_offset); debugfs_remove(dfile_wr_offset);
debugfs_remove(dfile_wr_mask); debugfs_remove(dfile_wr_mask);
debugfs_remove(dfile_wr_value); debugfs_remove(dfile_wr_value);
debugfs_remove(dfile_ep_wakeirq); debugfs_remove(dfile_boot_option);
debugfs_remove(dfile_aer_enable); debugfs_remove(dfile_aer_enable);
debugfs_remove(dfile_corr_counter_limit); debugfs_remove(dfile_corr_counter_limit);
} }
@ -5411,14 +5416,10 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
PCIE_DBG2(dev, "PCIe WAKE is asserted by Endpoint of RC%d\n", PCIE_DBG2(dev, "PCIe WAKE is asserted by Endpoint of RC%d\n",
dev->rc_idx); dev->rc_idx);
if (!dev->enumerated) { if (!dev->enumerated && !(dev->boot_option &
PCIE_DBG(dev, "Start enumeating RC%d\n", dev->rc_idx); MSM_PCIE_NO_WAKE_ENUMERATION)) {
if (dev->ep_wakeirq) PCIE_DBG(dev, "Start enumerating RC%d\n", dev->rc_idx);
schedule_work(&dev->handle_wake_work); 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);
} else { } else {
PCIE_DBG2(dev, "Wake up RC%d\n", dev->rc_idx); PCIE_DBG2(dev, "Wake up RC%d\n", dev->rc_idx);
__pm_stay_awake(&dev->ws); __pm_stay_awake(&dev->ws);
@ -6200,12 +6201,12 @@ static int msm_pcie_probe(struct platform_device *pdev)
msm_pcie_dev[rc_idx].rc_idx, msm_pcie_dev[rc_idx].rc_idx,
msm_pcie_dev[rc_idx].smmu_sid_base); msm_pcie_dev[rc_idx].smmu_sid_base);
msm_pcie_dev[rc_idx].ep_wakeirq = msm_pcie_dev[rc_idx].boot_option = 0;
of_property_read_bool((&pdev->dev)->of_node, ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,boot-option",
"qcom,ep-wakeirq"); &msm_pcie_dev[rc_idx].boot_option);
PCIE_DBG(&msm_pcie_dev[rc_idx], PCIE_DBG(&msm_pcie_dev[rc_idx],
"PCIe: EP of RC%d does %s assert wake when it is up.\n", "PCIe: RC%d boot option is 0x%x.\n",
rc_idx, msm_pcie_dev[rc_idx].ep_wakeirq ? "" : "not"); rc_idx, msm_pcie_dev[rc_idx].boot_option);
msm_pcie_dev[rc_idx].phy_ver = 1; msm_pcie_dev[rc_idx].phy_ver = 1;
ret = of_property_read_u32((&pdev->dev)->of_node, ret = of_property_read_u32((&pdev->dev)->of_node,
@ -6484,9 +6485,10 @@ static int msm_pcie_probe(struct platform_device *pdev)
msm_pcie_dev[rc_idx].drv_ready = true; 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_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); rc_idx);
mutex_unlock(&pcie_drv.drv_lock); mutex_unlock(&pcie_drv.drv_lock);
return 0; return 0;