clk/rockchip/regmap: Prepare RK628 PLL support

Change-Id: I45049b298de7635c08f92cd89db08b86ba6901f3
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
This commit is contained in:
Wyon Bi
2019-10-22 16:20:42 +08:00
committed by Tao Huang
parent 459a08874a
commit 962d002400
3 changed files with 41 additions and 31 deletions

View File

@@ -26,12 +26,6 @@
#define PLL_FBDIV_MASK GENMASK(11, 0)
#define PLL_FBDIV_SHIFT 0
#define PLL_LOCK BIT(15)
#define PLL_POWER_DOWN HIWORD_UPDATE(1, 10, 10)
#define PLL_POWER_UP HIWORD_UPDATE(0, 10, 10)
#define PLL_DSMPD_MASK BIT(9)
#define PLL_DSMPD_SHIFT 9
#define PLL_DSMPD(x) HIWORD_UPDATE(x, 9, 9)
#define PLL_POSTDIV2(x) HIWORD_UPDATE(x, 8, 6)
#define PLL_POSTDIV2_MASK GENMASK(8, 6)
#define PLL_POSTDIV2_SHIFT 6
@@ -61,6 +55,9 @@ struct clk_regmap_pll {
struct device *dev;
struct regmap *regmap;
unsigned int reg;
u8 pd_shift;
u8 dsmpd_shift;
u8 lock_shift;
};
#define to_clk_regmap_pll(_hw) container_of(_hw, struct clk_regmap_pll, hw)
@@ -80,7 +77,7 @@ clk_regmap_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
bypass = (con0 & PLL_BYPASS_MASK) >> PLL_BYPASS_SHIFT;
postdiv1 = (con0 & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
fbdiv = (con0 & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
dsmpd = (con1 & PLL_DSMPD_MASK) >> PLL_DSMPD_SHIFT;
dsmpd = (con1 & BIT(pll->dsmpd_shift)) >> pll->dsmpd_shift;
postdiv2 = (con1 & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
refdiv = (con1 & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
frac = (con2 & PLL_FRAC_MASK) >> PLL_FRAC_SHIFT;
@@ -274,8 +271,8 @@ clk_regmap_pll_set_rate(struct clk_hw *hw, unsigned long drate,
PLL_BYPASS(0) | PLL_POSTDIV1(postdiv1) |
PLL_FBDIV(fbdiv));
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(1),
PLL_DSMPD(dsmpd) | PLL_POSTDIV2(postdiv2) |
PLL_REFDIV(refdiv));
HIWORD_UPDATE(dsmpd, pll->dsmpd_shift, pll->dsmpd_shift) |
PLL_POSTDIV2(postdiv2) | PLL_REFDIV(refdiv));
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(2),
PLL_FRAC(frac));
@@ -294,11 +291,12 @@ static int clk_regmap_pll_prepare(struct clk_hw *hw)
u32 v;
int ret;
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(1), PLL_POWER_UP);
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(1),
HIWORD_UPDATE(0, pll->pd_shift, pll->pd_shift));
ret = regmap_read_poll_timeout(pll->regmap,
pll->reg + PLLCON_OFFSET(1),
v, v & PLL_LOCK, 50, 50000);
v, v & BIT(pll->lock_shift), 50, 50000);
if (ret)
dev_err(pll->dev, "%s is not lock\n", clk_hw_get_name(hw));
@@ -309,7 +307,8 @@ static void clk_regmap_pll_unprepare(struct clk_hw *hw)
{
struct clk_regmap_pll *pll = to_clk_regmap_pll(hw);
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(1), PLL_POWER_DOWN);
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(1),
HIWORD_UPDATE(1, pll->pd_shift, pll->pd_shift));
}
static int clk_regmap_pll_is_prepared(struct clk_hw *hw)
@@ -319,14 +318,7 @@ static int clk_regmap_pll_is_prepared(struct clk_hw *hw)
regmap_read(pll->regmap, pll->reg + PLLCON_OFFSET(1), &con1);
return !(con1 & PLL_POWER_DOWN);
}
static void clk_regmap_pll_init(struct clk_hw *hw)
{
struct clk_regmap_pll *pll = to_clk_regmap_pll(hw);
regmap_write(pll->regmap, pll->reg + PLLCON_OFFSET(0), PLL_BYPASS(1));
return !(con1 & BIT(pll->pd_shift));
}
static const struct clk_ops clk_regmap_pll_ops = {
@@ -336,13 +328,13 @@ static const struct clk_ops clk_regmap_pll_ops = {
.prepare = clk_regmap_pll_prepare,
.unprepare = clk_regmap_pll_unprepare,
.is_prepared = clk_regmap_pll_is_prepared,
.init = clk_regmap_pll_init,
};
struct clk *
devm_clk_regmap_register_pll(struct device *dev, const char *name,
const char *parent_name,
struct regmap *regmap, u32 reg,
struct regmap *regmap, u32 reg, u8 pd_shift,
u8 dsmpd_shift, u8 lock_shift,
unsigned long flags)
{
struct clk_regmap_pll *pll;
@@ -361,6 +353,9 @@ devm_clk_regmap_register_pll(struct device *dev, const char *name,
pll->dev = dev;
pll->regmap = regmap;
pll->reg = reg;
pll->pd_shift = pd_shift;
pll->dsmpd_shift = dsmpd_shift;
pll->lock_shift = lock_shift;
pll->hw.init = &init;
return devm_clk_register(dev, &pll->hw);

View File

@@ -31,18 +31,28 @@ struct clk_pll_data {
const char *name;
const char *parent_name;
u32 reg;
u8 pd_shift;
u8 dsmpd_shift;
u8 lock_shift;
unsigned long flags;
};
#define PLL(_id, _name, _parent_name, _reg, _flags) \
#define PLL(_id, _name, _parent_name, _reg, _pd_shift, _dsmpd_shift, \
_lock_shift, _flags) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _parent_name, \
.reg = _reg, \
.pd_shift = _pd_shift, \
.dsmpd_shift = _dsmpd_shift, \
.lock_shift = _lock_shift, \
.flags = _flags, \
}
#define RK618_PLL(_id, _name, _parent_name, _reg, _flags) \
PLL(_id, _name, _parent_name, _reg, 10, 9, 15, _flags)
struct clk_mux_data {
unsigned int id;
const char *name;
@@ -225,7 +235,8 @@ extern const struct clk_ops clk_regmap_fractional_divider_ops;
struct clk *
devm_clk_regmap_register_pll(struct device *dev, const char *name,
const char *parent_name,
struct regmap *regmap, u32 reg,
struct regmap *regmap, u32 reg, u8 pd_shift,
u8 dsmpd_shift, u8 lock_shift,
unsigned long flags);
struct clk *

View File

@@ -79,12 +79,12 @@ PNAME(mux_codec_src_p) = { "codec_pre_clk", clkin_name };
/* Two PLL, one for dual datarate input logic, the other for scaler */
static const struct clk_pll_data rk618_clk_plls[] = {
PLL(VIF_PLL_CLK, "vif_pll_clk", "vif_pllin_clk",
RK618_CRU_PLL0_CON0,
0),
PLL(SCALER_PLL_CLK, "scaler_pll_clk", "scaler_pllin_clk",
RK618_CRU_PLL1_CON0,
0),
RK618_PLL(VIF_PLL_CLK, "vif_pll_clk", "vif_pllin_clk",
RK618_CRU_PLL0_CON0,
0),
RK618_PLL(SCALER_PLL_CLK, "scaler_pll_clk", "scaler_pllin_clk",
RK618_CRU_PLL1_CON0,
0),
};
static const struct clk_mux_data rk618_clk_muxes[] = {
@@ -281,7 +281,11 @@ static void rk618_clk_register_plls(struct rk618_cru *cru)
clk = devm_clk_regmap_register_pll(cru->dev, data->name,
data->parent_name,
cru->regmap, data->reg,
cru->regmap,
data->reg,
data->pd_shift,
data->dsmpd_shift,
data->lock_shift,
data->flags);
if (IS_ERR(clk)) {
dev_err(cru->dev, "failed to register clock %s\n",