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);
}
Exemple #2
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);
}
Exemple #4
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, &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);
}
Exemple #8
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);
}
Exemple #9
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);
}
Exemple #10
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);
}