Message ID | 20190411170355.6882-13-mmaddireddy@nvidia.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | Enable Tegra PCIe root port features | expand |
On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote: > The logic which blocks read requests till AFI gets ACK for all outstanding > MC writes does not behave correctly when number of outstanding write > becomes more than 32 in Tegra124 and 132. > > SW fixup to prevent this issue is to limit outstanding posted writes and > tweak updateFC timer threshold. > > Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> > static void tegra_pcie_port_enable(struct tegra_pcie_port *port) > @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { > .program_uphy = true, > .update_clamp_threshold = false, > .program_deskew_time = false, > + .raw_violation_fixup = false, > .ectl.enable = false, It doesn't really matter either way, but you don't *have* to initialize all these flags to "false" since that's the default for uninitialized fields in static structs like these. If you left them out, the structs would only contain the "true" items, and it'd be easier to see what's special about each SoC. > }; > > @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { > .program_uphy = true, > .update_clamp_threshold = false, > .program_deskew_time = false, > + .raw_violation_fixup = false, > .ectl.enable = false, > };
On 12-Apr-19 1:31 AM, Bjorn Helgaas wrote: > On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote: >> The logic which blocks read requests till AFI gets ACK for all outstanding >> MC writes does not behave correctly when number of outstanding write >> becomes more than 32 in Tegra124 and 132. >> >> SW fixup to prevent this issue is to limit outstanding posted writes and >> tweak updateFC timer threshold. >> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> >> static void tegra_pcie_port_enable(struct tegra_pcie_port *port) >> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = false, >> .program_deskew_time = false, >> + .raw_violation_fixup = false, >> .ectl.enable = false, > It doesn't really matter either way, but you don't *have* to > initialize all these flags to "false" since that's the default for > uninitialized fields in static structs like these. If you left them > out, the structs would only contain the "true" items, and it'd be > easier to see what's special about each SoC. SoC flags are explicitly set false if not supported, I am following same existing coding style in this driver. Maybe the intention here is to convey what is not supported by a particular SoC without going through soc struct definition. >> }; >> >> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = false, >> .program_deskew_time = false, >> + .raw_violation_fixup = false, >> .ectl.enable = false, >> };
On Fri, Apr 12, 2019 at 11:29:35AM +0530, Manikanta Maddireddy wrote: > > On 12-Apr-19 1:31 AM, Bjorn Helgaas wrote: > > On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote: > >> The logic which blocks read requests till AFI gets ACK for all outstanding > >> MC writes does not behave correctly when number of outstanding write > >> becomes more than 32 in Tegra124 and 132. > >> > >> SW fixup to prevent this issue is to limit outstanding posted writes and > >> tweak updateFC timer threshold. > >> > >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> > >> static void tegra_pcie_port_enable(struct tegra_pcie_port *port) > >> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { > >> .program_uphy = true, > >> .update_clamp_threshold = false, > >> .program_deskew_time = false, > >> + .raw_violation_fixup = false, > >> .ectl.enable = false, > > It doesn't really matter either way, but you don't *have* to > > initialize all these flags to "false" since that's the default for > > uninitialized fields in static structs like these. If you left them > > out, the structs would only contain the "true" items, and it'd be > > easier to see what's special about each SoC. > > SoC flags are explicitly set false if not supported, I am following > same existing coding style in this driver. Maybe the intention here is > to convey what is not supported by a particular SoC without going > through soc struct definition. Yes, this was originally done on purpose. I think it's good to follow the existing convention, unless Bjorn feels strongly about it. Thierry
On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote: > The logic which blocks read requests till AFI gets ACK for all outstanding > MC writes does not behave correctly when number of outstanding write > becomes more than 32 in Tegra124 and 132. > > SW fixup to prevent this issue is to limit outstanding posted writes and > tweak updateFC timer threshold. > > Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> > --- > drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c > index 9e61da68cfae..b74408eeb367 100644 > --- a/drivers/pci/controller/pci-tegra.c > +++ b/drivers/pci/controller/pci-tegra.c > @@ -178,6 +178,13 @@ > > #define AFI_PEXBIAS_CTRL_0 0x168 > > +#define RP_PRIV_XP_DL 0x00000494 > +#define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1) > + > +#define RP_RX_HDR_LIMIT 0x00000e00 > +#define RP_RX_HDR_LIMIT_PW_MASK (0xff << 8) > +#define RP_RX_HDR_LIMIT_PW (0x0e << 8) > + > #define RP_ECTL_2_R1 0x00000e84 > #define RP_ECTL_2_R1_RX_CTLE_1C_MASK 0xffff > > @@ -208,6 +215,7 @@ > #define RP_VEND_XP_DL_UP (1 << 30) > #define RP_VEND_XP_OPPORTUNISTIC_ACK (1 << 27) > #define RP_VEND_XP_OPPORTUNISTIC_UPDATEFC (1 << 28) > +#define RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK (0xff << 18) > > #define RP_VEND_CTL0 0x00000f44 > #define RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK (0xf << 12) > @@ -300,6 +308,7 @@ struct tegra_pcie_soc { > u32 tx_ref_sel; > u32 pads_refclk_cfg0; > u32 pads_refclk_cfg1; > + u32 update_fc_val; Shouldn't this be something like "update_fc_threshold" since the mask defined above is for a field named UPDATE_FC_THRESHOLD? > bool has_pex_clkreq_en; > bool has_pex_bias_ctrl; > bool has_intr_prsnt_sense; > @@ -309,6 +318,7 @@ struct tegra_pcie_soc { > bool program_uphy; > bool update_clamp_threshold; > bool program_deskew_time; > + bool raw_violation_fixup; > struct { > struct { > u32 rp_ectl_2_r1; > @@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port) > value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH; > writel(value, port->base + RP_VEND_CTL0); > } > + > + /* Fixup for read after write violation in T124 & T132 platforms */ No need to mention the SoC generations here, it's already implied by the per-SoC flag. Thierry > + if (soc->raw_violation_fixup) { > + value = readl(port->base + RP_RX_HDR_LIMIT); > + value &= ~RP_RX_HDR_LIMIT_PW_MASK; > + value |= RP_RX_HDR_LIMIT_PW; > + writel(value, port->base + RP_RX_HDR_LIMIT); > + > + value = readl(port->base + RP_PRIV_XP_DL); > + value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD; > + writel(value, port->base + RP_PRIV_XP_DL); > + > + value = readl(port->base + RP_VEND_XP); > + value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK; > + value |= soc->update_fc_val; > + writel(value, port->base + RP_VEND_XP); > + } > } > > static void tegra_pcie_port_enable(struct tegra_pcie_port *port) > @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { > .program_uphy = true, > .update_clamp_threshold = false, > .program_deskew_time = false, > + .raw_violation_fixup = false, > .ectl.enable = false, > }; > > @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { > .program_uphy = true, > .update_clamp_threshold = false, > .program_deskew_time = false, > + .raw_violation_fixup = false, > .ectl.enable = false, > }; > > @@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = { > .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, > .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, > .pads_refclk_cfg0 = 0x44ac44ac, > + /* FC threshold is bit[25:18] */ > + .update_fc_val = 0x03fc0000, > .has_pex_clkreq_en = true, > .has_pex_bias_ctrl = true, > .has_intr_prsnt_sense = true, > @@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = { > .program_uphy = true, > .update_clamp_threshold = true, > .program_deskew_time = false, > + .raw_violation_fixup = true, > .ectl.enable = false, > }; > > @@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = { > .program_uphy = true, > .update_clamp_threshold = true, > .program_deskew_time = true, > + .raw_violation_fixup = false, > .ectl.regs.rp_ectl_2_r1 = 0x0000000f, > .ectl.regs.rp_ectl_4_r1 = 0x00000067, > .ectl.regs.rp_ectl_5_r1 = 0x55010000, > @@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = { > .program_uphy = false, > .update_clamp_threshold = false, > .program_deskew_time = false, > + .raw_violation_fixup = false, > .ectl.enable = false, > }; > > -- > 2.17.1 >
On 15-Apr-19 5:15 PM, Thierry Reding wrote: > On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote: >> The logic which blocks read requests till AFI gets ACK for all outstanding >> MC writes does not behave correctly when number of outstanding write >> becomes more than 32 in Tegra124 and 132. >> >> SW fixup to prevent this issue is to limit outstanding posted writes and >> tweak updateFC timer threshold. >> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> >> --- >> drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++ >> 1 file changed, 34 insertions(+) >> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c >> index 9e61da68cfae..b74408eeb367 100644 >> --- a/drivers/pci/controller/pci-tegra.c >> +++ b/drivers/pci/controller/pci-tegra.c >> @@ -178,6 +178,13 @@ >> >> #define AFI_PEXBIAS_CTRL_0 0x168 >> >> +#define RP_PRIV_XP_DL 0x00000494 >> +#define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1) >> + >> +#define RP_RX_HDR_LIMIT 0x00000e00 >> +#define RP_RX_HDR_LIMIT_PW_MASK (0xff << 8) >> +#define RP_RX_HDR_LIMIT_PW (0x0e << 8) >> + >> #define RP_ECTL_2_R1 0x00000e84 >> #define RP_ECTL_2_R1_RX_CTLE_1C_MASK 0xffff >> >> @@ -208,6 +215,7 @@ >> #define RP_VEND_XP_DL_UP (1 << 30) >> #define RP_VEND_XP_OPPORTUNISTIC_ACK (1 << 27) >> #define RP_VEND_XP_OPPORTUNISTIC_UPDATEFC (1 << 28) >> +#define RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK (0xff << 18) >> >> #define RP_VEND_CTL0 0x00000f44 >> #define RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK (0xf << 12) >> @@ -300,6 +308,7 @@ struct tegra_pcie_soc { >> u32 tx_ref_sel; >> u32 pads_refclk_cfg0; >> u32 pads_refclk_cfg1; >> + u32 update_fc_val; > Shouldn't this be something like "update_fc_threshold" since the mask > defined above is for a field named UPDATE_FC_THRESHOLD? > >> bool has_pex_clkreq_en; >> bool has_pex_bias_ctrl; >> bool has_intr_prsnt_sense; >> @@ -309,6 +318,7 @@ struct tegra_pcie_soc { >> bool program_uphy; >> bool update_clamp_threshold; >> bool program_deskew_time; >> + bool raw_violation_fixup; >> struct { >> struct { >> u32 rp_ectl_2_r1; >> @@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port) >> value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH; >> writel(value, port->base + RP_VEND_CTL0); >> } >> + >> + /* Fixup for read after write violation in T124 & T132 platforms */ > No need to mention the SoC generations here, it's already implied by the > per-SoC flag. > > Thierry I will take care of both the comments in V2 Manikanta > >> + if (soc->raw_violation_fixup) { >> + value = readl(port->base + RP_RX_HDR_LIMIT); >> + value &= ~RP_RX_HDR_LIMIT_PW_MASK; >> + value |= RP_RX_HDR_LIMIT_PW; >> + writel(value, port->base + RP_RX_HDR_LIMIT); >> + >> + value = readl(port->base + RP_PRIV_XP_DL); >> + value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD; >> + writel(value, port->base + RP_PRIV_XP_DL); >> + >> + value = readl(port->base + RP_VEND_XP); >> + value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK; >> + value |= soc->update_fc_val; >> + writel(value, port->base + RP_VEND_XP); >> + } >> } >> >> static void tegra_pcie_port_enable(struct tegra_pcie_port *port) >> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = false, >> .program_deskew_time = false, >> + .raw_violation_fixup = false, >> .ectl.enable = false, >> }; >> >> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = false, >> .program_deskew_time = false, >> + .raw_violation_fixup = false, >> .ectl.enable = false, >> }; >> >> @@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = { >> .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, >> .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, >> .pads_refclk_cfg0 = 0x44ac44ac, >> + /* FC threshold is bit[25:18] */ >> + .update_fc_val = 0x03fc0000, > > >> .has_pex_clkreq_en = true, >> .has_pex_bias_ctrl = true, >> .has_intr_prsnt_sense = true, >> @@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = true, >> .program_deskew_time = false, >> + .raw_violation_fixup = true, >> .ectl.enable = false, >> }; >> >> @@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = { >> .program_uphy = true, >> .update_clamp_threshold = true, >> .program_deskew_time = true, >> + .raw_violation_fixup = false, >> .ectl.regs.rp_ectl_2_r1 = 0x0000000f, >> .ectl.regs.rp_ectl_4_r1 = 0x00000067, >> .ectl.regs.rp_ectl_5_r1 = 0x55010000, >> @@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = { >> .program_uphy = false, >> .update_clamp_threshold = false, >> .program_deskew_time = false, >> + .raw_violation_fixup = false, >> .ectl.enable = false, >> }; >> >> -- >> 2.17.1 >>
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 9e61da68cfae..b74408eeb367 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -178,6 +178,13 @@ #define AFI_PEXBIAS_CTRL_0 0x168 +#define RP_PRIV_XP_DL 0x00000494 +#define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1) + +#define RP_RX_HDR_LIMIT 0x00000e00 +#define RP_RX_HDR_LIMIT_PW_MASK (0xff << 8) +#define RP_RX_HDR_LIMIT_PW (0x0e << 8) + #define RP_ECTL_2_R1 0x00000e84 #define RP_ECTL_2_R1_RX_CTLE_1C_MASK 0xffff @@ -208,6 +215,7 @@ #define RP_VEND_XP_DL_UP (1 << 30) #define RP_VEND_XP_OPPORTUNISTIC_ACK (1 << 27) #define RP_VEND_XP_OPPORTUNISTIC_UPDATEFC (1 << 28) +#define RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK (0xff << 18) #define RP_VEND_CTL0 0x00000f44 #define RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK (0xf << 12) @@ -300,6 +308,7 @@ struct tegra_pcie_soc { u32 tx_ref_sel; u32 pads_refclk_cfg0; u32 pads_refclk_cfg1; + u32 update_fc_val; bool has_pex_clkreq_en; bool has_pex_bias_ctrl; bool has_intr_prsnt_sense; @@ -309,6 +318,7 @@ struct tegra_pcie_soc { bool program_uphy; bool update_clamp_threshold; bool program_deskew_time; + bool raw_violation_fixup; struct { struct { u32 rp_ectl_2_r1; @@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port) value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH; writel(value, port->base + RP_VEND_CTL0); } + + /* Fixup for read after write violation in T124 & T132 platforms */ + if (soc->raw_violation_fixup) { + value = readl(port->base + RP_RX_HDR_LIMIT); + value &= ~RP_RX_HDR_LIMIT_PW_MASK; + value |= RP_RX_HDR_LIMIT_PW; + writel(value, port->base + RP_RX_HDR_LIMIT); + + value = readl(port->base + RP_PRIV_XP_DL); + value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD; + writel(value, port->base + RP_PRIV_XP_DL); + + value = readl(port->base + RP_VEND_XP); + value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK; + value |= soc->update_fc_val; + writel(value, port->base + RP_VEND_XP); + } } static void tegra_pcie_port_enable(struct tegra_pcie_port *port) @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = { .program_uphy = true, .update_clamp_threshold = false, .program_deskew_time = false, + .raw_violation_fixup = false, .ectl.enable = false, }; @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = { .program_uphy = true, .update_clamp_threshold = false, .program_deskew_time = false, + .raw_violation_fixup = false, .ectl.enable = false, }; @@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = { .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .pads_refclk_cfg0 = 0x44ac44ac, + /* FC threshold is bit[25:18] */ + .update_fc_val = 0x03fc0000, .has_pex_clkreq_en = true, .has_pex_bias_ctrl = true, .has_intr_prsnt_sense = true, @@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = { .program_uphy = true, .update_clamp_threshold = true, .program_deskew_time = false, + .raw_violation_fixup = true, .ectl.enable = false, }; @@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = { .program_uphy = true, .update_clamp_threshold = true, .program_deskew_time = true, + .raw_violation_fixup = false, .ectl.regs.rp_ectl_2_r1 = 0x0000000f, .ectl.regs.rp_ectl_4_r1 = 0x00000067, .ectl.regs.rp_ectl_5_r1 = 0x55010000, @@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = { .program_uphy = false, .update_clamp_threshold = false, .program_deskew_time = false, + .raw_violation_fixup = false, .ectl.enable = false, };
The logic which blocks read requests till AFI gets ACK for all outstanding MC writes does not behave correctly when number of outstanding write becomes more than 32 in Tegra124 and 132. SW fixup to prevent this issue is to limit outstanding posted writes and tweak updateFC timer threshold. Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> --- drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)