Loading drivers/pci/controller/pci-msm.c +178 −44 Original line number Diff line number Diff line Loading @@ -551,6 +551,12 @@ struct msm_pcie_irq_info_t { uint32_t num; }; /* bandwidth info structure */ struct msm_pcie_bw_scale_info_t { u32 cx_vreg_min; u32 rate_change_freq; }; /* phy info structure */ struct msm_pcie_phy_info_t { u32 offset; Loading Loading @@ -662,12 +668,15 @@ struct msm_pcie_dev_t { struct msm_pcie_vreg_info_t *cx_vreg; struct msm_pcie_clk_info_t *rate_change_clk; struct msm_pcie_bw_scale_info_t *bw_scale; u32 bw_gen_max; bool cfg_access; spinlock_t cfg_lock; unsigned long irqsave_flags; struct mutex enumerate_lock; struct mutex setup_lock; struct mutex clk_lock; struct irq_domain *irq_domain; DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_NR_IRQS); Loading Loading @@ -836,6 +845,7 @@ static struct pcie_drv_sta { struct msm_pcie_dev_t *msm_pcie_dev; struct rpmsg_device *rpdev; struct work_struct drv_connect; /* connect worker */ u32 rate_change_vote; /* each bit corresponds to RC vote for 100MHz */ struct mutex drv_lock; } pcie_drv; Loading Loading @@ -3171,6 +3181,12 @@ static int msm_pcie_clk_init(struct msm_pcie_dev_t *dev) msm_pcie_config_clock_mem(dev, info); if (info->freq) { if (!strcmp(info->name, "pcie_phy_refgen_clk")) { mutex_lock(&dev->clk_lock); pcie_drv.rate_change_vote |= BIT(dev->rc_idx); mutex_unlock(&dev->clk_lock); } rc = clk_set_rate(info->hdl, info->freq); if (rc) { PCIE_ERR(dev, Loading Loading @@ -3251,6 +3267,17 @@ static void msm_pcie_clk_deinit(struct msm_pcie_dev_t *dev) if (dev->clk[i].hdl) clk_disable_unprepare(dev->clk[i].hdl); if (dev->rate_change_clk) { mutex_lock(&dev->clk_lock); pcie_drv.rate_change_vote &= ~BIT(dev->rc_idx); if (!pcie_drv.rate_change_vote) clk_set_rate(dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); mutex_unlock(&dev->clk_lock); } if (dev->bus_client) { PCIE_DBG(dev, "PCIe: removing bus vote for RC%d\n", dev->rc_idx); Loading Loading @@ -3722,6 +3749,29 @@ static int msm_pcie_get_reset(struct msm_pcie_dev_t *pcie_dev) return 0; } static int msm_pcie_get_bw_scale(struct msm_pcie_dev_t *pcie_dev) { int size = 0; struct platform_device *pdev = pcie_dev->pdev; of_get_property(pdev->dev.of_node, "qcom,bw-scale", &size); if (size) { pcie_dev->bw_scale = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!pcie_dev->bw_scale) return -ENOMEM; of_property_read_u32_array(pdev->dev.of_node, "qcom,bw-scale", (u32 *)pcie_dev->bw_scale, size / sizeof(u32)); pcie_dev->bw_gen_max = size / sizeof(u32); } else { PCIE_DBG(pcie_dev, "RC%d: bandwidth scaling is not supported\n", pcie_dev->rc_idx); } return 0; } static int msm_pcie_get_phy(struct msm_pcie_dev_t *pcie_dev) { int ret, size = 0; Loading Loading @@ -3934,6 +3984,10 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, if (ret) return ret; ret = msm_pcie_get_bw_scale(dev); if (ret) return ret; ret = msm_pcie_get_phy(dev); if (ret) return ret; Loading Loading @@ -3966,6 +4020,50 @@ static void msm_pcie_release_resources(struct msm_pcie_dev_t *dev) dev->rumi = NULL; } static void msm_pcie_scale_link_bandwidth(struct msm_pcie_dev_t *pcie_dev, u16 target_link_speed) { struct msm_pcie_bw_scale_info_t *bw_scale; u32 index = target_link_speed - PCI_EXP_LNKCTL2_TLS_2_5GT; if (!pcie_dev->bw_scale) return; if (index >= pcie_dev->bw_gen_max) { PCIE_ERR(pcie_dev, "PCIe: RC%d: invalid target link speed: %d\n", pcie_dev->rc_idx, target_link_speed); return; } bw_scale = &pcie_dev->bw_scale[index]; if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, bw_scale->cx_vreg_min, pcie_dev->cx_vreg->max_v); if (pcie_dev->rate_change_clk) { mutex_lock(&pcie_dev->clk_lock); /* it is okay to always scale up */ clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_100MHZ); if (bw_scale->rate_change_freq == RATE_CHANGE_100MHZ) pcie_drv.rate_change_vote |= BIT(pcie_dev->rc_idx); else pcie_drv.rate_change_vote &= ~BIT(pcie_dev->rc_idx); /* scale down to 19.2MHz if no one needs 100MHz */ if (!pcie_drv.rate_change_vote) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); mutex_unlock(&pcie_dev->clk_lock); } } static int msm_pcie_link_train(struct msm_pcie_dev_t *dev) { int link_check_count = 0; Loading Loading @@ -4033,6 +4131,39 @@ static int msm_pcie_link_train(struct msm_pcie_dev_t *dev) return MSM_PCIE_ERROR; } if (dev->bw_scale) { u32 index; u32 current_link_speed; struct msm_pcie_bw_scale_info_t *bw_scale; /* * check if the link up GEN speed is less than the max/default * supported. If it is, scale down CX corner and rate change * clock accordingly. */ current_link_speed = readl_relaxed(dev->dm_core + PCIE20_CAP_LINKCTRLSTATUS); current_link_speed = ((current_link_speed >> 16) & PCI_EXP_LNKSTA_CLS); index = current_link_speed - PCI_EXP_LNKCTL2_TLS_2_5GT; if (index >= dev->bw_gen_max) { PCIE_ERR(dev, "PCIe: RC%d: unsupported gen speed: %d\n", dev->rc_idx, current_link_speed); return 0; } bw_scale = &dev->bw_scale[index]; if (bw_scale->cx_vreg_min < dev->cx_vreg->min_v) { msm_pcie_write_reg_field(dev->dm_core, PCIE20_CAP + PCI_EXP_LNKCTL2, PCI_EXP_LNKCAP_SLS, current_link_speed); msm_pcie_scale_link_bandwidth(dev, current_link_speed); } } return 0; } Loading Loading @@ -6140,9 +6271,6 @@ static int msm_pcie_link_retrain(struct msm_pcie_dev_t *pcie_dev, u32 cnt_max = 1000; /* 100ms timeout */ u32 link_status_lbms_mask = PCI_EXP_LNKSTA_LBMS << PCI_EXP_LNKCTL; /* force link to L0 */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(5)); cnt = 0; /* confirm link is in L0 */ while (((readl_relaxed(pcie_dev->parf + PCIE20_PARF_LTSSM) & Loading Loading @@ -6175,34 +6303,34 @@ static int msm_pcie_link_retrain(struct msm_pcie_dev_t *pcie_dev, usleep_range(100, 105); } /* re-enable link LPM */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, BIT(5), 0); return 0; } static void msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, u16 *target_link_width) static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, u16 target_link_width) { switch (*target_link_width) { u16 link_width; switch (target_link_width) { case PCI_EXP_LNKSTA_NLW_X1: *target_link_width = LINK_WIDTH_X1; link_width = LINK_WIDTH_X1; break; case PCI_EXP_LNKSTA_NLW_X2: *target_link_width = LINK_WIDTH_X2; link_width = LINK_WIDTH_X2; break; default: PCIE_ERR(pcie_dev, "PCIe: RC%d: unsupported link width request: %d\n", pcie_dev->rc_idx, *target_link_width); *target_link_width = 0; return; pcie_dev->rc_idx, target_link_width); return -EINVAL; } msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE20_PORT_LINK_CTRL_REG, LINK_WIDTH_MASK << LINK_WIDTH_SHIFT, *target_link_width); link_width); return 0; } int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, Loading @@ -6213,6 +6341,8 @@ int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, u16 link_status; u16 current_link_speed; u16 current_link_width; bool set_link_speed = true; bool set_link_width = true; int ret; if (!pci_dev) Loading @@ -6228,54 +6358,57 @@ int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, target_link_width <<= PCI_EXP_LNKSTA_NLW_SHIFT; if (target_link_speed == current_link_speed) target_link_speed = 0; set_link_speed = false; if (target_link_width == current_link_width) target_link_width = 0; if (target_link_width) msm_pcie_set_link_width(pcie_dev, &target_link_width); set_link_width = false; if (!target_link_speed && !target_link_width) if (!set_link_speed && !set_link_width) return 0; if (target_link_speed) if (set_link_width) { ret = msm_pcie_set_link_width(pcie_dev, target_link_width); if (ret) return ret; } if (set_link_speed) msm_pcie_config_clear_set_dword(root_pci_dev, root_pci_dev->pcie_cap + PCI_EXP_LNKCTL2, PCI_EXP_LNKSTA_CLS, target_link_speed); /* increase CX and rate change clk freq if target speed is Gen3 */ if (target_link_speed == PCI_EXP_LNKCTL2_TLS_8_0GT) { if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, RPMH_REGULATOR_LEVEL_NOM, pcie_dev->cx_vreg->max_v); /* disable link L1. Need to be in L0 for gen switch */ msm_pcie_config_l1(pcie_dev, root_pci_dev, false); msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(5)); if (pcie_dev->rate_change_clk) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_100MHZ); } if (target_link_speed > current_link_speed) msm_pcie_scale_link_bandwidth(pcie_dev, target_link_speed); ret = msm_pcie_link_retrain(pcie_dev, root_pci_dev); if (ret) return ret; goto out; /* decrease CX and rate change clk freq if link is in Gen1 */ pcie_capability_read_word(root_pci_dev, PCI_EXP_LNKSTA, &link_status); if ((link_status & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKCTL2_TLS_2_5GT) { if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, RPMH_REGULATOR_LEVEL_LOW_SVS, pcie_dev->cx_vreg->max_v); if (pcie_dev->rate_change_clk) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); if ((link_status & PCI_EXP_LNKSTA_CLS) != target_link_speed || (link_status & PCI_EXP_LNKSTA_NLW) != target_link_width) { PCIE_ERR(pcie_dev, "PCIe: RC%d: failed to switch bandwidth: target speed: %d width: %d\n", pcie_dev->rc_idx, target_link_speed, target_link_width >> PCI_EXP_LNKSTA_NLW_SHIFT); ret = -EIO; goto out; } return 0; if (target_link_speed < current_link_speed) msm_pcie_scale_link_bandwidth(pcie_dev, target_link_speed); out: /* re-enable link L1 */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, BIT(5), 0); msm_pcie_config_l1(pcie_dev, root_pci_dev, true); return ret; } EXPORT_SYMBOL(msm_pcie_set_link_bandwidth); Loading Loading @@ -6561,6 +6694,7 @@ static int __init pcie_init(void) msm_pcie_dev[i].cfg_access = true; mutex_init(&msm_pcie_dev[i].enumerate_lock); mutex_init(&msm_pcie_dev[i].setup_lock); mutex_init(&msm_pcie_dev[i].clk_lock); mutex_init(&msm_pcie_dev[i].recovery_lock); spin_lock_init(&msm_pcie_dev[i].wakeup_lock); spin_lock_init(&msm_pcie_dev[i].irq_lock); Loading Loading
drivers/pci/controller/pci-msm.c +178 −44 Original line number Diff line number Diff line Loading @@ -551,6 +551,12 @@ struct msm_pcie_irq_info_t { uint32_t num; }; /* bandwidth info structure */ struct msm_pcie_bw_scale_info_t { u32 cx_vreg_min; u32 rate_change_freq; }; /* phy info structure */ struct msm_pcie_phy_info_t { u32 offset; Loading Loading @@ -662,12 +668,15 @@ struct msm_pcie_dev_t { struct msm_pcie_vreg_info_t *cx_vreg; struct msm_pcie_clk_info_t *rate_change_clk; struct msm_pcie_bw_scale_info_t *bw_scale; u32 bw_gen_max; bool cfg_access; spinlock_t cfg_lock; unsigned long irqsave_flags; struct mutex enumerate_lock; struct mutex setup_lock; struct mutex clk_lock; struct irq_domain *irq_domain; DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_NR_IRQS); Loading Loading @@ -836,6 +845,7 @@ static struct pcie_drv_sta { struct msm_pcie_dev_t *msm_pcie_dev; struct rpmsg_device *rpdev; struct work_struct drv_connect; /* connect worker */ u32 rate_change_vote; /* each bit corresponds to RC vote for 100MHz */ struct mutex drv_lock; } pcie_drv; Loading Loading @@ -3171,6 +3181,12 @@ static int msm_pcie_clk_init(struct msm_pcie_dev_t *dev) msm_pcie_config_clock_mem(dev, info); if (info->freq) { if (!strcmp(info->name, "pcie_phy_refgen_clk")) { mutex_lock(&dev->clk_lock); pcie_drv.rate_change_vote |= BIT(dev->rc_idx); mutex_unlock(&dev->clk_lock); } rc = clk_set_rate(info->hdl, info->freq); if (rc) { PCIE_ERR(dev, Loading Loading @@ -3251,6 +3267,17 @@ static void msm_pcie_clk_deinit(struct msm_pcie_dev_t *dev) if (dev->clk[i].hdl) clk_disable_unprepare(dev->clk[i].hdl); if (dev->rate_change_clk) { mutex_lock(&dev->clk_lock); pcie_drv.rate_change_vote &= ~BIT(dev->rc_idx); if (!pcie_drv.rate_change_vote) clk_set_rate(dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); mutex_unlock(&dev->clk_lock); } if (dev->bus_client) { PCIE_DBG(dev, "PCIe: removing bus vote for RC%d\n", dev->rc_idx); Loading Loading @@ -3722,6 +3749,29 @@ static int msm_pcie_get_reset(struct msm_pcie_dev_t *pcie_dev) return 0; } static int msm_pcie_get_bw_scale(struct msm_pcie_dev_t *pcie_dev) { int size = 0; struct platform_device *pdev = pcie_dev->pdev; of_get_property(pdev->dev.of_node, "qcom,bw-scale", &size); if (size) { pcie_dev->bw_scale = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!pcie_dev->bw_scale) return -ENOMEM; of_property_read_u32_array(pdev->dev.of_node, "qcom,bw-scale", (u32 *)pcie_dev->bw_scale, size / sizeof(u32)); pcie_dev->bw_gen_max = size / sizeof(u32); } else { PCIE_DBG(pcie_dev, "RC%d: bandwidth scaling is not supported\n", pcie_dev->rc_idx); } return 0; } static int msm_pcie_get_phy(struct msm_pcie_dev_t *pcie_dev) { int ret, size = 0; Loading Loading @@ -3934,6 +3984,10 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, if (ret) return ret; ret = msm_pcie_get_bw_scale(dev); if (ret) return ret; ret = msm_pcie_get_phy(dev); if (ret) return ret; Loading Loading @@ -3966,6 +4020,50 @@ static void msm_pcie_release_resources(struct msm_pcie_dev_t *dev) dev->rumi = NULL; } static void msm_pcie_scale_link_bandwidth(struct msm_pcie_dev_t *pcie_dev, u16 target_link_speed) { struct msm_pcie_bw_scale_info_t *bw_scale; u32 index = target_link_speed - PCI_EXP_LNKCTL2_TLS_2_5GT; if (!pcie_dev->bw_scale) return; if (index >= pcie_dev->bw_gen_max) { PCIE_ERR(pcie_dev, "PCIe: RC%d: invalid target link speed: %d\n", pcie_dev->rc_idx, target_link_speed); return; } bw_scale = &pcie_dev->bw_scale[index]; if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, bw_scale->cx_vreg_min, pcie_dev->cx_vreg->max_v); if (pcie_dev->rate_change_clk) { mutex_lock(&pcie_dev->clk_lock); /* it is okay to always scale up */ clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_100MHZ); if (bw_scale->rate_change_freq == RATE_CHANGE_100MHZ) pcie_drv.rate_change_vote |= BIT(pcie_dev->rc_idx); else pcie_drv.rate_change_vote &= ~BIT(pcie_dev->rc_idx); /* scale down to 19.2MHz if no one needs 100MHz */ if (!pcie_drv.rate_change_vote) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); mutex_unlock(&pcie_dev->clk_lock); } } static int msm_pcie_link_train(struct msm_pcie_dev_t *dev) { int link_check_count = 0; Loading Loading @@ -4033,6 +4131,39 @@ static int msm_pcie_link_train(struct msm_pcie_dev_t *dev) return MSM_PCIE_ERROR; } if (dev->bw_scale) { u32 index; u32 current_link_speed; struct msm_pcie_bw_scale_info_t *bw_scale; /* * check if the link up GEN speed is less than the max/default * supported. If it is, scale down CX corner and rate change * clock accordingly. */ current_link_speed = readl_relaxed(dev->dm_core + PCIE20_CAP_LINKCTRLSTATUS); current_link_speed = ((current_link_speed >> 16) & PCI_EXP_LNKSTA_CLS); index = current_link_speed - PCI_EXP_LNKCTL2_TLS_2_5GT; if (index >= dev->bw_gen_max) { PCIE_ERR(dev, "PCIe: RC%d: unsupported gen speed: %d\n", dev->rc_idx, current_link_speed); return 0; } bw_scale = &dev->bw_scale[index]; if (bw_scale->cx_vreg_min < dev->cx_vreg->min_v) { msm_pcie_write_reg_field(dev->dm_core, PCIE20_CAP + PCI_EXP_LNKCTL2, PCI_EXP_LNKCAP_SLS, current_link_speed); msm_pcie_scale_link_bandwidth(dev, current_link_speed); } } return 0; } Loading Loading @@ -6140,9 +6271,6 @@ static int msm_pcie_link_retrain(struct msm_pcie_dev_t *pcie_dev, u32 cnt_max = 1000; /* 100ms timeout */ u32 link_status_lbms_mask = PCI_EXP_LNKSTA_LBMS << PCI_EXP_LNKCTL; /* force link to L0 */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(5)); cnt = 0; /* confirm link is in L0 */ while (((readl_relaxed(pcie_dev->parf + PCIE20_PARF_LTSSM) & Loading Loading @@ -6175,34 +6303,34 @@ static int msm_pcie_link_retrain(struct msm_pcie_dev_t *pcie_dev, usleep_range(100, 105); } /* re-enable link LPM */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, BIT(5), 0); return 0; } static void msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, u16 *target_link_width) static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, u16 target_link_width) { switch (*target_link_width) { u16 link_width; switch (target_link_width) { case PCI_EXP_LNKSTA_NLW_X1: *target_link_width = LINK_WIDTH_X1; link_width = LINK_WIDTH_X1; break; case PCI_EXP_LNKSTA_NLW_X2: *target_link_width = LINK_WIDTH_X2; link_width = LINK_WIDTH_X2; break; default: PCIE_ERR(pcie_dev, "PCIe: RC%d: unsupported link width request: %d\n", pcie_dev->rc_idx, *target_link_width); *target_link_width = 0; return; pcie_dev->rc_idx, target_link_width); return -EINVAL; } msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE20_PORT_LINK_CTRL_REG, LINK_WIDTH_MASK << LINK_WIDTH_SHIFT, *target_link_width); link_width); return 0; } int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, Loading @@ -6213,6 +6341,8 @@ int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, u16 link_status; u16 current_link_speed; u16 current_link_width; bool set_link_speed = true; bool set_link_width = true; int ret; if (!pci_dev) Loading @@ -6228,54 +6358,57 @@ int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed, target_link_width <<= PCI_EXP_LNKSTA_NLW_SHIFT; if (target_link_speed == current_link_speed) target_link_speed = 0; set_link_speed = false; if (target_link_width == current_link_width) target_link_width = 0; if (target_link_width) msm_pcie_set_link_width(pcie_dev, &target_link_width); set_link_width = false; if (!target_link_speed && !target_link_width) if (!set_link_speed && !set_link_width) return 0; if (target_link_speed) if (set_link_width) { ret = msm_pcie_set_link_width(pcie_dev, target_link_width); if (ret) return ret; } if (set_link_speed) msm_pcie_config_clear_set_dword(root_pci_dev, root_pci_dev->pcie_cap + PCI_EXP_LNKCTL2, PCI_EXP_LNKSTA_CLS, target_link_speed); /* increase CX and rate change clk freq if target speed is Gen3 */ if (target_link_speed == PCI_EXP_LNKCTL2_TLS_8_0GT) { if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, RPMH_REGULATOR_LEVEL_NOM, pcie_dev->cx_vreg->max_v); /* disable link L1. Need to be in L0 for gen switch */ msm_pcie_config_l1(pcie_dev, root_pci_dev, false); msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(5)); if (pcie_dev->rate_change_clk) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_100MHZ); } if (target_link_speed > current_link_speed) msm_pcie_scale_link_bandwidth(pcie_dev, target_link_speed); ret = msm_pcie_link_retrain(pcie_dev, root_pci_dev); if (ret) return ret; goto out; /* decrease CX and rate change clk freq if link is in Gen1 */ pcie_capability_read_word(root_pci_dev, PCI_EXP_LNKSTA, &link_status); if ((link_status & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKCTL2_TLS_2_5GT) { if (pcie_dev->cx_vreg) regulator_set_voltage(pcie_dev->cx_vreg->hdl, RPMH_REGULATOR_LEVEL_LOW_SVS, pcie_dev->cx_vreg->max_v); if (pcie_dev->rate_change_clk) clk_set_rate(pcie_dev->rate_change_clk->hdl, RATE_CHANGE_19P2MHZ); if ((link_status & PCI_EXP_LNKSTA_CLS) != target_link_speed || (link_status & PCI_EXP_LNKSTA_NLW) != target_link_width) { PCIE_ERR(pcie_dev, "PCIe: RC%d: failed to switch bandwidth: target speed: %d width: %d\n", pcie_dev->rc_idx, target_link_speed, target_link_width >> PCI_EXP_LNKSTA_NLW_SHIFT); ret = -EIO; goto out; } return 0; if (target_link_speed < current_link_speed) msm_pcie_scale_link_bandwidth(pcie_dev, target_link_speed); out: /* re-enable link L1 */ msm_pcie_write_mask(pcie_dev->parf + PCIE20_PARF_PM_CTRL, BIT(5), 0); msm_pcie_config_l1(pcie_dev, root_pci_dev, true); return ret; } EXPORT_SYMBOL(msm_pcie_set_link_bandwidth); Loading Loading @@ -6561,6 +6694,7 @@ static int __init pcie_init(void) msm_pcie_dev[i].cfg_access = true; mutex_init(&msm_pcie_dev[i].enumerate_lock); mutex_init(&msm_pcie_dev[i].setup_lock); mutex_init(&msm_pcie_dev[i].clk_lock); mutex_init(&msm_pcie_dev[i].recovery_lock); spin_lock_init(&msm_pcie_dev[i].wakeup_lock); spin_lock_init(&msm_pcie_dev[i].irq_lock); Loading