rockchip: add audio-related clocks to the CRU driver
- Add I2S and CODEC clocks to CRU driver - Add support for gate selection to frac clock - Add setfreq support to mux clock Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D27831
This commit is contained in:
parent
52981a1694
commit
d03fd8ede2
@ -56,6 +56,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/* GATES */
|
||||
|
||||
#define SCLK_I2S0 41
|
||||
#define SCLK_I2S1 42
|
||||
#define SCLK_I2S2 43
|
||||
#define SCLK_I2S1_OUT 44
|
||||
#define SCLK_I2S2_OUT 45
|
||||
#define SCLK_MAC2PHY_RXTX 83
|
||||
#define SCLK_MAC2PHY_SRC 84
|
||||
#define SCLK_MAC2PHY_REF 85
|
||||
@ -90,6 +95,10 @@ __FBSDID("$FreeBSD$");
|
||||
#define PCLK_USB3PHY_OTG 224
|
||||
#define PCLK_USB3PHY_PIPE 225
|
||||
#define PCLK_USB3_GRF 226
|
||||
#define PCLK_ACODECPHY 235
|
||||
#define HCLK_I2S0_8CH 311
|
||||
#define HCLK_I2S1_8CH 312
|
||||
#define HCLK_I2S2_2CH 313
|
||||
#define HCLK_SDMMC 317
|
||||
#define HCLK_SDIO 318
|
||||
#define HCLK_EMMC 319
|
||||
@ -102,6 +111,11 @@ static struct rk_cru_gate rk3328_gates[] = {
|
||||
CRU_GATE(0, "gpll_core", "gpll", 0x200, 2)
|
||||
CRU_GATE(0, "npll_core", "npll", 0x200, 12)
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
CRU_GATE(SCLK_I2S0, "clk_i2s0", "clk_i2s0_mux", 0x204, 3)
|
||||
CRU_GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", 0x204, 6)
|
||||
CRU_GATE(SCLK_I2S1, "clk_i2s2", "clk_i2s2_mux", 0x204, 10)
|
||||
|
||||
/* CRU_CLKGATE_CON4 */
|
||||
CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0)
|
||||
CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1)
|
||||
@ -123,6 +137,9 @@ static struct rk_cru_gate rk3328_gates[] = {
|
||||
CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0)
|
||||
|
||||
/* CRU_CLKGATE_CON15*/
|
||||
CRU_GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0x23C, 3)
|
||||
CRU_GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0x23C, 4)
|
||||
CRU_GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0x23C, 5)
|
||||
CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10)
|
||||
|
||||
/* CRU_CLKGATE_CON16 */
|
||||
@ -138,6 +155,7 @@ static struct rk_cru_gate rk3328_gates[] = {
|
||||
|
||||
/* CRU_CLKGATE_CON17 */
|
||||
CRU_GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", 0x244, 2)
|
||||
CRU_GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", 0x244, 5)
|
||||
|
||||
/* CRU_CLKGATE_CON19 */
|
||||
CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0)
|
||||
@ -1115,6 +1133,215 @@ static struct rk_clk_composite_def ref_usb3otg_src = {
|
||||
.flags = RK_CLK_COMPOSITE_HAVE_GATE,
|
||||
};
|
||||
|
||||
/* I2S0 */
|
||||
static const char *i2s0_div_parents[] = { "cpll", "gpll" };
|
||||
static struct rk_clk_composite_def i2s0_div = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s0_div",
|
||||
.parent_names = i2s0_div_parents,
|
||||
.parent_cnt = nitems(i2s0_div_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON6 */
|
||||
.muxdiv_offset = 0x118,
|
||||
|
||||
.mux_shift = 15,
|
||||
.mux_width = 1,
|
||||
|
||||
.div_shift = 0,
|
||||
.div_width = 7,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 1,
|
||||
|
||||
.flags = RK_CLK_COMPOSITE_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s0_frac_parents[] = { "clk_i2s0_div" };
|
||||
static struct rk_clk_fract_def i2s0_frac = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s0_frac",
|
||||
.parent_names = i2s0_frac_parents,
|
||||
.parent_cnt = nitems(i2s0_frac_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON7 */
|
||||
.offset = 0x11c,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 2,
|
||||
|
||||
.flags = RK_CLK_FRACT_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s0_mux_parents[] = { "clk_i2s0_div", "clk_i2s0_frac", "xin12m", "xin12m" };
|
||||
static struct rk_clk_mux_def i2s0_mux = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s0_mux",
|
||||
.parent_names = i2s0_mux_parents,
|
||||
.parent_cnt = nitems(i2s0_mux_parents),
|
||||
},
|
||||
.offset = 0x118,
|
||||
|
||||
.shift = 8,
|
||||
.width = 2,
|
||||
|
||||
.mux_flags = RK_CLK_MUX_REPARENT,
|
||||
};
|
||||
|
||||
/* I2S1 */
|
||||
static const char *i2s1_div_parents[] = { "cpll", "gpll" };
|
||||
static struct rk_clk_composite_def i2s1_div = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s1_div",
|
||||
.parent_names = i2s1_div_parents,
|
||||
.parent_cnt = nitems(i2s1_div_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON8 */
|
||||
.muxdiv_offset = 0x120,
|
||||
|
||||
.mux_shift = 15,
|
||||
.mux_width = 1,
|
||||
|
||||
.div_shift = 0,
|
||||
.div_width = 7,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 4,
|
||||
|
||||
.flags = RK_CLK_COMPOSITE_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s1_frac_parents[] = { "clk_i2s1_div" };
|
||||
static struct rk_clk_fract_def i2s1_frac = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s1_frac",
|
||||
.parent_names = i2s1_frac_parents,
|
||||
.parent_cnt = nitems(i2s1_frac_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON9 */
|
||||
.offset = 0x124,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 5,
|
||||
|
||||
.flags = RK_CLK_FRACT_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s1_mux_parents[] = { "clk_i2s1_div", "clk_i2s1_frac", "clkin_i2s1", "xin12m" };
|
||||
static struct rk_clk_mux_def i2s1_mux = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s1_mux",
|
||||
.parent_names = i2s1_mux_parents,
|
||||
.parent_cnt = nitems(i2s1_mux_parents),
|
||||
},
|
||||
.offset = 0x120,
|
||||
|
||||
.shift = 8,
|
||||
.width = 2,
|
||||
.mux_flags = RK_CLK_MUX_REPARENT,
|
||||
};
|
||||
|
||||
static struct clk_fixed_def clkin_i2s1 = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clkin_i2s1",
|
||||
.parent_names = NULL,
|
||||
.parent_cnt = 0
|
||||
},
|
||||
|
||||
.freq = 0,
|
||||
};
|
||||
|
||||
/* I2S2 */
|
||||
static const char *i2s2_div_parents[] = { "cpll", "gpll" };
|
||||
static struct rk_clk_composite_def i2s2_div = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s2_div",
|
||||
.parent_names = i2s2_div_parents,
|
||||
.parent_cnt = nitems(i2s2_div_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON10 */
|
||||
.muxdiv_offset = 0x128,
|
||||
|
||||
.mux_shift = 15,
|
||||
.mux_width = 1,
|
||||
|
||||
.div_shift = 0,
|
||||
.div_width = 7,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 8,
|
||||
|
||||
.flags = RK_CLK_COMPOSITE_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s2_frac_parents[] = { "clk_i2s2_div" };
|
||||
static struct rk_clk_fract_def i2s2_frac = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s2_frac",
|
||||
.parent_names = i2s2_frac_parents,
|
||||
.parent_cnt = nitems(i2s2_frac_parents),
|
||||
},
|
||||
/* CRU_CLKSEL_CON11 */
|
||||
.offset = 0x12c,
|
||||
|
||||
/* CRU_CLKGATE_CON1 */
|
||||
.gate_offset = 0x204,
|
||||
.gate_shift = 9,
|
||||
|
||||
.flags = RK_CLK_FRACT_HAVE_GATE,
|
||||
};
|
||||
|
||||
static const char *i2s2_mux_parents[] = { "clk_i2s2_div", "clk_i2s2_frac", "clkin_i2s2", "xin12m" };
|
||||
static struct rk_clk_mux_def i2s2_mux = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clk_i2s2_mux",
|
||||
.parent_names = i2s2_mux_parents,
|
||||
.parent_cnt = nitems(i2s2_mux_parents),
|
||||
},
|
||||
.offset = 0x128,
|
||||
|
||||
.shift = 8,
|
||||
.width = 2,
|
||||
|
||||
.mux_flags = RK_CLK_MUX_REPARENT,
|
||||
};
|
||||
|
||||
static struct clk_fixed_def clkin_i2s2 = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "clkin_i2s2",
|
||||
.parent_names = NULL,
|
||||
.parent_cnt = 0
|
||||
},
|
||||
|
||||
.freq = 0,
|
||||
};
|
||||
|
||||
static struct clk_fixed_def xin12m = {
|
||||
.clkdef = {
|
||||
.id = 0,
|
||||
.name = "xin12m",
|
||||
.parent_names = NULL,
|
||||
.parent_cnt = 0
|
||||
},
|
||||
|
||||
.freq = 12000000,
|
||||
};
|
||||
|
||||
static const char *mac2io_src_parents[] = { "cpll", "gpll" };
|
||||
|
||||
static struct rk_clk_composite_def mac2io_src = {
|
||||
@ -1417,6 +1644,54 @@ static struct rk_clk rk3328_clks[] = {
|
||||
.type = RK_CLK_COMPOSITE,
|
||||
.clk.composite = &usb3otg_suspend
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_COMPOSITE,
|
||||
.clk.composite = &i2s0_div
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FRACT,
|
||||
.clk.fract = &i2s0_frac
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_MUX,
|
||||
.clk.mux = &i2s0_mux
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_COMPOSITE,
|
||||
.clk.composite = &i2s1_div
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FRACT,
|
||||
.clk.fract = &i2s1_frac
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_MUX,
|
||||
.clk.mux = &i2s1_mux
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FIXED,
|
||||
.clk.fixed = &clkin_i2s1
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_COMPOSITE,
|
||||
.clk.composite = &i2s2_div
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FRACT,
|
||||
.clk.fract = &i2s2_frac
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_MUX,
|
||||
.clk.mux = &i2s2_mux
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FIXED,
|
||||
.clk.fixed = &clkin_i2s2
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_FIXED,
|
||||
.clk.fixed = &xin12m
|
||||
},
|
||||
{
|
||||
.type = RK_CLK_COMPOSITE,
|
||||
.clk.composite = &mac2io_src
|
||||
|
@ -964,19 +964,19 @@ static struct rk_clk rk3399_clks[] = {
|
||||
27, 0, 10, 15, 1),
|
||||
|
||||
/* CRU_CLKSEL_CON28 */
|
||||
MUX(0, "clk_i2s0_mux", i2s0_p, 0,
|
||||
MUX(0, "clk_i2s0_mux", i2s0_p, RK_CLK_MUX_REPARENT,
|
||||
28, 8, 2),
|
||||
COMP(0, "clk_i2s0_div_c", pll_src_cpll_gpll_p, 0,
|
||||
28, 0, 7, 7, 1),
|
||||
|
||||
/* CRU_CLKSEL_CON29 */
|
||||
MUX(0, "clk_i2s1_mux", i2s1_p, 0,
|
||||
MUX(0, "clk_i2s1_mux", i2s1_p, RK_CLK_MUX_REPARENT,
|
||||
29, 8, 2),
|
||||
COMP(0, "clk_i2s1_div_c", pll_src_cpll_gpll_p, 0,
|
||||
29, 0, 7, 7, 1),
|
||||
|
||||
/* CRU_CLKSEL_CON30 */
|
||||
MUX(0, "clk_i2s2_mux", i2s2_p, 0,
|
||||
MUX(0, "clk_i2s2_mux", i2s2_p, RK_CLK_MUX_REPARENT,
|
||||
30, 8, 2),
|
||||
COMP(0, "clk_i2s2_div_c", pll_src_cpll_gpll_p, 0,
|
||||
30, 0, 7, 7, 1),
|
||||
|
@ -49,21 +49,27 @@ __FBSDID("$FreeBSD$");
|
||||
#define DEVICE_UNLOCK(_clk) \
|
||||
CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
|
||||
|
||||
#define RK_CLK_FRACT_MASK_SHIFT 16
|
||||
|
||||
static int rk_clk_fract_init(struct clknode *clk, device_t dev);
|
||||
static int rk_clk_fract_recalc(struct clknode *clk, uint64_t *req);
|
||||
static int rk_clk_fract_set_freq(struct clknode *clknode, uint64_t fin,
|
||||
uint64_t *fout, int flag, int *stop);
|
||||
static int rk_clk_fract_set_gate(struct clknode *clk, bool enable);
|
||||
|
||||
struct rk_clk_fract_sc {
|
||||
uint32_t flags;
|
||||
uint32_t offset;
|
||||
uint32_t numerator;
|
||||
uint32_t denominator;
|
||||
uint32_t gate_offset;
|
||||
uint32_t gate_shift;
|
||||
};
|
||||
|
||||
static clknode_method_t rk_clk_fract_methods[] = {
|
||||
/* Device interface */
|
||||
CLKNODEMETHOD(clknode_init, rk_clk_fract_init),
|
||||
CLKNODEMETHOD(clknode_set_gate, rk_clk_fract_set_gate),
|
||||
CLKNODEMETHOD(clknode_recalc_freq, rk_clk_fract_recalc),
|
||||
CLKNODEMETHOD(clknode_set_freq, rk_clk_fract_set_freq),
|
||||
CLKNODEMETHOD_END
|
||||
@ -149,6 +155,33 @@ rk_clk_fract_init(struct clknode *clk, device_t dev)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
rk_clk_fract_set_gate(struct clknode *clk, bool enable)
|
||||
{
|
||||
struct rk_clk_fract_sc *sc;
|
||||
uint32_t val = 0;
|
||||
|
||||
sc = clknode_get_softc(clk);
|
||||
|
||||
if ((sc->flags & RK_CLK_FRACT_HAVE_GATE) == 0)
|
||||
return (0);
|
||||
|
||||
RD4(clk, sc->gate_offset, &val);
|
||||
|
||||
val = 0;
|
||||
if (!enable)
|
||||
val |= 1 << sc->gate_shift;
|
||||
val |= (1 << sc->gate_shift) << RK_CLK_FRACT_MASK_SHIFT;
|
||||
DEVICE_LOCK(clk);
|
||||
WR4(clk, sc->gate_offset, val);
|
||||
DEVICE_UNLOCK(clk);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
rk_clk_fract_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
|
||||
int flags, int *stop);
|
||||
static int
|
||||
rk_clk_fract_recalc(struct clknode *clk, uint64_t *freq)
|
||||
{
|
||||
@ -240,6 +273,8 @@ rk_clk_fract_register(struct clkdom *clkdom, struct rk_clk_fract_def *clkdef)
|
||||
sc = clknode_get_softc(clk);
|
||||
sc->flags = clkdef->flags;
|
||||
sc->offset = clkdef->offset;
|
||||
sc->gate_offset = clkdef->gate_offset;
|
||||
sc->gate_shift = clkdef->gate_shift;
|
||||
|
||||
clknode_register(clkdom, clk);
|
||||
return (0);
|
||||
|
@ -35,9 +35,13 @@
|
||||
struct rk_clk_fract_def {
|
||||
struct clknode_init_def clkdef;
|
||||
uint32_t offset;
|
||||
uint32_t gate_offset;
|
||||
uint32_t gate_shift;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
#define RK_CLK_FRACT_HAVE_GATE 0x0001
|
||||
|
||||
int rk_clk_fract_register(struct clkdom *clkdom,
|
||||
struct rk_clk_fract_def *clkdef);
|
||||
|
||||
|
@ -55,8 +55,17 @@ __FBSDID("$FreeBSD$");
|
||||
#define DEVICE_UNLOCK(_clk) \
|
||||
CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
|
||||
|
||||
#if 0
|
||||
#define dprintf(format, arg...) \
|
||||
printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg)
|
||||
#else
|
||||
#define dprintf(format, arg...)
|
||||
#endif
|
||||
|
||||
static int rk_clk_mux_init(struct clknode *clk, device_t dev);
|
||||
static int rk_clk_mux_set_mux(struct clknode *clk, int idx);
|
||||
static int rk_clk_mux_set_freq(struct clknode *clk, uint64_t fparent,
|
||||
uint64_t *fout, int flags, int *stop);
|
||||
|
||||
struct rk_clk_mux_sc {
|
||||
uint32_t offset;
|
||||
@ -69,6 +78,7 @@ static clknode_method_t rk_clk_mux_methods[] = {
|
||||
/* Device interface */
|
||||
CLKNODEMETHOD(clknode_init, rk_clk_mux_init),
|
||||
CLKNODEMETHOD(clknode_set_mux, rk_clk_mux_set_mux),
|
||||
CLKNODEMETHOD(clknode_set_freq, rk_clk_mux_set_freq),
|
||||
CLKNODEMETHOD_END
|
||||
};
|
||||
DEFINE_CLASS_1(rk_clk_mux, rk_clk_mux_class, rk_clk_mux_methods,
|
||||
@ -116,6 +126,57 @@ rk_clk_mux_set_mux(struct clknode *clk, int idx)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
rk_clk_mux_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
|
||||
int flags, int *stop)
|
||||
{
|
||||
struct rk_clk_mux_sc *sc;
|
||||
struct clknode *p_clk, *p_best_clk;
|
||||
const char **p_names;
|
||||
int p_idx, best_parent;
|
||||
int rv;
|
||||
|
||||
sc = clknode_get_softc(clk);
|
||||
|
||||
if ((sc->mux_flags & RK_CLK_MUX_REPARENT) == 0)
|
||||
return (0);
|
||||
|
||||
dprintf("Finding best parent for target freq of %ju\n", *fout);
|
||||
p_names = clknode_get_parent_names(clk);
|
||||
for (p_idx = 0; p_idx != clknode_get_parents_num(clk); p_idx++) {
|
||||
p_clk = clknode_find_by_name(p_names[p_idx]);
|
||||
dprintf("Testing with parent %s (%d)\n",
|
||||
clknode_get_name(p_clk), p_idx);
|
||||
|
||||
rv = clknode_set_freq(p_clk, *fout, flags | CLK_SET_DRYRUN, 0);
|
||||
dprintf("Testing with parent %s (%d) rv=%d\n",
|
||||
clknode_get_name(p_clk), p_idx, rv);
|
||||
if (rv == 0) {
|
||||
best_parent = p_idx;
|
||||
p_best_clk = p_clk;
|
||||
*stop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*stop)
|
||||
return (0);
|
||||
|
||||
if ((flags & CLK_SET_DRYRUN) != 0)
|
||||
return (0);
|
||||
|
||||
p_idx = clknode_get_parent_idx(clk);
|
||||
if (p_idx != best_parent) {
|
||||
dprintf("Switching parent index from %d to %d\n", p_idx,
|
||||
best_parent);
|
||||
clknode_set_parent_by_idx(clk, best_parent);
|
||||
}
|
||||
|
||||
clknode_set_freq(p_best_clk, *fout, flags, 0);
|
||||
clknode_get_freq(p_best_clk, fout);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rk_clk_mux_register(struct clkdom *clkdom, struct rk_clk_mux_def *clkdef)
|
||||
{
|
||||
|
@ -41,6 +41,7 @@ struct rk_clk_mux_def {
|
||||
};
|
||||
|
||||
#define RK_CLK_MUX_MASK 0xFFFF0000
|
||||
#define RK_CLK_MUX_REPARENT (1 << 0)
|
||||
|
||||
int rk_clk_mux_register(struct clkdom *clkdom, struct rk_clk_mux_def *clkdef);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user