static long branch_clk_list_rate(struct clk *c, unsigned n) { int level, fmax = 0, rate; struct branch_clk *branch = to_branch_clk(c); struct clk *parent = c->parent; if (branch->has_sibling == 1) return -ENXIO; if (!parent || !parent->ops->list_rate) return -ENXIO; if (!parent->vdd_class) { fmax = INT_MAX; } else { for (level = 0; level < parent->num_fmax; level++) if (parent->fmax[level]) fmax = parent->fmax[level]; } rate = parent->ops->list_rate(parent, n); if (rate <= fmax) return rate; else return -ENXIO; }
static int branch_clk_list_rate(struct clk *c, unsigned n) { int level, fmax = 0, rate; struct branch_clk *branch = to_branch_clk(c); struct clk *parent = c->parent; if (branch->has_sibling == 1) return -ENXIO; if (!parent || !parent->ops->list_rate) return -ENXIO; /* Find max frequency supported within voltage constraints. */ if (!parent->vdd_class) { fmax = INT_MAX; } else { for (level = 0; level < parent->num_fmax; level++) if (parent->fmax[level]) fmax = parent->fmax[level]; } rate = parent->ops->list_rate(parent, n); if (rate <= fmax) return rate; else return -ENXIO; }
static unsigned long branch_clk_get_rate(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); if (branch->max_div) return branch->c.rate; return clk_get_rate(c->parent); }
/* Branch clock set rate */ int clock_lib2_branch_set_rate(struct clk *c, unsigned rate) { struct branch_clk *branch = to_branch_clk(c); if (!branch->has_sibling) return clk_set_rate(branch->parent, rate); return -1; }
/* * Branch clocks functions */ int branch_clk_enable(struct clk *clk) { struct branch_clk *branch = to_branch_clk(clk); __branch_clk_enable_reg(&branch->b, branch->c.dbg_name); branch->enabled = true; return 0; }
int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action) { struct branch_clk *bclk = to_branch_clk(c); if (!bclk) return 0; return __clock_lib2_branch_clk_reset(bclk->bcr_reg, action); }
static int branch_clk_reset(struct clk *c, enum clk_reset_action action) { struct branch_clk *branch = to_branch_clk(c); if (!branch->bcr_reg) { WARN("clk_reset called on an unsupported clock (%s)\n", c->dbg_name); return -EPERM; } return __branch_clk_reset(BCR_REG(branch), action); }
static int branch_clk_set_rate(struct clk *c, unsigned long rate) { struct branch_clk *branch = to_branch_clk(c); if (branch->max_div) return branch_cdiv_set_rate(branch, rate); if (!branch->has_sibling) return clk_set_rate(c->parent, rate); return -EPERM; }
static int branch_clk_list_rate(struct clk *c, unsigned n) { struct branch_clk *branch = to_branch_clk(c); if (branch->has_sibling == 1) return -ENXIO; if (branch->parent) return rcg_clk_list_rate(branch->parent, n); else return 0; }
/* Branch clock disable */ void clock_lib2_branch_clk_disable(struct clk *clk) { uint32_t cbcr_val; struct branch_clk *bclk = to_branch_clk(clk); cbcr_val = readl(bclk->cbcr_reg); cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT; writel(cbcr_val, bclk->cbcr_reg); /* wait until status shows it is disabled */ while(!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT)); }
static long branch_clk_round_rate(struct clk *c, unsigned long rate) { struct branch_clk *branch = to_branch_clk(c); if (branch->max_div) return rate <= (branch->max_div) ? rate : -EPERM; if (!branch->has_sibling) return clk_round_rate(c->parent, rate); return -EPERM; }
static unsigned long branch_clk_get_rate(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); if (branch->max_div) return branch->c.rate; if (!branch->has_sibling) return clk_get_rate(branch->parent); return 0; }
static enum handoff branch_clk_handoff(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); u32 cbcr_regval; cbcr_regval = readl_relaxed(CBCR_REG(branch)); if ((cbcr_regval & CBCR_BRANCH_OFF_BIT)) return HANDOFF_DISABLED_CLK; if (branch->max_div) { cbcr_regval &= BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB); cbcr_regval >>= CBCR_CDIV_LSB; c->rate = cbcr_regval; } else if (!branch->has_sibling) {
/* Branch clock enable */ int clock_lib2_branch_clk_enable(struct clk *clk) { int rc = 0; uint32_t cbcr_val; struct branch_clk *bclk = to_branch_clk(clk); cbcr_val = readl(bclk->cbcr_reg); cbcr_val |= CBCR_BRANCH_ENABLE_BIT; writel(cbcr_val, bclk->cbcr_reg); /* wait until status shows it is enabled */ while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT); return rc; }
static enum handoff branch_clk_handoff(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); u32 cbcr_regval; cbcr_regval = readl_relaxed(CBCR_REG(branch)); if ((cbcr_regval & CBCR_BRANCH_OFF_BIT)) return HANDOFF_DISABLED_CLK; if (c->parent) { if (c->parent->ops->handoff) return c->parent->ops->handoff(c->parent); } return HANDOFF_ENABLED_CLK; }
static void branch_clk_disable(struct clk *c) { unsigned long flags; struct branch_clk *branch = to_branch_clk(c); u32 reg_val; spin_lock_irqsave(&local_clock_reg_lock, flags); reg_val = readl_relaxed(CBCR_REG(branch)); reg_val &= ~CBCR_BRANCH_ENABLE_BIT; writel_relaxed(reg_val, CBCR_REG(branch)); spin_unlock_irqrestore(&local_clock_reg_lock, flags); /* Wait for clock to disable before continuing. */ branch_clk_halt_check(branch->halt_check, branch->c.dbg_name, CBCR_REG(branch), BRANCH_OFF); }
static enum handoff branch_clk_handoff(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); u32 cbcr_regval; cbcr_regval = readl_relaxed(CBCR_REG(branch)); if ((cbcr_regval & CBCR_BRANCH_OFF_BIT)) return HANDOFF_DISABLED_CLK; pr_info("%s enabled.\n", branch->c.dbg_name); if (branch->parent) { if (branch->parent->ops->handoff) return branch->parent->ops->handoff(branch->parent); } return HANDOFF_ENABLED_CLK; }
static int branch_clk_enable(struct clk *c) { unsigned long flags; u32 cbcr_val; struct branch_clk *branch = to_branch_clk(c); spin_lock_irqsave(&local_clock_reg_lock, flags); cbcr_val = readl_relaxed(CBCR_REG(branch)); cbcr_val |= CBCR_BRANCH_ENABLE_BIT; writel_relaxed(cbcr_val, CBCR_REG(branch)); spin_unlock_irqrestore(&local_clock_reg_lock, flags); /* Wait for clock to enable before continuing. */ branch_clk_halt_check(branch->halt_check, branch->c.dbg_name, CBCR_REG(branch), BRANCH_ON); return 0; }
static int branch_clk_reset(struct clk *c, enum clk_reset_action action) { struct branch_clk *branch = to_branch_clk(c); return __branch_clk_reset(BCR_REG(branch), action, c->dbg_name); }
struct clk *branch_clk_get_parent(struct clk *clk) { struct branch_clk *branch = to_branch_clk(clk); return branch->parent; }
int branch_clk_is_enabled(struct clk *clk) { struct branch_clk *branch = to_branch_clk(clk); return branch->enabled; }
static struct clk *branch_clk_get_parent(struct clk *c) { return to_branch_clk(c)->parent; }