diff options
Diffstat (limited to 'drivers/clk/sifive/sifive-prci.c')
-rw-r--r-- | drivers/clk/sifive/sifive-prci.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index 1490b01ce629..0d79ba31a793 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -453,6 +453,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd) r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */ } +/* PCIE AUX clock APIs for enable, disable. */ +int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r; + + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); + + if (r & PRCI_PCIE_AUX_EN_MASK) + return 1; + else + return 0; +} + +int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r __maybe_unused; + + if (sifive_prci_pcie_aux_clock_is_enabled(hw)) + return 0; + + __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd); + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */ + + return 0; +} + +void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw) +{ + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); + struct __prci_data *pd = pc->pd; + u32 r __maybe_unused; + + __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd); + r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */ + +} + /** * __prci_register_clocks() - register clock controls in the PRCI * @dev: Linux struct device @@ -547,6 +588,19 @@ static int sifive_prci_probe(struct platform_device *pdev) if (IS_ERR(pd->va)) return PTR_ERR(pd->va); + pd->reset.rcdev.owner = THIS_MODULE; + pd->reset.rcdev.nr_resets = PRCI_RST_NR; + pd->reset.rcdev.ops = &reset_simple_ops; + pd->reset.rcdev.of_node = pdev->dev.of_node; + pd->reset.active_low = true; + pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET; + spin_lock_init(&pd->reset.lock); + + r = devm_reset_controller_register(&pdev->dev, &pd->reset.rcdev); + if (r) { + dev_err(dev, "could not register reset controller: %d\n", r); + return r; + } r = __prci_register_clocks(dev, pd, desc); if (r) { dev_err(dev, "could not register clocks: %d\n", r); |