mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
clk: clk-rp1: Add "varsrc" clocks to represent MIPI byte clocks
Add a new class of clocks to RP1 to represent clock sources whose frequency changes at run-time as a side-effect of some other driver. Specifically this is for the two MIPI DSI byte-clock sources. Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
This commit is contained in:
committed by
Dom Cobley
parent
4dbb16ff38
commit
4da5801e66
@@ -394,6 +394,11 @@ struct rp1_clock {
|
||||
unsigned long cached_rate;
|
||||
};
|
||||
|
||||
struct rp1_varsrc {
|
||||
struct clk_hw hw;
|
||||
struct rp1_clockman *clockman;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
struct rp1_clk_change {
|
||||
struct clk_hw *hw;
|
||||
@@ -1414,6 +1419,34 @@ static void rp1_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
|
||||
rp1_debugfs_regset(clockman, 0, regs, i, dentry);
|
||||
}
|
||||
|
||||
static int rp1_varsrc_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long parent_rate)
|
||||
{
|
||||
struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
|
||||
|
||||
/*
|
||||
* "varsrc" exists purely to let clock dividers know the frequency
|
||||
* of an externally-managed clock source (such as MIPI DSI byte-clock)
|
||||
* which may change at run-time as a side-effect of some other driver.
|
||||
*/
|
||||
varsrc->rate = rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
|
||||
|
||||
return varsrc->rate;
|
||||
}
|
||||
|
||||
static long rp1_varsrc_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops rp1_pll_core_ops = {
|
||||
.is_prepared = rp1_pll_core_is_on,
|
||||
.prepare = rp1_pll_core_on,
|
||||
@@ -1464,6 +1497,12 @@ static const struct clk_ops rp1_clk_ops = {
|
||||
.debug_init = rp1_clk_debug_init,
|
||||
};
|
||||
|
||||
static const struct clk_ops rp1_varsrc_ops = {
|
||||
.set_rate = rp1_varsrc_set_rate,
|
||||
.recalc_rate = rp1_varsrc_recalc_rate,
|
||||
.round_rate = rp1_varsrc_round_rate,
|
||||
};
|
||||
|
||||
static bool rp1_clk_is_claimed(const char *name);
|
||||
|
||||
static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
|
||||
@@ -1647,6 +1686,35 @@ static struct clk_hw *rp1_register_clock(struct rp1_clockman *clockman,
|
||||
return &clock->hw;
|
||||
}
|
||||
|
||||
static struct clk_hw *rp1_register_varsrc(struct rp1_clockman *clockman,
|
||||
const void *data)
|
||||
{
|
||||
const char *name = *(char const * const *)data;
|
||||
struct rp1_varsrc *clock;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
memset(&init, 0, sizeof(init));
|
||||
init.parent_names = &ref_clock;
|
||||
init.num_parents = 1;
|
||||
init.name = name;
|
||||
init.flags = CLK_IGNORE_UNUSED;
|
||||
init.ops = &rp1_varsrc_ops;
|
||||
|
||||
clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return NULL;
|
||||
|
||||
clock->clockman = clockman;
|
||||
clock->hw.init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(clockman->dev, &clock->hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return &clock->hw;
|
||||
}
|
||||
|
||||
struct rp1_clk_desc {
|
||||
struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
|
||||
const void *data);
|
||||
@@ -1676,6 +1744,8 @@ struct rp1_clk_desc {
|
||||
&(struct rp1_clock_data) \
|
||||
{__VA_ARGS__})
|
||||
|
||||
#define REGISTER_VARSRC(n) _REGISTER(&rp1_register_varsrc, &(const char *){n})
|
||||
|
||||
static const struct rp1_clk_desc clk_desc_array[] = {
|
||||
[RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(
|
||||
.name = "pll_sys_core",
|
||||
@@ -2318,6 +2388,9 @@ static const struct rp1_clk_desc clk_desc_array[] = {
|
||||
.max_freq = 200 * MHz,
|
||||
.fc0_src = FC_NUM(3, 6),
|
||||
),
|
||||
|
||||
[RP1_CLK_MIPI0_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi0_dsi_byteclk"),
|
||||
[RP1_CLK_MIPI1_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi1_dsi_byteclk"),
|
||||
};
|
||||
|
||||
static bool rp1_clk_claimed[ARRAY_SIZE(clk_desc_array)];
|
||||
|
||||
Reference in New Issue
Block a user