Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102943223
D27831.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D27831.diff
View Options
diff --git a/sys/arm64/rockchip/clk/rk3328_cru.c b/sys/arm64/rockchip/clk/rk3328_cru.c
--- a/sys/arm64/rockchip/clk/rk3328_cru.c
+++ b/sys/arm64/rockchip/clk/rk3328_cru.c
@@ -56,6 +56,11 @@
/* 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 @@
#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 @@
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 @@
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 @@
/* 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 @@
.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 @@
.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
diff --git a/sys/arm64/rockchip/clk/rk3399_cru.c b/sys/arm64/rockchip/clk/rk3399_cru.c
--- a/sys/arm64/rockchip/clk/rk3399_cru.c
+++ b/sys/arm64/rockchip/clk/rk3399_cru.c
@@ -964,19 +964,19 @@
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),
diff --git a/sys/arm64/rockchip/clk/rk_clk_fract.h b/sys/arm64/rockchip/clk/rk_clk_fract.h
--- a/sys/arm64/rockchip/clk/rk_clk_fract.h
+++ b/sys/arm64/rockchip/clk/rk_clk_fract.h
@@ -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);
diff --git a/sys/arm64/rockchip/clk/rk_clk_fract.c b/sys/arm64/rockchip/clk/rk_clk_fract.c
--- a/sys/arm64/rockchip/clk/rk_clk_fract.c
+++ b/sys/arm64/rockchip/clk/rk_clk_fract.c
@@ -49,21 +49,27 @@
#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 @@
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 @@
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);
diff --git a/sys/arm64/rockchip/clk/rk_clk_mux.h b/sys/arm64/rockchip/clk/rk_clk_mux.h
--- a/sys/arm64/rockchip/clk/rk_clk_mux.h
+++ b/sys/arm64/rockchip/clk/rk_clk_mux.h
@@ -41,6 +41,7 @@
};
#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);
diff --git a/sys/arm64/rockchip/clk/rk_clk_mux.c b/sys/arm64/rockchip/clk/rk_clk_mux.c
--- a/sys/arm64/rockchip/clk/rk_clk_mux.c
+++ b/sys/arm64/rockchip/clk/rk_clk_mux.c
@@ -55,8 +55,17 @@
#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 @@
/* 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 @@
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)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 20, 1:22 AM (22 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14727052
Default Alt Text
D27831.diff (13 KB)
Attached To
Mode
D27831: rockchip: add audio-related clocks to the CRU driver
Attached
Detach File
Event Timeline
Log In to Comment