Skip to content

Commit b91401a

Browse files
Marek Vasutgeertu
authored andcommitted
clk: renesas: cpg-mssr: Read back reset registers to assure values latched
On R-Car V4H, the PCIEC controller DBI read would generate an SError in case the controller reset is released by writing SRSTCLR register first, and immediately afterward reading some PCIEC controller DBI register. The issue triggers in rcar_gen4_pcie_additional_common_init() on dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). The reset controller which contains the SRSTCLR register and the PCIEC controller which contains the DBI register share the same root access bus, but the bus then splits into separate segments before reaching each IP. Even if the SRSTCLR write access was posted on the bus before the DBI read access, it seems the DBI read access may reach the PCIEC controller before the SRSTCLR write completed, and trigger the SError. Mitigate the issue by adding a dummy SRSTCLR read, which assures the SRSTCLR write completes fully and is latched into the reset controller, before the PCIEC DBI read access can occur. Fixes: 0ab55cf ("clk: renesas: cpg-mssr: Add support for R-Car V4H") Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
1 parent 62abfd7 commit b91401a

1 file changed

Lines changed: 21 additions & 25 deletions

File tree

drivers/clk/renesas/renesas-cpg-mssr.c

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -676,18 +676,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
676676

677677
#define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev)
678678

679-
static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
680-
unsigned long id)
679+
static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev,
680+
const char *func, bool set, unsigned long id)
681681
{
682682
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
683683
unsigned int reg = id / 32;
684684
unsigned int bit = id % 32;
685+
const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg];
685686
u32 bitmask = BIT(bit);
686687

687-
dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
688+
if (func)
689+
dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit);
690+
691+
writel(bitmask, priv->pub.base0 + off);
692+
readl(priv->pub.base0 + off);
693+
barrier_data(priv->pub.base0 + off);
694+
695+
return 0;
696+
}
697+
698+
static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
699+
unsigned long id)
700+
{
701+
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
688702

689703
/* Reset module */
690-
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
704+
cpg_mssr_reset_operate(rcdev, "reset", true, id);
691705

692706
/*
693707
* On R-Car Gen4, delay after SRCR has been written is 1ms.
@@ -700,36 +714,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
700714
usleep_range(35, 1000);
701715

702716
/* Release module from reset state */
703-
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
704-
705-
return 0;
717+
return cpg_mssr_reset_operate(rcdev, NULL, false, id);
706718
}
707719

708720
static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
709721
{
710-
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
711-
unsigned int reg = id / 32;
712-
unsigned int bit = id % 32;
713-
u32 bitmask = BIT(bit);
714-
715-
dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
716-
717-
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
718-
return 0;
722+
return cpg_mssr_reset_operate(rcdev, "assert", true, id);
719723
}
720724

721725
static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
722726
unsigned long id)
723727
{
724-
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
725-
unsigned int reg = id / 32;
726-
unsigned int bit = id % 32;
727-
u32 bitmask = BIT(bit);
728-
729-
dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
730-
731-
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
732-
return 0;
728+
return cpg_mssr_reset_operate(rcdev, "deassert", false, id);
733729
}
734730

735731
static int cpg_mssr_status(struct reset_controller_dev *rcdev,

0 commit comments

Comments
 (0)