diff --git a/drivers/pci/controller/pci-msm.c b/drivers/pci/controller/pci-msm.c index 9de57f01491c..ba472a3037e8 100644 --- a/drivers/pci/controller/pci-msm.c +++ b/drivers/pci/controller/pci-msm.c @@ -567,6 +567,12 @@ struct msm_pcie_phy_info_t { u32 delay; }; +/* tcsr info structure */ +struct msm_pcie_tcsr_info_t { + u32 offset; + u32 val; +}; + /* sid info structure */ struct msm_pcie_sid_info_t { u16 bdf; @@ -981,6 +987,8 @@ struct msm_pcie_dev_t { u32 num_parf_testbus_sel; u32 phy_len; struct msm_pcie_phy_info_t *phy_sequence; + u32 tcsr_len; + struct msm_pcie_tcsr_info_t *tcsr_config; u32 sid_info_len; struct msm_pcie_sid_info_t *sid_info; bool bridge_found; @@ -1250,6 +1258,21 @@ static void pcie_phy_dump(struct msm_pcie_dev_t *dev) } } +static void pcie_tcsr_init(struct msm_pcie_dev_t *dev) +{ + int i; + struct msm_pcie_tcsr_info_t *tcsr_cfg; + + i = dev->tcsr_len; + tcsr_cfg = dev->tcsr_config; + while (i--) { + msm_pcie_write_reg(dev->tcsr, + tcsr_cfg->offset, + tcsr_cfg->val); + tcsr_cfg++; + } +} + static int msm_pcie_check_align(struct msm_pcie_dev_t *dev, u32 offset) { @@ -4060,6 +4083,34 @@ static int msm_pcie_get_reg(struct msm_pcie_dev_t *pcie_dev) return 0; } +static int msm_pcie_get_tcsr_values(struct msm_pcie_dev_t *dev, + struct platform_device *pdev) +{ + int size = 0, ret = 0; + + of_get_property(pdev->dev.of_node, "qcom,tcsr", &size); + + if (!size) { + PCIE_DBG(dev, "PCIe: RC%d: tcsr is not present in DT\n", + dev->rc_idx); + return 0; + } + + dev->tcsr_config = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + + if (!dev->tcsr_config) + return -ENOMEM; + + dev->tcsr_len = size / sizeof(*dev->tcsr_config); + + of_property_read_u32_array(pdev->dev.of_node, + "qcom,tcsr", + (unsigned int *)dev->tcsr_config, + size / sizeof(dev->tcsr_config->offset)); + + return ret; +} + static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, struct platform_device *pdev) { @@ -4094,6 +4145,10 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, } } + ret = msm_pcie_get_tcsr_values(dev, pdev); + if (ret) + return ret; + ret = msm_pcie_get_clk(dev); if (ret) return ret; @@ -4358,6 +4413,10 @@ static int msm_pcie_enable(struct msm_pcie_dev_t *dev) msm_pcie_write_reg(dev->parf, PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT, BIT(31) | val); + /* init tcsr */ + if (dev->tcsr_config) + pcie_tcsr_init(dev); + /* init PCIe PHY */ ret = pcie_phy_init(dev); if (ret)