/* Get the CCU clock rate */ static unsigned long ccu_clk_get_rate(struct clk *c) { struct ccu_clock *ccu_clk = to_ccu_clk(c); debug("%s: %s\n", __func__, c->name); c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id]; return c->rate; }
/* Get the rate of a bus clock */ static unsigned long bus_clk_get_rate(struct clk *c) { struct bus_clock *bus_clk = to_bus_clk(c); struct ccu_clock *ccu_clk; debug("%s: %s\n", __func__, c->name); ccu_clk = to_ccu_clk(c->parent); c->rate = bus_clk->freq_tbl[ccu_clk->freq_id]; c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate; return c->rate; }
static int switch_arm_pll(int freq_id, int policy) { struct opp_info opp_info; struct clk *clk; struct ccu_clk *ccu_clk; clk = clk_get(NULL, KPROC_CCU_CLK_NAME_STR); if (IS_ERR_OR_NULL(clk)) return -EINVAL; ccu_clk = to_ccu_clk(clk); opp_info.freq_id = freq_id; return ccu_set_freq_policy(ccu_clk, CCU_POLICY(policy), &opp_info); }
static int switch_arm_pll(int freq_id, int policy) { int ret = 0; struct opp_info opp_info; struct clk *clk; struct ccu_clk *ccu_clk; clk = clk_get(NULL, KPROC_CCU_CLK_NAME_STR); if (IS_ERR_OR_NULL(clk)) { ret = -EINVAL; goto out; } ccu_clk = to_ccu_clk(clk); opp_info.freq_id = freq_id; opp_info.ctrl_prms = CCU_POLICY_FREQ_REG_INIT; ret = ccu_set_freq_policy(ccu_clk, CCU_POLICY(policy), &opp_info); out: return ret; }
/* Enable a CCU clock */ static int ccu_clk_enable(struct clk *c, int enable) { struct ccu_clock *ccu_clk = to_ccu_clk(c); void *base = (void *)c->ccu_clk_mgr_base; int ret = 0; u32 reg; debug("%s: %s\n", __func__, c->name); if (!enable) return -EINVAL; /* CCU clock cannot shutdown */ /* enable access */ writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET); /* config enable for policy engine */ writel(1, base + ccu_clk->lvm_en_offset); /* wait for bit to go to 0 */ ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0); if (ret) return ret; /* freq ID */ if (!ccu_clk->freq_bit_shift) ccu_clk->freq_bit_shift = 8; /* Set frequency id for each of the 4 policies */ reg = ccu_clk->freq_id | (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) | (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) | (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3)); writel(reg, base + ccu_clk->policy_freq_offset); /* enable all clock mask */ writel(0x7fffffff, base + ccu_clk->policy0_mask_offset); writel(0x7fffffff, base + ccu_clk->policy1_mask_offset); writel(0x7fffffff, base + ccu_clk->policy2_mask_offset); writel(0x7fffffff, base + ccu_clk->policy3_mask_offset); if (ccu_clk->num_policy_masks == 2) { writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset); writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset); writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset); writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset); } /* start policy engine */ reg = readl(base + ccu_clk->policy_ctl_offset); reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL); writel(reg, base + ccu_clk->policy_ctl_offset); /* wait till started */ ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0); if (ret) return ret; /* disable access */ writel(0, base + WR_ACCESS_OFFSET); return ret; }