PCI: tegra: Convert WRAP transactions to increment burst
AFI module doesn't support WRAP transactions in Tegra. WRAP instructions from CPU targeting PCIe BAR memory can cause data corruption. This can happen if PCIe memory is marked as normal cacheable or GRE device. Program mselect register to convert WRAP transactions to increment burst for slave PCIe. bug 200353330 bug 200420606 Change-Id: I867da85eb63332708bc294238e30ad99a71f345d Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1786561 (cherry picked from commit b345cfae7b7633a3a52e0f2a659baf44feee1466) Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407869 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
@@ -310,6 +310,7 @@ struct tegra_pcie_soc {
|
||||
bool program_deskew_time;
|
||||
bool update_fc_timer;
|
||||
bool has_cache_bars;
|
||||
bool enable_wrap;
|
||||
struct {
|
||||
struct {
|
||||
u32 rp_ectl_1_r1;
|
||||
@@ -671,6 +672,26 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
|
||||
writel(value, port->base + RP_ECTL_6_R2);
|
||||
}
|
||||
|
||||
static void tegra_pcie_enable_wrap(void)
|
||||
{
|
||||
u32 val;
|
||||
void __iomem *msel_base;
|
||||
|
||||
#define MSELECT_CONFIG_BASE 0x50060000
|
||||
#define MSELECT_CONFIG_WRAP_TO_INCR_SLAVE1 BIT(28)
|
||||
#define MSELECT_CONFIG_ERR_RESP_EN_SLAVE1 BIT(24)
|
||||
|
||||
/* Config MSELECT to support wrap trans for normal NC & GRE mapping */
|
||||
msel_base = ioremap(MSELECT_CONFIG_BASE, 4);
|
||||
val = readl(msel_base);
|
||||
/* Enable WRAP_TO_INCR_SLAVE1 */
|
||||
val |= MSELECT_CONFIG_WRAP_TO_INCR_SLAVE1;
|
||||
/* Disable ERR_RESP_EN_SLAVE1 */
|
||||
val &= ~MSELECT_CONFIG_ERR_RESP_EN_SLAVE1;
|
||||
writel(val, msel_base);
|
||||
iounmap(msel_base);
|
||||
}
|
||||
|
||||
static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
|
||||
{
|
||||
const struct tegra_pcie_soc *soc = port->pcie->soc;
|
||||
@@ -705,6 +726,9 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
|
||||
value &= ~PCI_EXP_LNKSTA_CLS;
|
||||
value |= PCI_EXP_LNKSTA_CLS_2_5GB;
|
||||
writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
|
||||
|
||||
if (soc->enable_wrap)
|
||||
tegra_pcie_enable_wrap();
|
||||
}
|
||||
|
||||
static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
|
||||
@@ -2462,6 +2486,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
|
||||
.program_deskew_time = false,
|
||||
.update_fc_timer = false,
|
||||
.has_cache_bars = true,
|
||||
.enable_wrap = false,
|
||||
.ectl.enable = false,
|
||||
};
|
||||
|
||||
@@ -2491,6 +2516,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
|
||||
.program_deskew_time = false,
|
||||
.update_fc_timer = false,
|
||||
.has_cache_bars = false,
|
||||
.enable_wrap = false,
|
||||
.ectl.enable = false,
|
||||
};
|
||||
|
||||
@@ -2512,6 +2538,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
|
||||
.program_deskew_time = false,
|
||||
.update_fc_timer = false,
|
||||
.has_cache_bars = false,
|
||||
.enable_wrap = false,
|
||||
.ectl.enable = false,
|
||||
};
|
||||
|
||||
@@ -2535,6 +2562,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
|
||||
.program_deskew_time = true,
|
||||
.update_fc_timer = true,
|
||||
.has_cache_bars = false,
|
||||
.enable_wrap = true,
|
||||
.ectl = {
|
||||
.regs = {
|
||||
.rp_ectl_1_r1 = 0x0000001f,
|
||||
@@ -2614,6 +2642,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
|
||||
.program_deskew_time = false,
|
||||
.update_fc_timer = false,
|
||||
.has_cache_bars = false,
|
||||
.enable_wrap = false,
|
||||
.ectl.enable = false,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user