clk: axg: add pll enable op [1/1]

PD#146411: add enable op for pcie_gp0/hifi/mpll pll

Change-Id: I15eb279a0bf00035d2053322179dddc5d8d9d213
Signed-off-by: Qiufang Dai <qiufang.dai@amlogic.com>
This commit is contained in:
Qiufang Dai
2017-07-13 14:20:54 +08:00
committed by Jianxin Pan
parent 1ed4152d43
commit 0ec1fea28c
2 changed files with 80 additions and 0 deletions

View File

@@ -39,6 +39,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/amlogic/cpu_version.h>
#include <linux/clk.h>
#ifdef CONFIG_ARM64
#include "../clkc.h"
@@ -273,6 +274,62 @@ static int meson_axg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return ret;
}
static int meson_axg_pll_enable(struct clk_hw *hw)
{
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
struct parm *p;
int ret = 0;
unsigned long flags = 0;
unsigned long first_set = 1;
struct clk *parent;
unsigned long rate;
p = &pll->n;
if (pll->lock)
spin_lock_irqsave(pll->lock, flags);
if (readl(pll->base + p->reg_off) & MESON_PLL_ENABLE) {
if (pll->lock)
spin_unlock_irqrestore(pll->lock, flags);
return ret;
}
if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
|| !strcmp(clk_hw_get_name(hw), "hifi_pll")
|| !strcmp(clk_hw_get_name(hw), "pcie_pll")) {
void *cntlbase = pll->base + p->reg_off;
if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) {
if (readl(cntlbase + (u64)(6*4)) == AXG_PCIE_PLL_CNTL6)
first_set = 0;
} else if (!strcmp(clk_hw_get_name(hw), "hifi_pll")) {
if (readl(cntlbase + (u64)(4*4)) == AXG_HIFI_PLL_CNTL5)
first_set = 0;
} else {
if (readl(cntlbase + (u64)(4*4)) == GXL_GP0_CNTL5)
first_set = 0;
}
}
parent = clk_get_parent(hw->clk);
/*First init, just set minimal rate.*/
if (first_set)
rate = pll->rate_table[0].rate;
else {
rate = meson_axg_pll_recalc_rate(hw, clk_get_rate(parent));
rate = meson_axg_pll_round_rate(hw, rate, NULL);
}
if (pll->lock)
spin_unlock_irqrestore(pll->lock, flags);
ret = meson_axg_pll_set_rate(hw, rate, clk_get_rate(parent));
return ret;
}
static void meson_axg_pll_disable(struct clk_hw *hw)
{
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
@@ -297,6 +354,7 @@ const struct clk_ops meson_axg_pll_ops = {
.recalc_rate = meson_axg_pll_recalc_rate,
.round_rate = meson_axg_pll_round_rate,
.set_rate = meson_axg_pll_set_rate,
.enable = meson_axg_pll_enable,
.disable = meson_axg_pll_disable,
};

View File

@@ -140,6 +140,27 @@ static int mpll_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static int mpll_enable(struct clk_hw *hw)
{
struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
struct parm *p = &mpll->sdm;
unsigned long reg;
unsigned long flags = 0;
if (mpll->lock)
spin_lock_irqsave(mpll->lock, flags);
reg = readl(mpll->base + p->reg_off);
reg = PARM_SET(1, mpll->sdm_en, reg, 1);
reg = PARM_SET(1, mpll->en_dds, reg, 1);
writel(reg, mpll->base + p->reg_off);
if (mpll->lock)
spin_unlock_irqrestore(mpll->lock, flags);
return 0;
}
void mpll_disable(struct clk_hw *hw)
{
struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
@@ -163,6 +184,7 @@ const struct clk_ops meson_clk_mpll_ops = {
.recalc_rate = mpll_recalc_rate,
.round_rate = meson_clk_pll_round_rate,
.set_rate = mpll_set_rate,
.enable = mpll_enable,
.disable = mpll_disable,
};