allwinner: nkmp: Add MUX capability
Some NKMP clocks have a mux options. Add the capability to aw_clk_nkmp.
This commit is contained in:
parent
755fb5b45d
commit
bf7132992c
@ -219,6 +219,48 @@ aw_clk_factor_get_value(struct aw_clk_factor *factor, uint32_t raw)
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
#define NKMP_CLK_WITH_MUX(_clkname, \
|
||||
_id, _name, _pnames, \
|
||||
_offset, \
|
||||
_n_shift, _n_width, _n_value, _n_flags, \
|
||||
_k_shift, _k_width, _k_value, _k_flags, \
|
||||
_m_shift, _m_width, _m_value, _m_flags, \
|
||||
_p_shift, _p_width, _p_value, _p_flags, \
|
||||
_mux_shift, _mux_width, _gate, \
|
||||
_lock, _lock_retries, \
|
||||
_flags) \
|
||||
static struct aw_clk_nkmp_def _clkname = { \
|
||||
.clkdef = { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_names = _pnames, \
|
||||
.parent_cnt = nitems(_pnames), \
|
||||
}, \
|
||||
.offset = _offset, \
|
||||
.n.shift = _n_shift, \
|
||||
.n.width = _n_width, \
|
||||
.n.value = _n_value, \
|
||||
.n.flags = _n_flags, \
|
||||
.k.shift = _k_shift, \
|
||||
.k.width = _k_width, \
|
||||
.k.value = _k_value, \
|
||||
.k.flags = _k_flags, \
|
||||
.m.shift = _m_shift, \
|
||||
.m.width = _m_width, \
|
||||
.m.value = _m_value, \
|
||||
.m.flags = _m_flags, \
|
||||
.p.shift = _p_shift, \
|
||||
.p.width = _p_width, \
|
||||
.p.value = _p_value, \
|
||||
.p.flags = _p_flags, \
|
||||
.mux_shift = _mux_shift, \
|
||||
.mux_width = _mux_width, \
|
||||
.gate_shift = _gate, \
|
||||
.lock_shift = _lock, \
|
||||
.lock_retries = _lock_retries, \
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
#define NKMP_CLK_WITH_UPDATE(_clkname, \
|
||||
_id, _name, _pnames, \
|
||||
_offset, \
|
||||
|
@ -55,6 +55,8 @@ struct aw_clk_nkmp_sc {
|
||||
struct aw_clk_factor m;
|
||||
struct aw_clk_factor p;
|
||||
|
||||
uint32_t mux_shift;
|
||||
uint32_t mux_mask;
|
||||
uint32_t gate_shift;
|
||||
uint32_t lock_shift;
|
||||
uint32_t lock_retries;
|
||||
@ -77,7 +79,21 @@ struct aw_clk_nkmp_sc {
|
||||
static int
|
||||
aw_clk_nkmp_init(struct clknode *clk, device_t dev)
|
||||
{
|
||||
clknode_init_parent_idx(clk, 0);
|
||||
struct aw_clk_nkmp_sc *sc;
|
||||
uint32_t val, idx;
|
||||
|
||||
sc = clknode_get_softc(clk);
|
||||
|
||||
idx = 0;
|
||||
if ((sc->flags & AW_CLK_HAS_MUX) != 0) {
|
||||
DEVICE_LOCK(clk);
|
||||
READ4(clk, sc->offset, &val);
|
||||
DEVICE_UNLOCK(clk);
|
||||
|
||||
idx = (val & sc->mux_mask) >> sc->mux_shift;
|
||||
}
|
||||
|
||||
clknode_init_parent_idx(clk, idx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -104,6 +120,27 @@ aw_clk_nkmp_set_gate(struct clknode *clk, bool enable)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
aw_clk_nkmp_set_mux(struct clknode *clk, int index)
|
||||
{
|
||||
struct aw_clk_nkmp_sc *sc;
|
||||
uint32_t val;
|
||||
|
||||
sc = clknode_get_softc(clk);
|
||||
|
||||
if ((sc->flags & AW_CLK_HAS_MUX) != 0)
|
||||
return (0);
|
||||
|
||||
DEVICE_LOCK(clk);
|
||||
READ4(clk, sc->offset, &val);
|
||||
val &= ~(sc->mux_mask >> sc->mux_shift);
|
||||
val |= index << sc->mux_shift;
|
||||
WRITE4(clk, sc->offset, val);
|
||||
DEVICE_UNLOCK(clk);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
aw_clk_nkmp_find_best(struct aw_clk_nkmp_sc *sc, uint64_t fparent, uint64_t *fout,
|
||||
uint32_t *factor_n, uint32_t *factor_k, uint32_t *factor_m, uint32_t *factor_p)
|
||||
@ -314,6 +351,7 @@ static clknode_method_t aw_nkmp_clknode_methods[] = {
|
||||
/* Device interface */
|
||||
CLKNODEMETHOD(clknode_init, aw_clk_nkmp_init),
|
||||
CLKNODEMETHOD(clknode_set_gate, aw_clk_nkmp_set_gate),
|
||||
CLKNODEMETHOD(clknode_set_mux, aw_clk_nkmp_set_mux),
|
||||
CLKNODEMETHOD(clknode_recalc_freq, aw_clk_nkmp_recalc),
|
||||
CLKNODEMETHOD(clknode_set_freq, aw_clk_nkmp_set_freq),
|
||||
CLKNODEMETHOD_END
|
||||
@ -360,6 +398,9 @@ aw_clk_nkmp_register(struct clkdom *clkdom, struct aw_clk_nkmp_def *clkdef)
|
||||
sc->p.value = clkdef->p.value;
|
||||
sc->p.flags = clkdef->p.flags;
|
||||
|
||||
sc->mux_shift = clkdef->mux_shift;
|
||||
sc->mux_mask = ((1 << clkdef->mux_width) - 1) << sc->mux_shift;
|
||||
|
||||
sc->gate_shift = clkdef->gate_shift;
|
||||
sc->lock_shift = clkdef->lock_shift;
|
||||
sc->lock_retries = clkdef->lock_retries;
|
||||
|
@ -41,6 +41,8 @@ struct aw_clk_nkmp_def {
|
||||
struct aw_clk_factor n;
|
||||
struct aw_clk_factor p;
|
||||
|
||||
uint32_t mux_shift;
|
||||
uint32_t mux_width;
|
||||
uint32_t gate_shift;
|
||||
uint32_t lock_shift;
|
||||
uint32_t lock_retries;
|
||||
|
Loading…
x
Reference in New Issue
Block a user