Loading Documentation/devicetree/bindings/pci/msm_pcie.txt +7 −3 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading drivers/pci/host/pci-msm.c +43 −41 Original line number Diff line number Diff line Loading @@ -481,6 +481,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; Loading Loading @@ -629,7 +634,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; Loading Loading @@ -1950,8 +1955,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", Loading Loading @@ -2565,7 +2570,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; Loading Loading @@ -2834,13 +2839,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)); Loading @@ -2849,33 +2854,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, Loading Loading @@ -3028,12 +3033,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, Loading @@ -3056,8 +3061,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); Loading @@ -3084,7 +3089,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); } Loading Loading @@ -5423,14 +5428,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) 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_DBG(dev, "wake irq is received but ep_wakeirq is not supported for RC%d.\n", dev->rc_idx); } else { PCIE_DBG2(dev, "Wake up RC%d\n", dev->rc_idx); __pm_stay_awake(&dev->ws); Loading Loading @@ -6213,12 +6214,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, Loading Loading @@ -6497,9 +6498,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 Loading
Documentation/devicetree/bindings/pci/msm_pcie.txt +7 −3 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading
drivers/pci/host/pci-msm.c +43 −41 Original line number Diff line number Diff line Loading @@ -481,6 +481,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; Loading Loading @@ -629,7 +634,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; Loading Loading @@ -1950,8 +1955,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", Loading Loading @@ -2565,7 +2570,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; Loading Loading @@ -2834,13 +2839,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)); Loading @@ -2849,33 +2854,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, Loading Loading @@ -3028,12 +3033,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, Loading @@ -3056,8 +3061,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); Loading @@ -3084,7 +3089,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); } Loading Loading @@ -5423,14 +5428,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) 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_DBG(dev, "wake irq is received but ep_wakeirq is not supported for RC%d.\n", dev->rc_idx); } else { PCIE_DBG2(dev, "Wake up RC%d\n", dev->rc_idx); __pm_stay_awake(&dev->ws); Loading Loading @@ -6213,12 +6214,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, Loading Loading @@ -6497,9 +6498,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