diff --git a/drivers/pci/controller/pci-msm.c b/drivers/pci/controller/pci-msm.c index ce014787acbe..b238ec4ed87c 100644 --- a/drivers/pci/controller/pci-msm.c +++ b/drivers/pci/controller/pci-msm.c @@ -503,7 +503,6 @@ enum msm_pcie_debugfs_option { MSM_PCIE_DISABLE_LINK, MSM_PCIE_ENABLE_LINK, MSM_PCIE_DISABLE_ENABLE_LINK, - MSM_PCIE_DUMP_SHADOW_REGISTER, MSM_PCIE_DISABLE_L0S, MSM_PCIE_ENABLE_L0S, MSM_PCIE_DISABLE_L1, @@ -532,7 +531,6 @@ static const char * const "DISABLE LINK", "ENABLE LINK", "DISABLE AND ENABLE LINK", - "DUMP PCIE SHADOW REGISTER", "DISABLE L0S", "ENABLE L0S", "DISABLE L1", @@ -788,6 +786,8 @@ struct msm_pcie_dev_t { enum msm_pcie_link_status link_status; bool user_suspend; bool disable_pc; + + struct pci_saved_state *default_state; struct pci_saved_state *saved_state; struct wakeup_source *ws; @@ -863,9 +863,6 @@ struct msm_pcie_dev_t { struct msm_pcie_tcsr_info_t *tcsr_config; u32 sid_info_len; struct msm_pcie_sid_info_t *sid_info; - u32 ep_shadow[MAX_DEVICE_NUM][PCIE_CONF_SPACE_DW]; - u32 rc_shadow[PCIE_CONF_SPACE_DW]; - bool shadow_en; bool bridge_found; struct list_head event_reg_list; spinlock_t evt_reg_list_lock; @@ -1524,54 +1521,6 @@ static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev, return true; } -static void msm_pcie_cfg_recover(struct msm_pcie_dev_t *dev, bool rc) -{ - int i, j; - u32 val = 0; - u32 *shadow; - void __iomem *cfg = dev->conf; - - for (i = 0; i < MAX_DEVICE_NUM; i++) { - if (!rc && !dev->pcidev_table[i].bdf) - break; - if (rc) { - cfg = dev->dm_core; - shadow = dev->rc_shadow; - } else { - if (!msm_pcie_confirm_linkup(dev, false, true, - dev->pcidev_table[i].dev)) - continue; - - shadow = dev->ep_shadow[i]; - PCIE_DBG(dev, - "PCIe Device: %02x:%02x.%01x\n", - dev->pcidev_table[i].bdf >> 24, - dev->pcidev_table[i].bdf >> 19 & 0x1f, - dev->pcidev_table[i].bdf >> 16 & 0x07); - } - for (j = PCIE_CONF_SPACE_DW - 1; j >= 0; j--) { - val = shadow[j]; - if (val != PCIE_CLEAR) { - PCIE_DBG3(dev, - "PCIe: before recovery:cfg 0x%x:0x%x\n", - j * 4, readl_relaxed(cfg + j * 4)); - PCIE_DBG3(dev, - "PCIe: shadow_dw[%d]:cfg 0x%x:0x%x\n", - j, j * 4, val); - msm_pcie_write_reg(cfg, j * 4, val); - PCIE_DBG3(dev, - "PCIe: after recovery:cfg 0x%x:0x%x\n\n", - j * 4, readl_relaxed(cfg + j * 4)); - } - } - if (rc) - break; - - pci_save_state(dev->pcidev_table[i].dev); - cfg += SZ_4K; - } -} - static void msm_pcie_write_mask(void __iomem *addr, uint32_t clear_mask, uint32_t set_mask) { @@ -1701,8 +1650,6 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev) dev->linkdown_panic); PCIE_DBG_FS(dev, "the link is %s suspending\n", dev->suspending ? "" : "not"); - PCIE_DBG_FS(dev, "shadow is %s enabled\n", - dev->shadow_en ? "" : "not"); PCIE_DBG_FS(dev, "the power of RC is %s on\n", dev->power_on ? "" : "not"); PCIE_DBG_FS(dev, "smmu_sid_base: 0x%x\n", @@ -1771,37 +1718,6 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev) dev->l23_rdy_poll_timeout); } -static void msm_pcie_shadow_dump(struct msm_pcie_dev_t *dev, bool rc) -{ - int i, j; - u32 val = 0; - u32 *shadow; - - for (i = 0; i < MAX_DEVICE_NUM; i++) { - if (!rc && !dev->pcidev_table[i].bdf) - break; - if (rc) { - shadow = dev->rc_shadow; - } else { - shadow = dev->ep_shadow[i]; - PCIE_DBG_FS(dev, "PCIe Device: %02x:%02x.%01x\n", - dev->pcidev_table[i].bdf >> 24, - dev->pcidev_table[i].bdf >> 19 & 0x1f, - dev->pcidev_table[i].bdf >> 16 & 0x07); - } - for (j = 0; j < PCIE_CONF_SPACE_DW; j++) { - val = shadow[j]; - if (val != PCIE_CLEAR) { - PCIE_DBG_FS(dev, - "PCIe: shadow_dw[%d]:cfg 0x%x:0x%x\n", - j, j * 4, val); - } - } - if (rc) - break; - } -} - static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev, u32 testcase) { @@ -1818,9 +1734,8 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev, case MSM_PCIE_DISABLE_LINK: PCIE_DBG_FS(dev, "\n\nPCIe: RC%d: disable link\n\n", dev->rc_idx); - ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, 0, - dev->dev, NULL, - MSM_PCIE_CONFIG_NO_CFG_RESTORE); + ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, 0, dev->dev, NULL, + 0); if (ret) PCIE_DBG_FS(dev, "PCIe:%s:failed to disable link\n", __func__); @@ -1832,50 +1747,28 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev, PCIE_DBG_FS(dev, "\n\nPCIe: RC%d: enable link and recover config space\n\n", dev->rc_idx); - ret = msm_pcie_pm_control(MSM_PCIE_RESUME, 0, - dev->dev, NULL, - MSM_PCIE_CONFIG_NO_CFG_RESTORE); + ret = msm_pcie_pm_control(MSM_PCIE_RESUME, 0, dev->dev, NULL, + 0); if (ret) PCIE_DBG_FS(dev, "PCIe:%s:failed to enable link\n", __func__); - else { - PCIE_DBG_FS(dev, "PCIe:%s:enabled link\n", __func__); - msm_pcie_recover_config(dev->dev); - } break; case MSM_PCIE_DISABLE_ENABLE_LINK: PCIE_DBG_FS(dev, "\n\nPCIe: RC%d: disable and enable link then recover config space\n\n", dev->rc_idx); - ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, 0, - dev->dev, NULL, - MSM_PCIE_CONFIG_NO_CFG_RESTORE); + ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, 0, dev->dev, NULL, + 0); if (ret) PCIE_DBG_FS(dev, "PCIe:%s:failed to disable link\n", __func__); else PCIE_DBG_FS(dev, "PCIe:%s:disabled link\n", __func__); - ret = msm_pcie_pm_control(MSM_PCIE_RESUME, 0, - dev->dev, NULL, - MSM_PCIE_CONFIG_NO_CFG_RESTORE); + ret = msm_pcie_pm_control(MSM_PCIE_RESUME, 0, dev->dev, NULL, + 0); if (ret) PCIE_DBG_FS(dev, "PCIe:%s:failed to enable link\n", __func__); - else { - PCIE_DBG_FS(dev, "PCIe:%s:enabled link\n", __func__); - msm_pcie_recover_config(dev->dev); - } - break; - case MSM_PCIE_DUMP_SHADOW_REGISTER: - PCIE_DBG_FS(dev, - "\n\nPCIe: RC%d: dumping RC shadow registers\n", - dev->rc_idx); - msm_pcie_shadow_dump(dev, true); - - PCIE_DBG_FS(dev, - "\n\nPCIe: RC%d: dumping EP shadow registers\n", - dev->rc_idx); - msm_pcie_shadow_dump(dev, false); break; case MSM_PCIE_DISABLE_L0S: PCIE_DBG_FS(dev, "\n\nPCIe: RC%d: disable L0s\n\n", @@ -2965,29 +2858,6 @@ static void msm_pcie_cfg_bdf(struct msm_pcie_dev_t *dev, u8 bus, u8 devfn) dev->current_bdf = bdf; } -static void msm_pcie_save_shadow(struct msm_pcie_dev_t *dev, - u32 word_offset, u32 wr_val, - u32 bdf, bool rc) -{ - int i; - - if (rc) { - dev->rc_shadow[word_offset / 4] = wr_val; - } else { - for (i = 0; i < MAX_DEVICE_NUM; i++) { - if (!dev->pcidev_table[i].bdf) { - dev->pcidev_table[i].bdf = bdf; - if ((!dev->bridge_found) && (i > 0)) - dev->bridge_found = true; - } - if (dev->pcidev_table[i].bdf == bdf) { - dev->ep_shadow[i][word_offset / 4] = wr_val; - break; - } - } - } -} - static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper, int where, int size, u32 *val) { @@ -3089,18 +2959,6 @@ static int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper, msm_pcie_write_reg(config_base, word_offset, wr_val); - if (dev->shadow_en) { - if (rd_val == PCIE_LINK_DOWN && - (readl_relaxed(config_base) == PCIE_LINK_DOWN)) - PCIE_ERR(dev, - "Read of RC%d %d:0x%02x + 0x%04x[%d] is all FFs\n", - rc_idx, bus->number, devfn, - where, size); - else - msm_pcie_save_shadow(dev, word_offset, wr_val, - bdf, rc); - } - PCIE_DBG3(dev, "RC%d %d:0x%02x + 0x%04x[%d] <- 0x%08x; rd 0x%08x val 0x%08x\n", rc_idx, bus->number, devfn, where, size, @@ -3815,11 +3673,6 @@ static void msm_pcie_config_controller(struct msm_pcie_dev_t *dev) PCIE20_ACK_N_FTS, dev->n_fts << 8); - if (dev->shadow_en) - dev->rc_shadow[PCIE20_ACK_F_ASPM_CTRL_REG / 4] = - readl_relaxed(dev->dm_core + - PCIE20_ACK_F_ASPM_CTRL_REG); - PCIE_DBG2(dev, "Updated PCIE20_ACK_F_ASPM_CTRL_REG:0x%x\n", readl_relaxed(dev->dm_core + PCIE20_ACK_F_ASPM_CTRL_REG)); @@ -5094,13 +4947,6 @@ int msm_pcie_enumerate(u32 rc_idx) msm_pcie_write_reg_field(dev->dm_core, PCIE20_DEVICE_CONTROL2_STATUS2, 0xf, dev->cpl_timeout); - if (dev->shadow_en) { - u32 val = readl_relaxed(dev->dm_core + PCIE20_COMMAND_STATUS); - - PCIE_DBG(dev, "PCIE20_COMMAND_STATUS:0x%x\n", val); - dev->rc_shadow[PCIE20_COMMAND_STATUS / 4] = val; - } - do { pcidev = pci_get_device(vendor_id, device_id, pcidev); if (pcidev && (dev == (struct msm_pcie_dev_t *) @@ -5119,6 +4965,8 @@ int msm_pcie_enumerate(u32 rc_idx) pci_walk_bus(dev->dev->bus, msm_pcie_config_device_table, dev); + pci_save_state(pcidev); + dev->default_state = pci_store_saved_state(pcidev); out: mutex_unlock(&dev->enumerate_lock); @@ -5387,7 +5235,6 @@ static void msm_pcie_handle_linkdown(struct msm_pcie_dev_t *dev) return; dev->link_status = MSM_PCIE_LINK_DOWN; - dev->shadow_en = false; if (!dev->suspending) { /* PCIe registers dump on link down */ @@ -6061,7 +5908,7 @@ static int msm_pcie_probe(struct platform_device *pdev) { int ret = 0; int rc_idx = -1; - int i, j, size; + int i, size; struct msm_pcie_dev_t *pcie_dev; struct device_node *of_node; @@ -6274,7 +6121,6 @@ static int msm_pcie_probe(struct platform_device *pdev) PCIE_DBG(pcie_dev, "RC%d: clkreq gpio no:%u\n", pcie_dev->rc_idx, pcie_dev->clkreq_gpio); - pcie_dev->shadow_en = true; pcie_dev->aer_enable = true; memcpy(pcie_dev->vreg, msm_pcie_vreg_info, sizeof(msm_pcie_vreg_info)); @@ -6290,11 +6136,6 @@ static int msm_pcie_probe(struct platform_device *pdev) memcpy(pcie_dev->pipe_reset, msm_pcie_pipe_reset_info[rc_idx], sizeof(msm_pcie_pipe_reset_info[rc_idx])); - for (i = 0; i < PCIE_CONF_SPACE_DW; i++) - pcie_dev->rc_shadow[i] = PCIE_CLEAR; - for (i = 0; i < MAX_DEVICE_NUM; i++) - for (j = 0; j < PCIE_CONF_SPACE_DW; j++) - pcie_dev->ep_shadow[i][j] = PCIE_CLEAR; for (i = 0; i < MAX_DEVICE_NUM; i++) { pcie_dev->pcidev_table[i].bdf = 0; pcie_dev->pcidev_table[i].dev = NULL; @@ -6438,6 +6279,14 @@ static int msm_pcie_remove(struct platform_device *pdev) dev_info(&pdev->dev, "PCIe: RC%d: being removed\n", rc_idx); } + if (msm_pcie_dev[rc_idx].saved_state) + pci_load_and_free_saved_state(msm_pcie_dev[rc_idx].dev, + &msm_pcie_dev[rc_idx].saved_state); + + if (msm_pcie_dev[rc_idx].default_state) + pci_load_and_free_saved_state(msm_pcie_dev[rc_idx].dev, + &msm_pcie_dev[rc_idx].default_state); + msm_pcie_irq_deinit(&msm_pcie_dev[rc_idx]); msm_pcie_vreg_deinit(&msm_pcie_dev[rc_idx]); msm_pcie_clk_deinit(&msm_pcie_dev[rc_idx]); @@ -7331,16 +7180,26 @@ static int msm_pcie_pm_suspend(struct pci_dev *dev, return ret; } - if (dev && !(options & MSM_PCIE_CONFIG_NO_CFG_RESTORE) - && msm_pcie_confirm_linkup(pcie_dev, true, true, dev)) { - ret = pci_save_state(dev); - pcie_dev->saved_state = pci_store_saved_state(dev); - } - if (ret) { - PCIE_ERR(pcie_dev, "PCIe: fail to save state of RC%d:%d.\n", - pcie_dev->rc_idx, ret); - pcie_dev->suspending = false; - return ret; + if (dev) { + if (msm_pcie_confirm_linkup(pcie_dev, true, true, dev)) { + ret = pci_save_state(dev); + if (ret) { + PCIE_ERR(pcie_dev, + "PCIe: RC%d: fail to save state of RC%d:%d.\n", + pcie_dev->rc_idx, ret); + pcie_dev->suspending = false; + return ret; + } + + pcie_dev->saved_state = pci_store_saved_state(dev); + } else { + pci_load_and_free_saved_state(dev, + &pcie_dev->saved_state); + pcie_dev->saved_state = pcie_dev->default_state; + PCIE_DBG(pcie_dev, + "PCIe: RC%d: saved default config space\n", + pcie_dev->rc_idx); + } } spin_lock_irqsave(&pcie_dev->cfg_lock, @@ -7451,37 +7310,11 @@ static int msm_pcie_pm_resume(struct pci_dev *dev, "dev->bus->number = %d dev->bus->primary = %d\n", dev->bus->number, dev->bus->primary); - if (!(options & MSM_PCIE_CONFIG_NO_CFG_RESTORE)) { - if (pcie_dev->saved_state) { - PCIE_DBG(pcie_dev, - "RC%d: entry of PCI framework restore state\n", - pcie_dev->rc_idx); - - pci_load_and_free_saved_state(dev, - &pcie_dev->saved_state); - pci_restore_state(dev); - - PCIE_DBG(pcie_dev, - "RC%d: exit of PCI framework restore state\n", - pcie_dev->rc_idx); - } else { - PCIE_DBG(pcie_dev, - "RC%d: restore rc config space using shadow recovery\n", - pcie_dev->rc_idx); - msm_pcie_cfg_recover(pcie_dev, true); - } - } - - if (pcie_dev->bridge_found) { - PCIE_DBG(pcie_dev, - "RC%d: entry of PCIe recover config\n", - pcie_dev->rc_idx); - - msm_pcie_recover_config(dev); - - PCIE_DBG(pcie_dev, - "RC%d: exit of PCIe recover config\n", - pcie_dev->rc_idx); + if (dev) { + PCIE_DBG(pcie_dev, "RC%d: restore config space\n", + pcie_dev->rc_idx); + pci_load_and_free_saved_state(dev, &pcie_dev->saved_state); + pci_restore_state(dev); } msm_msi_config_access(dev_get_msi_domain(&pcie_dev->dev->dev), true); @@ -8205,76 +8038,5 @@ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg) } EXPORT_SYMBOL(msm_pcie_deregister_event); -int msm_pcie_recover_config(struct pci_dev *dev) -{ - int ret = 0; - struct msm_pcie_dev_t *pcie_dev; - - if (dev) { - pcie_dev = PCIE_BUS_PRIV_DATA(dev->bus); - PCIE_DBG(pcie_dev, - "Recovery for the link of RC%d\n", pcie_dev->rc_idx); - } else { - pr_err("PCIe: the input pci dev is NULL.\n"); - return -ENODEV; - } - - if (msm_pcie_confirm_linkup(pcie_dev, true, true, dev)) { - PCIE_DBG(pcie_dev, - "Recover config space of RC%d and its EP\n", - pcie_dev->rc_idx); - pcie_dev->shadow_en = false; - PCIE_DBG(pcie_dev, "Recover RC%d\n", pcie_dev->rc_idx); - msm_pcie_cfg_recover(pcie_dev, true); - PCIE_DBG(pcie_dev, "Recover EP of RC%d\n", pcie_dev->rc_idx); - msm_pcie_cfg_recover(pcie_dev, false); - PCIE_DBG(pcie_dev, - "Refreshing the saved config space in PCI framework for RC%d and its EP\n", - pcie_dev->rc_idx); - pci_save_state(pcie_dev->dev); - pci_save_state(dev); - pcie_dev->shadow_en = true; - PCIE_DBG(pcie_dev, "Turn on shadow for RC%d\n", - pcie_dev->rc_idx); - } else { - PCIE_ERR(pcie_dev, - "PCIe: the link of RC%d is not up yet; can't recover config space.\n", - pcie_dev->rc_idx); - ret = -ENODEV; - } - - return ret; -} -EXPORT_SYMBOL(msm_pcie_recover_config); - -int msm_pcie_shadow_control(struct pci_dev *dev, bool enable) -{ - int ret = 0; - struct msm_pcie_dev_t *pcie_dev; - - if (dev) { - pcie_dev = PCIE_BUS_PRIV_DATA(dev->bus); - PCIE_DBG(pcie_dev, - "User requests to %s shadow\n", - enable ? "enable" : "disable"); - } else { - pr_err("PCIe: the input pci dev is NULL.\n"); - return -ENODEV; - } - - PCIE_DBG(pcie_dev, - "The shadowing of RC%d is %s enabled currently.\n", - pcie_dev->rc_idx, pcie_dev->shadow_en ? "" : "not"); - - pcie_dev->shadow_en = enable; - - PCIE_DBG(pcie_dev, - "Shadowing of RC%d is turned %s upon user's request.\n", - pcie_dev->rc_idx, enable ? "on" : "off"); - - return ret; -} -EXPORT_SYMBOL(msm_pcie_shadow_control); - MODULE_DESCRIPTION("Qualcomm Technologies, Inc. PCIe RC driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/msm_pcie.h b/include/linux/msm_pcie.h index 6910eb4c76cf..44a076807bb5 100644 --- a/include/linux/msm_pcie.h +++ b/include/linux/msm_pcie.h @@ -9,11 +9,10 @@ enum msm_pcie_config { MSM_PCIE_CONFIG_INVALID = 0, - MSM_PCIE_CONFIG_NO_CFG_RESTORE = 0x1, - MSM_PCIE_CONFIG_LINKDOWN = 0x2, - MSM_PCIE_CONFIG_NO_RECOVERY = 0x4, - MSM_PCIE_CONFIG_NO_L1SS_TO = 0x8, - MSM_PCIE_CONFIG_NO_DRV_PC = 0x10, + MSM_PCIE_CONFIG_LINKDOWN = BIT(0), + MSM_PCIE_CONFIG_NO_RECOVERY = BIT(1), + MSM_PCIE_CONFIG_NO_L1SS_TO = BIT(2), + MSM_PCIE_CONFIG_NO_DRV_PC = BIT(3), }; enum msm_pcie_pm_opt { @@ -174,16 +173,6 @@ int msm_pcie_register_event(struct msm_pcie_register_event *reg); */ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg); -/** - * msm_pcie_recover_config - recover config space. - * @dev: pci device structure - * - * This function recovers the config space of both RC and Endpoint. - * - * Return: 0 on success, negative value on error - */ -int msm_pcie_recover_config(struct pci_dev *dev); - /** * msm_pcie_enumerate - enumerate Endpoints. * @rc_idx: RC that Endpoints connect to. @@ -194,28 +183,6 @@ int msm_pcie_recover_config(struct pci_dev *dev); */ int msm_pcie_enumerate(u32 rc_idx); -/** - * msm_pcie_recover_config - recover config space. - * @dev: pci device structure - * - * This function recovers the config space of both RC and Endpoint. - * - * Return: 0 on success, negative value on error - */ -int msm_pcie_recover_config(struct pci_dev *dev); - -/** - * msm_pcie_shadow_control - control the shadowing of PCIe config space. - * @dev: pci device structure - * @enable: shadowing should be enabled or disabled - * - * This function gives PCIe endpoint device drivers the control to enable - * or disable the shadowing of PCIe config space. - * - * Return: 0 on success, negative value on error - */ -int msm_pcie_shadow_control(struct pci_dev *dev, bool enable); - /* * msm_pcie_debug_info - run a PCIe specific debug testcase. * @dev: pci device structure @@ -286,21 +253,11 @@ static inline int msm_pcie_deregister_event(struct msm_pcie_register_event *reg) return -ENODEV; } -static inline int msm_pcie_recover_config(struct pci_dev *dev) -{ - return -ENODEV; -} - static inline int msm_pcie_enumerate(u32 rc_idx) { return -ENODEV; } -static inline int msm_pcie_shadow_control(struct pci_dev *dev, bool enable) -{ - return -ENODEV; -} - static inline int msm_pcie_debug_info(struct pci_dev *dev, u32 option, u32 base, u32 offset, u32 mask, u32 value) {