#define TEGRA_SMC_PMC_WRITE 0xbb
struct pmc_clk {
- struct clk_hw hw;
- unsigned long offs;
- u32 mux_shift;
- u32 force_en_shift;
+ struct clk_hw hw;
+ struct tegra_pmc *pmc;
+ unsigned long offs;
+ u32 mux_shift;
+ u32 force_en_shift;
};
#define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw)
struct pmc_clk_gate {
- struct clk_hw hw;
- unsigned long offs;
- u32 shift;
+ struct clk_hw hw;
+ struct tegra_pmc *pmc;
+ unsigned long offs;
+ u32 shift;
};
#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
return NOTIFY_OK;
}
-static void pmc_clk_fence_udelay(u32 offset)
+static void pmc_clk_fence_udelay(struct tegra_pmc *pmc, u32 offset)
{
tegra_pmc_readl(pmc, offset);
/* pmc clk propagation delay 2 us */
struct pmc_clk *clk = to_pmc_clk(hw);
u32 val;
- val = tegra_pmc_readl(pmc, clk->offs) >> clk->mux_shift;
+ val = tegra_pmc_readl(clk->pmc, clk->offs) >> clk->mux_shift;
val &= PMC_CLK_OUT_MUX_MASK;
return val;
struct pmc_clk *clk = to_pmc_clk(hw);
u32 val;
- val = tegra_pmc_readl(pmc, clk->offs);
+ val = tegra_pmc_readl(clk->pmc, clk->offs);
val &= ~(PMC_CLK_OUT_MUX_MASK << clk->mux_shift);
val |= index << clk->mux_shift;
- tegra_pmc_writel(pmc, val, clk->offs);
- pmc_clk_fence_udelay(clk->offs);
+ tegra_pmc_writel(clk->pmc, val, clk->offs);
+ pmc_clk_fence_udelay(clk->pmc, clk->offs);
return 0;
}
struct pmc_clk *clk = to_pmc_clk(hw);
u32 val;
- val = tegra_pmc_readl(pmc, clk->offs) & BIT(clk->force_en_shift);
+ val = tegra_pmc_readl(clk->pmc, clk->offs) & BIT(clk->force_en_shift);
return val ? 1 : 0;
}
-static void pmc_clk_set_state(unsigned long offs, u32 shift, int state)
+static void pmc_clk_set_state(struct tegra_pmc *pmc, unsigned long offs,
+ u32 shift, int state)
{
u32 val;
val = tegra_pmc_readl(pmc, offs);
val = state ? (val | BIT(shift)) : (val & ~BIT(shift));
tegra_pmc_writel(pmc, val, offs);
- pmc_clk_fence_udelay(offs);
+ pmc_clk_fence_udelay(pmc, offs);
}
static int pmc_clk_enable(struct clk_hw *hw)
{
struct pmc_clk *clk = to_pmc_clk(hw);
- pmc_clk_set_state(clk->offs, clk->force_en_shift, 1);
+ pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 1);
return 0;
}
{
struct pmc_clk *clk = to_pmc_clk(hw);
- pmc_clk_set_state(clk->offs, clk->force_en_shift, 0);
+ pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 0);
}
static const struct clk_ops pmc_clk_ops = {
CLK_SET_PARENT_GATE;
pmc_clk->hw.init = &init;
+ pmc_clk->pmc = pmc;
pmc_clk->offs = offset;
pmc_clk->mux_shift = data->mux_shift;
pmc_clk->force_en_shift = data->force_en_shift;
static int pmc_clk_gate_is_enabled(struct clk_hw *hw)
{
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+ u32 value = tegra_pmc_readl(gate->pmc, gate->offs);
- return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
+ return value & BIT(gate->shift) ? 1 : 0;
}
static int pmc_clk_gate_enable(struct clk_hw *hw)
{
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
- pmc_clk_set_state(gate->offs, gate->shift, 1);
+ pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 1);
return 0;
}
{
struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
- pmc_clk_set_state(gate->offs, gate->shift, 0);
+ pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 0);
}
static const struct clk_ops pmc_clk_gate_ops = {
init.flags = 0;
gate->hw.init = &init;
+ gate->pmc = pmc;
gate->offs = offset;
gate->shift = shift;