Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2356dc1 authored by Nitesh Gupta's avatar Nitesh Gupta Committed by Gerrit - the friendly Code Review server
Browse files

msm: pcie: Add tcsr configuration



Add support for reading tcsr configuration from device tree and
configuring tcsr register dynamically.
This change for supporting sa8195p PCIe1. The default PCIe linkage
status of PCIe1 and 2 on sa8195p is:
PCIe1: not enabled
PCIe2: x4 lane
When config the register TCSR_PCIEPHY_LINK_CONFIG to 0(default 1),
the linkage status becomes:
PCIe1: x2 lane
PCIe2: x2 lane
This change add the ability to read tcsr value from device tree.

Change-Id: Iac53f61a147a839772c8411993f3be233b142b56
Signed-off-by: default avatarXiang Li <lixiang@codeaurora.org>
Signed-off-by: default avatarNitesh Gupta <nitegupt@codeaurora.org>
parent dabe1619
Loading
Loading
Loading
Loading
+60 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.*/
/* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.*/

#include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h>
#include <linux/bitops.h>
@@ -540,6 +540,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;
@@ -742,6 +748,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;
	u32 ep_shadow[MAX_DEVICE_NUM][PCIE_CONF_SPACE_DW];
@@ -1099,6 +1107,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)
{
@@ -3795,6 +3818,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)
{
@@ -3829,6 +3880,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;
@@ -4084,6 +4139,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)