static int jz4780_clk_pll_recalc_freq(struct clknode *clk, uint64_t *freq) { struct jz4780_clk_pll_sc *sc; uint32_t reg, m, n, od; sc = clknode_get_softc(clk); reg = CLK_RD_4(sc, sc->clk_reg); /* Check for PLL enabled status */ if (REG_GET(reg, CGU_PLL_EN) == 0) { *freq = 0; return 0; } /* Return parent frequency if PPL is being bypassed */ if (REG_GET(reg, CGU_PLL_BP) != 0) return 0; m = REG_GET(reg, CGU_PLL_M) + 1; n = REG_GET(reg, CGU_PLL_N) + 1; od = REG_GET(reg, CGU_PLL_OD) + 1; /* Sanity check values */ if (m == 0 || n == 0 || od == 0) { *freq = 0; return (EINVAL); } *freq = ((*freq / n) * m) / od; return (0); }
static int clknode_fixed_init(struct clknode *clk, device_t dev) { struct clknode_fixed_sc *sc; sc = clknode_get_softc(clk); if (sc->freq == 0) clknode_init_parent_idx(clk, 0); return(0); }
static int jz4780_clk_pll_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout, int flags, int *stop) { struct jz4780_clk_pll_sc *sc; uint32_t reg, m, n, od; int rv; sc = clknode_get_softc(clk); /* Should be able to figure all clocks with m & n only */ od = 1; m = MIN((uint32_t)(*fout / MHZ), (1u << CGU_PLL_M_WIDTH)); m = MIN(m, 1); n = MIN((uint32_t)(fin / MHZ), (1u << CGU_PLL_N_WIDTH)); n = MIN(n, 1); if (flags & CLK_SET_DRYRUN) { if (((flags & (CLK_SET_ROUND_UP | CLK_SET_ROUND_DOWN)) == 0) && (*fout != (((fin / n) * m) / od))) return (ERANGE); *fout = ((fin / n) * m) / od; return (0); } CLK_LOCK(sc); reg = CLK_RD_4(sc, sc->clk_reg); /* Set the calculated values */ reg = REG_SET(reg, CGU_PLL_M, m - 1); reg = REG_SET(reg, CGU_PLL_N, n - 1); reg = REG_SET(reg, CGU_PLL_OD, od - 1); /* Enable the PLL */ reg = REG_SET(reg, CGU_PLL_EN, 1); reg = REG_SET(reg, CGU_PLL_BP, 0); /* Initiate the change */ CLK_WR_4(sc, sc->clk_reg, reg); /* Wait for PLL to lock */ rv = jz4780_clk_pll_wait_lock(sc); CLK_UNLOCK(sc); if (rv != 0) return (rv); *fout = ((fin / n) * m) / od; return (0); }
static int clknode_fixed_recalc(struct clknode *clk, uint64_t *freq) { struct clknode_fixed_sc *sc; sc = clknode_get_softc(clk); if ((sc->mult != 0) && (sc->div != 0)) *freq = (*freq / sc->div) * sc->mult; else *freq = sc->freq; return (0); }
static int jz4780_clk_pll_init(struct clknode *clk, device_t dev) { struct jz4780_clk_pll_sc *sc; uint32_t reg; sc = clknode_get_softc(clk); CLK_LOCK(sc); reg = CLK_RD_4(sc, sc->clk_reg); CLK_WR_4(sc, sc->clk_reg, reg); CLK_UNLOCK(sc); clknode_init_parent_idx(clk, 0); return (0); }
static int periph_init(struct clknode *clk, device_t dev) { struct periph_sc *sc; uint32_t reg; sc = clknode_get_softc(clk); DEVICE_LOCK(sc); if (sc->flags & DCF_HAVE_ENA) MD4(sc, sc->base_reg, PERLCK_ENA_MASK, PERLCK_ENA_MASK); RD4(sc, sc->base_reg, ®); DEVICE_UNLOCK(sc); /* Stnadard mux. */ if (sc->flags & DCF_HAVE_MUX) sc->mux = (reg >> PERLCK_MUX_SHIFT) & PERLCK_MUX_MASK; else
int jz4780_clk_pll_register(struct clkdom *clkdom, struct clknode_init_def *clkdef, struct mtx *dev_mtx, struct resource *mem_res, uint32_t mem_reg) { struct clknode *clk; struct jz4780_clk_pll_sc *sc; clk = clknode_create(clkdom, &jz4780_clk_pll_class, clkdef); if (clk == NULL) return (1); sc = clknode_get_softc(clk); sc->clk_mtx = dev_mtx; sc->clk_res = mem_res; sc->clk_reg = mem_reg; clknode_register(clkdom, clk); return (0); }
static int clknode_fixed_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout, int flags, int *stop) { struct clknode_fixed_sc *sc; sc = clknode_get_softc(clk); if (sc->mult == 0 || sc->div == 0) { /* Fixed frequency clock. */ *stop = 1; if (*fout != sc->freq) return (ERANGE); return (0); } /* Fixed factor clock. */ *stop = 0; *fout = (*fout / sc->mult) * sc->div; return (0); }
int clknode_fixed_register(struct clkdom *clkdom, struct clk_fixed_def *clkdef) { struct clknode *clk; struct clknode_fixed_sc *sc; clk = clknode_create(clkdom, &clknode_fixed_class, &clkdef->clkdef); if (clk == NULL) return (1); sc = clknode_get_softc(clk); sc->fixed_flags = clkdef->fixed_flags; sc->freq = clkdef->freq; sc->mult = clkdef->mult; sc->div = clkdef->div; clknode_register(clkdom, clk); return (0); }
int clknode_fixed_register(struct clkdom *clkdom, struct clk_fixed_def *clkdef, struct mtx *dev_mtx) { struct clknode *clk; struct clknode_fixed_sc *sc; if ((clkdef->freq == 0) && (clkdef->clkdef.parent_cnt == 0)) panic("fixed clk: Frequency is not defined for clock source"); clk = clknode_create(clkdom, &clknode_fixed_class, &clkdef->clkdef); if (clk == NULL) return (1); sc = clknode_get_softc(clk); sc->mtx = dev_mtx; sc->fixed_flags = clkdef->fixed_flags; sc->freq = clkdef->freq; sc->mult = clkdef->mult; sc->div = clkdef->div; clknode_register(clkdom, clk); return (0); }