clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Link: https://lore.kernel.org/r/20210504105940.100004-2-greentime.hu@sifive.com
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
Greentime Hu 2021-05-04 18:59:35 +08:00 committed by Lorenzo Pieralisi
parent a38fd87484
commit c61287bf17
5 changed files with 63 additions and 1 deletions

View file

@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
};
static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
.enable = sifive_prci_pcie_aux_clock_enable,
.disable = sifive_prci_pcie_aux_clock_disable,
.is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
};
/* List of clock controls provided by the PRCI */
struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
},
[PRCI_CLK_PCIE_AUX] = {
.name = "pcie_aux",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_pcie_aux_clk_ops,
},
};

View file

@ -9,7 +9,7 @@
#include "sifive-prci.h"
#define NUM_CLOCK_FU740 8
#define NUM_CLOCK_FU740 9
extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];

View file

@ -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

View file

@ -67,6 +67,11 @@
#define PRCI_DDRPLLCFG1_CKE_SHIFT 31
#define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
/* PCIEAUX */
#define PRCI_PCIE_AUX_OFFSET 0x14
#define PRCI_PCIE_AUX_EN_SHIFT 0
#define PRCI_PCIE_AUX_EN_MASK (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
/* GEMGXLPLLCFG0 */
#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
#define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate);
int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
#endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */

View file

@ -19,5 +19,6 @@
#define PRCI_CLK_CLTXPLL 5
#define PRCI_CLK_TLCLK 6
#define PRCI_CLK_PCLK 7
#define PRCI_CLK_PCIE_AUX 8
#endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */