Author: manu
Date: Tue Feb 28 15:11:33 2017
New Revision: 314393
URL: https://svnweb.freebsd.org/changeset/base/314393

Log:
  allwinner: nkmp: Add MUX capability
  
  Some NKMP clocks have a mux options.
  Add the capability to aw_clk_nkmp.

Modified:
  head/sys/arm/allwinner/clkng/aw_clk.h
  head/sys/arm/allwinner/clkng/aw_clk_nkmp.c
  head/sys/arm/allwinner/clkng/aw_clk_nkmp.h

Modified: head/sys/arm/allwinner/clkng/aw_clk.h
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk.h       Tue Feb 28 15:03:34 2017        
(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk.h       Tue Feb 28 15:11:33 2017        
(r314393)
@@ -219,6 +219,48 @@ aw_clk_factor_get_value(struct aw_clk_fa
                .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,                                             \

Modified: head/sys/arm/allwinner/clkng/aw_clk_nkmp.c
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk_nkmp.c  Tue Feb 28 15:03:34 2017        
(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk_nkmp.c  Tue Feb 28 15:11:33 2017        
(r314393)
@@ -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
        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_
        /* 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 *clkd
        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;

Modified: head/sys/arm/allwinner/clkng/aw_clk_nkmp.h
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk_nkmp.h  Tue Feb 28 15:03:34 2017        
(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk_nkmp.h  Tue Feb 28 15:11:33 2017        
(r314393)
@@ -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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to