int genclk_set_parent(struct clk *clk, struct clk *parent) { u32 control; dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n", clk->name, parent->name, clk->parent->name); control = pm_readl(GCCTRL(clk->index)); if (parent == &osc1 || parent == &pll1) control |= PM_BIT(OSCSEL); else if (parent == &osc0 || parent == &pll0) control &= ~PM_BIT(OSCSEL); else return -EINVAL; if (parent == &pll0 || parent == &pll1) control |= PM_BIT(PLLSEL); else control &= ~PM_BIT(PLLSEL); pm_writel(GCCTRL(clk->index), control); clk->parent = parent; return 0; }
static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply) { u32 control; unsigned long parent_rate, actual_rate, div; parent_rate = clk->parent->get_rate(clk->parent); control = pm_readl(GCCTRL(clk->index)); if (rate > 3 * parent_rate / 4) { actual_rate = parent_rate; control &= ~PM_BIT(DIVEN); } else { div = (parent_rate + rate) / (2 * rate) - 1; control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN); actual_rate = parent_rate / (2 * (div + 1)); } dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n", clk->name, rate, actual_rate); if (apply) pm_writel(GCCTRL(clk->index), control); return actual_rate; }
static void genclk_mode(struct clk *clk, int enabled) { u32 control; control = pm_readl(GCCTRL(clk->index)); if (enabled) control |= PM_BIT(CEN); else control &= ~PM_BIT(CEN); pm_writel(GCCTRL(clk->index), control); }
static int clk_show(struct seq_file *s, void *unused) { struct clkinf r; int i; /* show all the power manager registers */ seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL)); seq_printf(s, "CKSEL = %8x\n", pm_readl(CKSEL)); seq_printf(s, "CPUMASK = %8x\n", pm_readl(CPU_MASK)); seq_printf(s, "HSBMASK = %8x\n", pm_readl(HSB_MASK)); seq_printf(s, "PBAMASK = %8x\n", pm_readl(PBA_MASK)); seq_printf(s, "PBBMASK = %8x\n", pm_readl(PBB_MASK)); seq_printf(s, "PLL0 = %8x\n", pm_readl(PLL0)); seq_printf(s, "PLL1 = %8x\n", pm_readl(PLL1)); seq_printf(s, "IMR = %8x\n", pm_readl(IMR)); for (i = 0; i < 8; i++) { if (i == 5) continue; seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i))); } seq_printf(s, "\n"); /* show clock tree as derived from the three oscillators * we "know" are at the head of the list */ r.s = s; r.nest = 0; dump_clock(at32_clock_list[0], &r); dump_clock(at32_clock_list[1], &r); dump_clock(at32_clock_list[2], &r); return 0; }
static unsigned long genclk_get_rate(struct clk *clk) { u32 control; unsigned long div = 1; control = pm_readl(GCCTRL(clk->index)); if (control & PM_BIT(DIVEN)) div = 2 * (PM_BFEXT(DIV, control) + 1); return clk->parent->get_rate(clk->parent) / div; }
static void __init genclk_init_parent(struct clk *clk) { u32 control; struct clk *parent; BUG_ON(clk->index > 7); control = pm_readl(GCCTRL(clk->index)); if (control & PM_BIT(OSCSEL)) parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1; else parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0; clk->parent = parent; }