Merge "clk: qcom: Add support for gfx clock to ping pong PLLs"
This commit is contained in:
commit
3ea0533e23
2 changed files with 80 additions and 0 deletions
|
@ -23,6 +23,7 @@ struct freq_tbl {
|
||||||
u8 pre_div;
|
u8 pre_div;
|
||||||
u16 m;
|
u16 m;
|
||||||
u16 n;
|
u16 n;
|
||||||
|
unsigned long src_freq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,5 +185,6 @@ extern const struct clk_ops clk_byte_ops;
|
||||||
extern const struct clk_ops clk_byte2_ops;
|
extern const struct clk_ops clk_byte2_ops;
|
||||||
extern const struct clk_ops clk_pixel_ops;
|
extern const struct clk_ops clk_pixel_ops;
|
||||||
extern const struct clk_ops clk_gfx3d_ops;
|
extern const struct clk_ops clk_gfx3d_ops;
|
||||||
|
extern const struct clk_ops clk_gfx3d_src_ops;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
@ -865,3 +866,80 @@ const struct clk_ops clk_gfx3d_ops = {
|
||||||
.determine_rate = clk_gfx3d_determine_rate,
|
.determine_rate = clk_gfx3d_determine_rate,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
|
EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
|
||||||
|
|
||||||
|
static int clk_gfx3d_src_determine_rate(struct clk_hw *hw,
|
||||||
|
struct clk_rate_request *req)
|
||||||
|
{
|
||||||
|
struct clk_rate_request parent_req = { };
|
||||||
|
struct clk_hw *p1, *p3, *xo, *curr_p;
|
||||||
|
const struct freq_tbl *f;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
xo = clk_hw_get_parent_by_index(hw, 0);
|
||||||
|
if (req->rate == clk_hw_get_rate(xo)) {
|
||||||
|
req->best_parent_hw = xo;
|
||||||
|
req->best_parent_rate = req->rate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = qcom_find_freq(rcg->freq_tbl, req->rate);
|
||||||
|
if (!f || (req->rate != f->freq))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Indexes of source from the parent map */
|
||||||
|
p1 = clk_hw_get_parent_by_index(hw, 1);
|
||||||
|
p3 = clk_hw_get_parent_by_index(hw, 2);
|
||||||
|
|
||||||
|
curr_p = clk_hw_get_parent(hw);
|
||||||
|
parent_req.rate = f->src_freq;
|
||||||
|
|
||||||
|
if (curr_p == xo || curr_p == p3)
|
||||||
|
req->best_parent_hw = p1;
|
||||||
|
else if (curr_p == p1)
|
||||||
|
req->best_parent_hw = p3;
|
||||||
|
|
||||||
|
parent_req.best_parent_hw = req->best_parent_hw;
|
||||||
|
|
||||||
|
ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
req->best_parent_rate = parent_req.rate;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clk_gfx3d_src_set_rate_and_parent(struct clk_hw *hw,
|
||||||
|
unsigned long rate, unsigned long parent_rate, u8 index)
|
||||||
|
{
|
||||||
|
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||||
|
const struct freq_tbl *f;
|
||||||
|
u32 cfg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||||
|
|
||||||
|
f = qcom_find_freq(rcg->freq_tbl, rate);
|
||||||
|
if (!f)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Update the RCG-DIV */
|
||||||
|
cfg |= f->pre_div << CFG_SRC_DIV_SHIFT;
|
||||||
|
|
||||||
|
ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return update_config(rcg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct clk_ops clk_gfx3d_src_ops = {
|
||||||
|
.is_enabled = clk_rcg2_is_enabled,
|
||||||
|
.get_parent = clk_rcg2_get_parent,
|
||||||
|
.set_parent = clk_rcg2_set_parent,
|
||||||
|
.recalc_rate = clk_rcg2_recalc_rate,
|
||||||
|
.set_rate = clk_gfx3d_set_rate,
|
||||||
|
.set_rate_and_parent = clk_gfx3d_src_set_rate_and_parent,
|
||||||
|
.determine_rate = clk_gfx3d_src_determine_rate,
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(clk_gfx3d_src_ops);
|
||||||
|
|
Loading…
Add table
Reference in a new issue