msm: pcie: expand PCIe boot option
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>
This commit is contained in:
parent
928cd38621
commit
8f301e1bd1
6 changed files with 60 additions and 54 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -960,14 +960,14 @@
|
|||
};
|
||||
|
||||
&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 {
|
||||
|
|
|
@ -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
|
||||
|
@ -1371,7 +1371,7 @@
|
|||
|
||||
iommus = <&anoc0_smmu>;
|
||||
|
||||
qcom,ep-wakeirq;
|
||||
qcom,boot-option = <0x1>;
|
||||
|
||||
linux,pci-domain = <0>;
|
||||
|
||||
|
@ -1524,7 +1524,7 @@
|
|||
|
||||
iommus = <&anoc0_smmu>;
|
||||
|
||||
qcom,ep-wakeirq;
|
||||
qcom,boot-option = <0x1>;
|
||||
|
||||
qcom,ep-latency = <10>;
|
||||
|
||||
|
@ -1677,7 +1677,7 @@
|
|||
|
||||
iommus = <&anoc0_smmu>;
|
||||
|
||||
qcom,ep-wakeirq;
|
||||
qcom,boot-option = <0x1>;
|
||||
|
||||
qcom,ep-latency = <10>;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -1590,7 +1590,7 @@
|
|||
|
||||
qcom,ep-latency = <10>;
|
||||
|
||||
qcom,ep-wakeirq;
|
||||
qcom,boot-option = <0x1>;
|
||||
|
||||
linux,pci-domain = <0>;
|
||||
|
||||
|
|
|
@ -2676,7 +2676,7 @@
|
|||
|
||||
qcom,ep-latency = <10>;
|
||||
|
||||
qcom,ep-wakeirq;
|
||||
qcom,boot-option = <0x1>;
|
||||
|
||||
linux,pci-domain = <0>;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue