Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167374050
D40712.id123644.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
64 KB
Referenced Files
None
Subscribers
None
D40712.id123644.diff
View Options
Index: sys/arm64/conf/std.rockchip
===================================================================
--- sys/arm64/conf/std.rockchip
+++ sys/arm64/conf/std.rockchip
@@ -6,6 +6,8 @@
options SOC_ROCKCHIP_RK3328
options SOC_ROCKCHIP_RK3399
options SOC_ROCKCHIP_RK3568
+options SOC_ROCKCHIP_RK3308
+
# GPIO / PINCTRL
device dwgpio # Synopsys DesignWare APB GPIO Controller
Index: sys/arm64/rockchip/clk/rk3308_cru.c
===================================================================
--- /dev/null
+++ sys/arm64/rockchip/clk/rk3308_cru.c
@@ -0,0 +1,722 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+
+#include <dev/fdt/simplebus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/clk/clk_div.h>
+#include <dev/extres/clk/clk_fixed.h>
+#include <dev/extres/clk/clk_mux.h>
+
+#include <arm64/rockchip/clk/rk_cru.h>
+#include <contrib/device-tree/include/dt-bindings/clock/rk3308-cru.h>
+
+
+#define RK3308_PLLSEL_CON(x) ((x) * 0x20)
+#define RK3308_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
+#define RK3308_CLKGATE_CON(x) ((x) * 0x4 + 0x300)
+#define RK3308_GLB_SRST_FST 0xb8
+#define RK3308_SOFTRST_CON(x) ((x) * 0x4 + 0x400)
+#define RK3308_MODE_CON 0xa0
+#define RK3308_SDMMC_CON0 0x480
+#define RK3308_SDMMC_CON1 0x484
+#define RK3308_SDIO_CON0 0x488
+#define RK3308_SDIO_CON1 0x48c
+#define RK3308_EMMC_CON0 0x490
+#define RK3308_EMMC_CON1 0x494
+
+
+#define PNAME(_name) static const char *_name[]
+
+
+#define RK_PLLRATE(_hz, _ref, _fb, _post1, _post2, _dspd) \
+{ \
+ .freq = _hz, \
+ .refdiv = _ref, \
+ .fbdiv = _fb, \
+ .postdiv1 = _post1, \
+ .postdiv2 = _post2, \
+ .dsmpd = _dspd, \
+}
+
+/* PLL clock */
+#define RK_PLL(_id, _name, _pnames, _off, _shift) \
+{ \
+ .type = RK3328_CLK_PLL, \
+ .clk.pll = &(struct rk_clk_pll_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = _pnames, \
+ .clkdef.parent_cnt = nitems(_pnames), \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .base_offset = RK3308_PLLSEL_CON(_off), \
+ .mode_reg = 0xc0, \
+ .mode_shift = _shift, \
+ .rates = rk3308_pll_rates, \
+ }, \
+}
+
+/* Clock for ARM core(s) */
+#define RK_ARMDIV(_id, _nm, _pn, _r, _off, _ds, _dw, _ms, _mw, _mp, _ap)\
+{ \
+ .type = RK_CLK_ARMCLK, \
+ .clk.armclk = &(struct rk_clk_armclk_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _nm, \
+ .clkdef.parent_names = _pn, \
+ .clkdef.parent_cnt = nitems(_pn), \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_off), \
+ .mux_shift = _ms, \
+ .mux_width = _mw, \
+ .div_shift = _ds, \
+ .div_width = _dw, \
+ .main_parent = _mp, \
+ .alt_parent = _ap, \
+ .rates = _r, \
+ .nrates = nitems(_r), \
+ }, \
+}
+
+/* Composite */
+#define RK_COMPOSITE(_id, _name, _pnames, _o, _ms, _mw, _ds, _dw, _go, _gw,_f)\
+{ \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = _pnames, \
+ .clkdef.parent_cnt = nitems(_pnames), \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_o), \
+ .mux_shift = _ms, \
+ .mux_width = _mw, \
+ .div_shift = _ds, \
+ .div_width = _dw, \
+ .gate_offset = RK3308_CLKGATE_CON(_go), \
+ .gate_shift = _gw, \
+ .flags = RK_CLK_COMPOSITE_HAVE_MUX | \
+ RK_CLK_COMPOSITE_HAVE_GATE | _f, \
+ }, \
+}
+
+/* Composite no mux */
+#define RK_COMPNOMUX(_id, _name, _pname, _o, _ds, _dw, _go, _gw, _f) \
+{ \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = (const char *[]){_pname}, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_o), \
+ .div_shift = _ds, \
+ .div_width = _dw, \
+ .gate_offset = RK3308_CLKGATE_CON(_go), \
+ .gate_shift = _gw, \
+ .flags = RK_CLK_COMPOSITE_HAVE_GATE | _f, \
+ }, \
+}
+
+/* Composite no div */
+#define RK_COMPNODIV(_id, _name, _pnames, _o, _ms, _mw, _go, _gw, _f) \
+{ \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = _pnames, \
+ .clkdef.parent_cnt = nitems(_pnames), \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_o), \
+ .mux_shift = _ms, \
+ .mux_width = _mw, \
+ .gate_offset = RK3308_CLKGATE_CON(_go), \
+ .gate_shift = _gw, \
+ .flags = RK_CLK_COMPOSITE_HAVE_MUX | \
+ RK_CLK_COMPOSITE_HAVE_GATE | _f, \
+ }, \
+}
+
+/* Composite div only */
+#define RK_COMPDIV(_id, _name, _pname, _o, _ds, _dw, _f) \
+{ \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = (const char *[]){_pname}, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_o), \
+ .div_shift = _ds, \
+ .div_width = _dw, \
+ .flags = _f, \
+ }, \
+}
+
+
+/* Fixed factor mux/div */
+#define RK_FACTOR(_id, _name, _pname, _mult, _div) \
+{ \
+ .type = RK_CLK_FIXED, \
+ .clk.fixed = &(struct clk_fixed_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = (const char *[]){_pname}, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .mult = _mult, \
+ .div = _div, \
+ }, \
+}
+
+
+#define RK_FACTOR_GATE(_id, cname, pname,f, fm, fd, go, gb, gf) \
+ { \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = cname, \
+ .clkdef.parent_names = (const char *[]){ pname }, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .div_shift = fm, \
+ .div_width = fd, \
+ .gate_offset = go, \
+ .gate_shift = gb, \
+ .flags = RK_CLK_FRACT_HAVE_GATE | gf, \
+ }, \
+}
+/* Fractional */
+#define RK_FRACTION(_id, _name, _pname, _o, _go, _gw, _f) \
+{ \
+ .type = RK_CLK_FRACT, \
+ .clk.fract = &(struct rk_clk_fract_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = (const char *[]){_pname}, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .offset = RK3308_CLKSEL_CON(_o), \
+ .gate_offset = RK3308_CLKGATE_CON(_go), \
+ .gate_shift = _gw, \
+ .flags = RK_CLK_FRACT_HAVE_GATE | _f, \
+ }, \
+}
+
+/* Multiplexer */
+#define RK_MUX(_id, _name, _pnames, _o, _ms, _mw, _f) \
+{ \
+ .type = RK_CLK_MUX, \
+ .clk.mux = &(struct rk_clk_mux_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = _pnames, \
+ .clkdef.parent_cnt = nitems(_pnames), \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .offset = RK3308_CLKSEL_CON(_o), \
+ .shift = _ms, \
+ .width = _mw, \
+ .mux_flags = _f, \
+ }, \
+}
+
+#define RK_GATE(_id, _name, _pname, _o, _s) \
+{ \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _pname, \
+ .offset = RK3308_CLKGATE_CON(_o), \
+ .shift = _s, \
+}
+#define RK_MMC(_id, _name, _pname, _o, _ds) \
+{ \
+ .type = RK_CLK_COMPOSITE, \
+ .clk.composite = &(struct rk_clk_composite_def) { \
+ .clkdef.id = _id, \
+ .clkdef.name = _name, \
+ .clkdef.parent_names = (const char *[]){_pname}, \
+ .clkdef.parent_cnt = 1, \
+ .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
+ .muxdiv_offset = RK3308_CLKSEL_CON(_o), \
+ .div_shift = _ds, \
+ }, \
+}
+
+struct rk_clk_pll_rate rk3308_pll_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd */
+ RK_PLLRATE(1608000000, 1, 67, 1, 1, 1),
+ RK_PLLRATE(1584000000, 1, 66, 1, 1, 1),
+ RK_PLLRATE(1560000000, 1, 65, 1, 1, 1),
+ RK_PLLRATE(1536000000, 1, 64, 1, 1, 1),
+ RK_PLLRATE(1512000000, 1, 63, 1, 1, 1),
+ RK_PLLRATE(1488000000, 1, 62, 1, 1, 1),
+ RK_PLLRATE(1464000000, 1, 61, 1, 1, 1),
+ RK_PLLRATE(1440000000, 1, 60, 1, 1, 1),
+ RK_PLLRATE(1416000000, 1, 59, 1, 1, 1),
+ RK_PLLRATE(1392000000, 1, 58, 1, 1, 1),
+ RK_PLLRATE(1368000000, 1, 57, 1, 1, 1),
+ RK_PLLRATE(1344000000, 1, 56, 1, 1, 1),
+ RK_PLLRATE(1320000000, 1, 55, 1, 1, 1),
+ RK_PLLRATE(1296000000, 1, 54, 1, 1, 1),
+ RK_PLLRATE(1272000000, 1, 53, 1, 1, 1),
+ RK_PLLRATE(1248000000, 1, 52, 1, 1, 1),
+ RK_PLLRATE(1200000000, 1, 50, 1, 1, 1),
+ RK_PLLRATE(1188000000, 2, 99, 1, 1, 1),
+ RK_PLLRATE(1104000000, 1, 46, 1, 1, 1),
+ RK_PLLRATE(1100000000, 12, 550, 1, 1, 1),
+ RK_PLLRATE(1008000000, 1, 84, 2, 1, 1),
+ RK_PLLRATE(1000000000, 6, 500, 2, 1, 1),
+ RK_PLLRATE(984000000, 1, 82, 2, 1, 1),
+ RK_PLLRATE(960000000, 1, 80, 2, 1, 1),
+ RK_PLLRATE(936000000, 1, 78, 2, 1, 1),
+ RK_PLLRATE(912000000, 1, 76, 2, 1, 1),
+ RK_PLLRATE(900000000, 4, 300, 2, 1, 1),
+ RK_PLLRATE(888000000, 1, 74, 2, 1, 1),
+ RK_PLLRATE(864000000, 1, 72, 2, 1, 1),
+ RK_PLLRATE(840000000, 1, 70, 2, 1, 1),
+ RK_PLLRATE(816000000, 1, 68, 2, 1, 1),
+ RK_PLLRATE(800000000, 6, 400, 2, 1, 1),
+ RK_PLLRATE(700000000, 6, 350, 2, 1, 1),
+ RK_PLLRATE(696000000, 1, 58, 2, 1, 1),
+ RK_PLLRATE(624000000, 1, 52, 2, 1, 1),
+ RK_PLLRATE(600000000, 1, 75, 3, 1, 1),
+ RK_PLLRATE(594000000, 2, 99, 2, 1, 1),
+ RK_PLLRATE(504000000, 1, 63, 3, 1, 1),
+ RK_PLLRATE(500000000, 6, 250, 2, 1, 1),
+ RK_PLLRATE(408000000, 1, 68, 2, 2, 1),
+ RK_PLLRATE(312000000, 1, 52, 2, 2, 1),
+ RK_PLLRATE(216000000, 1, 72, 4, 2, 1),
+ RK_PLLRATE(96000000, 1, 64, 4, 4, 1),
+ { /* sentinel */ },
+};
+
+static struct rk_clk_armclk_rates rk3308_armclk_rates[] = {
+ {1608000000, 1},
+ {1512000000, 1},
+ {1488000000, 1},
+ {1416000000, 1},
+ {1392000000, 1},
+ {1296000000, 1},
+ {1200000000, 1},
+ {1104000000, 1},
+ {1008000000, 1},
+ {912000000, 1},
+ {816000000, 1},
+ {696000000, 1},
+ {600000000, 1},
+ {408000000, 1},
+ {312000000, 1},
+ {216000000, 1},
+ {96000000, 1},
+ {},
+};
+
+/* Parent clock defines */
+PNAME(mux_pll_p) = { "xin24m" };
+PNAME(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc32k" };
+PNAME(mux_armclk_p) = { "apll_core", "vpll0_core", "vpll1_core" };
+PNAME(mux_dpll_vpll0_p) = { "dpll", "vpll0" };
+PNAME(mux_dpll_vpll0_xin24m_p) = { "dpll", "vpll0", "xin24m" };
+PNAME(mux_dpll_vpll0_vpll1_p) = { "dpll", "vpll0", "vpll1" };
+PNAME(mux_dpll_vpll0_vpll1_xin24m_p) = { "dpll", "vpll0", "vpll1", "xin24m" };
+PNAME(mux_dpll_vpll0_vpll1_usb480m_xin24m_p) = { "dpll", "vpll0", "vpll1", "usb480m", "xin24m" };
+PNAME(mux_vpll0_vpll1_p) = { "vpll0", "vpll1" };
+PNAME(mux_vpll0_vpll1_xin24m_p) = { "vpll0", "vpll1", "xin24m" };
+PNAME(mux_uart0_p) = { "clk_uart0_src", "dummy", "clk_uart0_frac" };
+PNAME(mux_uart1_p) = { "clk_uart1_src", "dummy", "clk_uart1_frac" };
+PNAME(mux_uart2_p) = { "clk_uart2_src", "dummy", "clk_uart2_frac" };
+PNAME(mux_uart3_p) = { "clk_uart3_src", "dummy", "clk_uart3_frac" };
+PNAME(mux_uart4_p) = { "clk_uart4_src", "dummy", "clk_uart4_frac" };
+PNAME(mux_dclk_vop_p) = { "dclk_vop_src", "dclk_vop_frac", "xin24m" };
+PNAME(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" };
+PNAME(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" };
+PNAME(mux_sdio_p) = { "clk_sdio_div", "clk_sdio_div50" };
+PNAME(mux_emmc_p) = { "clk_emmc_div", "clk_emmc_div50" };
+PNAME(mux_mac_p) = { "clk_mac_src", "mac_clkin" };
+PNAME(mux_mac_rmii_sel_p) = { "clk_mac_rx_tx_div20", "clk_mac_rx_tx_div2" };
+PNAME(mux_ddrstdby_p) = { "clk_ddrphy1x_out", "clk_ddr_stdby_div4" };
+PNAME(mux_rtc32k_p) = { "xin32k", "clk_pvtm_32k", "clk_rtc32k_frac", "clk_rtc32k_div" };
+PNAME(mux_usbphy_ref_p) = { "xin24m", "clk_usbphy_ref_src" };
+PNAME(mux_wifi_src_p) = { "clk_wifi_dpll", "clk_wifi_vpll0" };
+PNAME(mux_wifi_p) = { "clk_wifi_osc", "clk_wifi_src" };
+PNAME(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" };
+PNAME(mux_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "mclk_i2s0_8ch_in" };
+PNAME(mux_i2s0_8ch_tx_rx_p) = { "clk_i2s0_8ch_tx_mux", "clk_i2s0_8ch_rx_mux"};
+PNAME(mux_i2s0_8ch_tx_out_p) = { "clk_i2s0_8ch_tx", "xin12m" };
+PNAME(mux_i2s0_8ch_rx_p) = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "mclk_i2s0_8ch_in" };
+PNAME(mux_i2s0_8ch_rx_tx_p) = { "clk_i2s0_8ch_rx_mux", "clk_i2s0_8ch_tx_mux"};
+PNAME(mux_i2s1_8ch_tx_p) = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "mclk_i2s1_8ch_in" };
+PNAME(mux_i2s1_8ch_tx_rx_p) = { "clk_i2s1_8ch_tx_mux", "clk_i2s1_8ch_rx_mux"};
+PNAME(mux_i2s1_8ch_tx_out_p) = { "clk_i2s1_8ch_tx", "xin12m" };
+PNAME(mux_i2s1_8ch_rx_p) = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "mclk_i2s1_8ch_in" };
+PNAME(mux_i2s1_8ch_rx_tx_p) = { "clk_i2s1_8ch_rx_mux", "clk_i2s1_8ch_tx_mux"};
+PNAME(mux_i2s2_8ch_tx_p) = { "clk_i2s2_8ch_tx_src", "clk_i2s2_8ch_tx_frac", "mclk_i2s2_8ch_in" };
+PNAME(mux_i2s2_8ch_tx_rx_p) = { "clk_i2s2_8ch_tx_mux", "clk_i2s2_8ch_rx_mux"};
+PNAME(mux_i2s2_8ch_tx_out_p) = { "clk_i2s2_8ch_tx", "xin12m" };
+PNAME(mux_i2s2_8ch_rx_p) = { "clk_i2s2_8ch_rx_src", "clk_i2s2_8ch_rx_frac", "mclk_i2s2_8ch_in" };
+PNAME(mux_i2s2_8ch_rx_tx_p) = { "clk_i2s2_8ch_rx_mux", "clk_i2s2_8ch_tx_mux"};
+PNAME(mux_i2s3_8ch_tx_p) = { "clk_i2s3_8ch_tx_src", "clk_i2s3_8ch_tx_frac", "mclk_i2s3_8ch_in" };
+PNAME(mux_i2s3_8ch_tx_rx_p) = { "clk_i2s3_8ch_tx_mux", "clk_i2s3_8ch_rx_mux"};
+PNAME(mux_i2s3_8ch_tx_out_p) = { "clk_i2s3_8ch_tx", "xin12m" };
+PNAME(mux_i2s3_8ch_rx_p) = { "clk_i2s3_8ch_rx_src", "clk_i2s3_8ch_rx_frac", "mclk_i2s3_8ch_in" };
+PNAME(mux_i2s3_8ch_rx_tx_p) = { "clk_i2s3_8ch_rx_mux", "clk_i2s3_8ch_tx_mux"};
+PNAME(mux_i2s0_2ch_p) = { "clk_i2s0_2ch_src", "clk_i2s0_2ch_frac", "mclk_i2s0_2ch_in" };
+PNAME(mux_i2s0_2ch_out_p) = { "clk_i2s0_2ch", "xin12m" };
+PNAME(mux_i2s1_2ch_p) = { "clk_i2s1_2ch_src", "clk_i2s1_2ch_frac", "mclk_i2s1_2ch_in"};
+PNAME(mux_i2s1_2ch_out_p) = { "clk_i2s1_2ch", "xin12m" };
+PNAME(mux_spdif_tx_src_p) = { "clk_spdif_tx_div", "clk_spdif_tx_div50" };
+PNAME(mux_spdif_tx_p) = { "clk_spdif_tx_src", "clk_spdif_tx_frac", "mclk_i2s0_2ch_in" };
+PNAME(mux_spdif_rx_src_p) = { "clk_spdif_rx_div", "clk_spdif_rx_div50" };
+PNAME(mux_spdif_rx_p) = { "clk_spdif_rx_src", "clk_spdif_rx_frac" };
+/* CLOCKS */
+static struct rk_clk rk3308_clks[] = {
+ /* External clocks */
+ LINK("xin24m"),
+ LINK("clk_rtc_32k"),
+ LINK("usb480m_phy"),
+// LINK("jtag_clkin"),
+ LINK("clk_ddrphy1x_out"),
+ LINK("clk_pvtm_32k"),
+ LINK("xin32k"),
+ LINK("mclk_i2s0_8ch_in"),
+ LINK("mclk_i2s1_8ch_in"), // SOS SCRU
+ LINK("mclk_i2s2_8ch_in"),
+ LINK("mclk_i2s3_8ch_in"),
+ LINK("mclk_i2s0_2ch_in"),
+ LINK("mclk_i2s1_2ch_in"),
+ LINK("mac_clkin"),
+ LINK("dummy"),
+ /* PLL's */
+ RK_PLL(PLL_APLL, "apll", mux_pll_p, 0, 0),
+ RK_PLL(PLL_DPLL, "dpll", mux_pll_p, 1, 2),
+ RK_PLL(PLL_VPLL0, "vpll0", mux_pll_p, 2, 4),
+ RK_PLL(PLL_VPLL1, "vpll1", mux_pll_p, 3, 6),
+ RK_ARMDIV(ARMCLK, "armclk", mux_armclk_p, rk3308_armclk_rates, 0, 0, 5,6, 1, 0, 1),
+ RK_MUX(USB480M, "usb480m", mux_usb480m_p, RK3308_MODE_CON, 8, 2, 0),
+ RK_FACTOR(0, "xin12m", "xin24m", 1, 2),
+ RK_COMPNOMUX(0, "pclk_core_dbg", "armclk", 0, 8, 4, 0, 2, 0),
+ RK_COMPNOMUX(0, "aclk_core", "armclk", 0, 12, 3, 0, 1, 0),
+ RK_COMPNODIV(ACLK_BUS_SRC, "clk_bus_src", mux_dpll_vpll0_vpll1_p, 5, 6, 2, 1, 0, 0),
+ RK_COMPNOMUX(PCLK_BUS, "pclk_bus", "clk_bus_src", 6, 8, 5, 1, 3, 0),
+ RK_COMPNOMUX(HCLK_BUS, "hclk_bus", "clk_bus_src", 6, 0, 5, 1, 2, 0),
+ RK_COMPNOMUX(ACLK_BUS, "aclk_bus", "clk_bus_src", 5, 0, 5, 1, 1, 0),
+ RK_COMPOSITE(0, "clk_uart0_src", mux_dpll_vpll0_vpll1_usb480m_xin24m_p, 10, 13, 3, 0, 5, 1, 9, 0),
+ RK_FRACTION(0, "clk_uart0_frac", "clk_uart0_src", 12, 1, 11, 0),
+ RK_MUX(0, "clk_uart0_mux", mux_uart0_p, 11, 14, 2, 0),
+ RK_COMPOSITE(0, "clk_uart1_src", mux_dpll_vpll0_vpll1_usb480m_xin24m_p, 13, 13, 3, 0, 5, 1, 13, 0),
+ RK_FRACTION(0, "clk_uart1_frac", "clk_uart1_src", 15, 1, 15, 0),
+ RK_MUX(0, "clk_uart1_mux", mux_uart1_p, 14, 14, 2, 0),
+ RK_COMPOSITE(0, "clk_uart2_src", mux_dpll_vpll0_vpll1_usb480m_xin24m_p, 16, 13, 3, 0, 5, 2, 1, 0),
+ RK_FRACTION(0, "clk_uart2_frac", "clk_uart2_src", 18, 2, 3, 0),
+ RK_MUX(0, "clk_uart2_mux", mux_uart2_p, 17, 14, 2, 0),
+ RK_COMPOSITE(0, "clk_uart3_src", mux_dpll_vpll0_vpll1_usb480m_xin24m_p, 19, 13, 3, 0, 5, 2, 5, 0),
+ RK_FRACTION(0, "clk_uart3_frac", "clk_uart3_src", 21, 2, 7, 0),
+ RK_MUX(0, "clk_uart3_mux", mux_uart3_p, 20, 14, 2, 0),
+ RK_COMPOSITE(0, "clk_uart4_src", mux_dpll_vpll0_vpll1_usb480m_xin24m_p, 22, 13, 3, 0, 5, 2, 9, 0),
+ RK_FRACTION(0, "clk_uart4_frac", "clk_uart4_src", 24, 2, 11, 0),
+ RK_MUX(0, "clk_uart4_mux", mux_uart4_p, 23, 14, 2, 0),
+ RK_COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_dpll_vpll0_xin24m_p, 25, 14, 2, 0, 7, 2, 13, 0),
+ RK_COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_dpll_vpll0_xin24m_p, 26, 14, 2, 0, 7, 2, 14, 0),
+ RK_COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_dpll_vpll0_xin24m_p, 27, 14, 2, 0, 7, 2, 15, 0),
+ RK_COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_dpll_vpll0_xin24m_p, 28, 14, 2, 0, 7, 3, 0, 0),
+ RK_COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_dpll_vpll0_xin24m_p, 29, 14, 2, 0, 7, 3, 1, 0),
+ RK_COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_dpll_vpll0_xin24m_p, 74, 14, 2, 0, 7, 15, 0, 0),
+ RK_COMPOSITE(SCLK_PWM2, "clk_pwm2", mux_dpll_vpll0_xin24m_p, 75, 14, 2, 0, 7, 15, 1, 0),
+ RK_COMPOSITE(SCLK_SPI0, "clk_spi0", mux_dpll_vpll0_xin24m_p, 30, 14, 2, 0, 7, 3, 2, 0),
+ RK_COMPOSITE(SCLK_SPI1, "clk_spi1", mux_dpll_vpll0_xin24m_p, 31, 14, 2, 0, 7, 3, 3, 0),
+ RK_COMPOSITE(SCLK_SPI2, "clk_spi2", mux_dpll_vpll0_xin24m_p, 32, 14, 2, 0, 7, 3, 4, 0),
+ RK_COMPNOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 33, 0, 11, 3, 5, 0),
+ RK_COMPNOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 34, 0, 11, 3, 6, 0),
+ RK_COMPNOMUX(SCLK_OTP, "clk_otp", "xin24m", 35, 0, 4, 3, 7, 0),
+ RK_COMPNOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 35, 4, 2, 3, 8, 0),
+ RK_COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_dpll_vpll0_vpll1_p, 7, 6, 2, 0, 5, 1, 4, 0),
+ RK_COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_dpll_vpll0_vpll1_p, 7, 14, 2, 8, 5, 1, 5, 0),
+ RK_COMPOSITE(0, "dclk_vop_src", mux_dpll_vpll0_vpll1_p, 8, 10, 2, 0, 8, 1, 6, 0),
+ RK_FRACTION(0, "dclk_vop_frac", "dclk_vop_src", 9, 1, 7, 0),
+ RK_MUX(0, "dclk_vop_mux", mux_dclk_vop_p, 8, 14, 2, 0),
+ RK_COMPNODIV(ACLK_PERI_SRC, "clk_peri_src", mux_dpll_vpll0_vpll1_p, 36, 6, 2, 8, 0, 0),
+ RK_COMPNOMUX(ACLK_PERI, "aclk_peri", "clk_peri_src", 36, 0, 5, 8, 1, 0),
+ RK_COMPNOMUX(HCLK_PERI, "hclk_peri", "clk_peri_src", 37, 0, 5, 8, 2, 0),
+ RK_COMPNOMUX(PCLK_PERI, "pclk_peri", "clk_peri_src", 37, 8, 5, 8, 3, 0),
+ RK_COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_dpll_vpll0_vpll1_p, 38, 6, 2, 0, 5, 8, 4, 0),
+ RK_COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_dpll_vpll0_vpll1_p, 38, 6, 2, 0, 5, 8, 4, 0),
+ RK_COMPNODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, 38, 15, 1, 8, 5, 0),
+ RK_COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_dpll_vpll0_vpll1_xin24m_p, 39, 8, 2, 0, 8, 8, 6, 0),
+ RK_COMPOSITE(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, 39, 8, 2, 0, 8, 8, 6, 0),
+ RK_COMPNODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, 39, 15, 1, 8, 7, 0),
+// RK_MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", RK3308_SDMMC_CON0, 1),
+// RK_MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", RK3308_SDMMC_CON1, 1),
+ RK_COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_dpll_vpll0_vpll1_xin24m_p, 40, 8, 2, 0, 8, 8, 8, 0),
+ RK_COMPOSITE(SCLK_SDIO_DIV50, "clk_sdio_div50", mux_dpll_vpll0_vpll1_xin24m_p, 40, 8, 2, 0, 8, 8, 8, 0),
+ RK_COMPNODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, 40, 15, 1, 8, 9, 0),
+// RK_MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3308_SDIO_CON0, 1),
+// RK_MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3308_SDIO_CON1, 1),
+ RK_COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_dpll_vpll0_vpll1_xin24m_p, 41, 8, 2, 0, 8, 8, 10, 0),
+ RK_COMPOSITE(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, 41, 8, 2, 0, 8, 8, 10, 0),
+ RK_COMPNODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, 41, 15, 1, 8, 11, 0),
+// RK_MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", RK3308_EMMC_CON0, 1),
+// RK_MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", RK3308_EMMC_CON1, 1),
+ RK_COMPOSITE(SCLK_SFC, "clk_sfc", mux_dpll_vpll0_vpll1_p, 42, 14, 2, 0, 7, 8, 12, 0),
+ RK_MUX(SCLK_RTC32K, "clk_rtc32k", mux_rtc32k_p, 2, 8, 2, 0),
+ RK_COMPOSITE(SCLK_MAC_SRC, "clk_mac_src", mux_dpll_vpll0_vpll1_p, 43, 6, 2, 0, 5, 8, 14, 0),
+ RK_MUX(SCLK_MAC, "clk_mac", mux_mac_p, 43, 14, 1, 0),
+ RK_FACTOR(0, "clk_mac_rx_tx_div2", "clk_mac_rx_tx", 1, 2),
+ RK_FACTOR(0, "clk_mac_rx_tx_div20", "clk_mac_rx_tx", 1, 20),
+ RK_MUX(SCLK_MAC_RMII, "clk_mac_rmii_sel", mux_mac_rmii_sel_p, 43, 15, 1, 0),
+ RK_COMPOSITE(SCLK_OWIRE, "clk_owire", mux_dpll_vpll0_xin24m_p, 44, 14, 2, 8, 6, 8, 15, 0),
+ RK_COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, 1, 6, 2, 0, 3, 0, 10, 0),
+ RK_FACTOR_GATE(0, "clk_ddr_stdby_div4", "clk_ddrphy4x",0,1, 4, 0, 13,0),
+ RK_COMPNODIV(0, "clk_ddrstdby", mux_ddrstdby_p, 1, 8, 1, 4, 14, 0),
+ RK_FRACTION(0, "clk_rtc32k_frac", "xin24m", 3, 4, 3, 0),
+ RK_MUX(0, "clk_rtc32k_div_src", mux_vpll0_vpll1_p, 2, 10, 1, 0),
+ RK_COMPNOMUX(0, "clk_rtc32k_div", "clk_rtc32k_div_src", 4, 0, 16, 4, 2, 0),
+ RK_COMPOSITE(0, "clk_usbphy_ref_src", mux_dpll_vpll0_p, 72, 6, 1, 0, 6, 4, 7, 0),
+ RK_COMPNODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, 72, 7, 1, 4, 8, 0),
+ RK_COMPOSITE(0, "clk_wifi_src", mux_wifi_src_p, 44, 6, 1, 0, 6, 4, 0, 0),
+ RK_COMPNODIV(SCLK_WIFI, "clk_wifi", mux_wifi_p, 44, 7, 1, 4, 1, 0),
+ RK_COMPNODIV(0, "clk_audio_src", mux_vpll0_vpll1_xin24m_p, 45, 6, 2, 10, 0, 0),
+ RK_COMPNOMUX(HCLK_AUDIO, "hclk_audio", "clk_audio_src", 45, 0, 5, 10, 1, 0),
+ RK_COMPNOMUX(PCLK_AUDIO, "pclk_audio", "clk_audio_src", 45, 8, 5, 10, 2, 0),
+ RK_COMPOSITE(0, "clk_pdm_src", mux_vpll0_vpll1_xin24m_p, 46, 8, 2, 0, 7, 10, 3, 0),
+ RK_FRACTION(0, "clk_pdm_frac", "clk_pdm_src", 47, 10, 4, 0),
+ RK_MUX(0, "clk_pdm_mux", mux_pdm_p, 46, 15, 1, 0),
+ RK_COMPOSITE(SCLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 52, 8, 2, 0, 7, 10, 12, 0),
+ RK_FRACTION(0, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", 53, 10, 13, 0),
+ RK_COMPNODIV(SCLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", mux_i2s0_8ch_tx_rx_p, 52, 12, 1, 10, 14, 0),
+ RK_COMPNODIV(SCLK_I2S0_8CH_TX_OUT, "clk_i2s0_8ch_tx_out", mux_i2s0_8ch_tx_out_p, 52, 15, 1, 10, 15, 0),
+ RK_COMPOSITE(SCLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 54, 8, 2, 0, 7, 11, 0, 0),
+ RK_FRACTION(0, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", 55, 11, 1, 0),
+ RK_COMPNODIV(SCLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", mux_i2s0_8ch_rx_tx_p, 54, 12, 1, 11, 2, 0),
+ RK_COMPOSITE(SCLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 56, 8, 2, 0, 7, 11, 4, 0),
+ RK_FRACTION(0, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", 57, 11, 5, 0),
+ RK_COMPNODIV(SCLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", mux_i2s1_8ch_tx_rx_p, 56, 12, 1, 11, 6, 0),
+ RK_COMPNODIV(SCLK_I2S1_8CH_TX_OUT, "clk_i2s1_8ch_tx_out", mux_i2s1_8ch_tx_out_p, 56, 15, 1, 11, 7, 0),
+ RK_COMPOSITE(SCLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 58, 8, 2, 0, 7, 11, 8, 0),
+ RK_FRACTION(0, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", 59, 11, 9, 0),
+ RK_COMPNODIV(SCLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", mux_i2s1_8ch_rx_tx_p, 58, 12, 1, 11, 10, 0),
+ RK_COMPOSITE(SCLK_I2S2_8CH_TX_SRC, "clk_i2s2_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 60, 8, 2, 0, 7, 11, 12, 0),
+ RK_FRACTION(0, "clk_i2s2_8ch_tx_frac", "clk_i2s2_8ch_tx_src", 61, 11, 13, 0),
+ RK_COMPNODIV(SCLK_I2S2_8CH_TX, "clk_i2s2_8ch_tx", mux_i2s2_8ch_tx_rx_p, 60, 12, 1, 11, 14, 0),
+ RK_COMPNODIV(SCLK_I2S2_8CH_TX_OUT, "clk_i2s2_8ch_tx_out", mux_i2s2_8ch_tx_out_p, 60, 15, 1, 11, 15, 0),
+ RK_COMPOSITE(SCLK_I2S2_8CH_RX_SRC, "clk_i2s2_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 62, 8, 2, 0, 7, 12, 0, 0),
+ RK_FRACTION(0, "clk_i2s2_8ch_rx_frac", "clk_i2s2_8ch_rx_src", 63, 12, 1, 0),
+ RK_COMPNODIV(SCLK_I2S2_8CH_RX, "clk_i2s2_8ch_rx", mux_i2s2_8ch_rx_tx_p, 62, 12, 1, 12, 2, 0),
+ RK_COMPOSITE(SCLK_I2S3_8CH_TX_SRC, "clk_i2s3_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 64, 8, 2, 0, 7, 12, 4, 0),
+ RK_FRACTION(0, "clk_i2s3_8ch_tx_frac", "clk_i2s3_8ch_tx_src", 65, 12, 5, 0),
+ RK_COMPNODIV(SCLK_I2S3_8CH_TX, "clk_i2s3_8ch_tx", mux_i2s3_8ch_tx_rx_p, 64, 12, 1, 12, 6, 0),
+ RK_COMPNODIV(SCLK_I2S3_8CH_TX_OUT, "clk_i2s3_8ch_tx_out", mux_i2s3_8ch_tx_out_p, 64, 15, 1, 12, 7, 0),
+ RK_COMPOSITE(SCLK_I2S3_8CH_RX_SRC, "clk_i2s3_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 66, 8, 2, 0, 7, 12, 8, 0),
+ RK_FRACTION(0, "clk_i2s3_8ch_rx_frac", "clk_i2s3_8ch_rx_src", 67, 12, 9, 0),
+ RK_COMPNODIV(SCLK_I2S3_8CH_RX, "clk_i2s3_8ch_rx", mux_i2s3_8ch_rx_tx_p, 66, 12, 1, 12, 10, 0),
+ RK_COMPOSITE(SCLK_I2S0_2CH_SRC, "clk_i2s0_2ch_src", mux_vpll0_vpll1_xin24m_p, 68, 8, 2, 0, 7, 12, 12, 0),
+ RK_FRACTION(0, "clk_i2s0_2ch_frac", "clk_i2s0_2ch_src", 69, 12, 13, 0),
+ RK_COMPNODIV(SCLK_I2S0_2CH_OUT, "clk_i2s0_2ch_out", mux_i2s0_2ch_out_p, 68, 15, 1, 12, 15, 0),
+ RK_COMPOSITE(SCLK_I2S1_2CH_SRC, "clk_i2s1_2ch_src", mux_vpll0_vpll1_xin24m_p, 70, 8, 2, 0, 7, 13, 0, 0),
+ RK_FRACTION(0, "clk_i2s1_2ch_frac", "clk_i2s1_2ch_src", 71, 13, 1, 0),
+ RK_COMPNODIV(SCLK_I2S1_2CH_OUT, "clk_i2s1_2ch_out", mux_i2s1_2ch_out_p, 70, 15, 1, 13, 3, 0),
+ RK_COMPOSITE(SCLK_SPDIF_TX_DIV, "clk_spdif_tx_div", mux_vpll0_vpll1_xin24m_p, 48, 8, 2, 0, 7, 10, 6, 0),
+ RK_COMPOSITE(SCLK_SPDIF_TX_DIV50, "clk_spdif_tx_div50", mux_vpll0_vpll1_xin24m_p, 48, 8, 2, 0, 7, 10, 6, 0),
+ RK_MUX(0, "clk_spdif_tx_src", mux_spdif_tx_src_p, 48, 12, 1, 0),
+ RK_FRACTION(0, "clk_spdif_tx_frac", "clk_spdif_tx_src", 49, 10, 7, 0),
+ RK_COMPOSITE(SCLK_SPDIF_RX_DIV, "clk_spdif_rx_div", mux_vpll0_vpll1_xin24m_p, 50, 8, 2, 0, 7, 10, 9, 0),
+ RK_COMPOSITE(SCLK_SPDIF_RX_DIV50, "clk_spdif_rx_div50", mux_vpll0_vpll1_xin24m_p, 50, 8, 2, 0, 7, 10, 9, 0),
+ RK_MUX(0, "clk_spdif_rx_src", mux_spdif_rx_src_p, 50, 14, 1, 0),
+ RK_FRACTION(0, "clk_spdif_rx_frac", "clk_spdif_rx_src", 51, 10, 10, 0),
+ RK_FACTOR(ACLK_DMAC0, "aclk_dmac0", "aclk_bus", 1, 1),
+ RK_FACTOR(ACLK_DMAC1, "aclk_dmac1", "aclk_bus", 1, 1),
+ RK_FACTOR(PCLK_WDT, "pclk_wdt", "pclk_bus", 1, 1),
+ RK_MUX(SCLK_I2S0_8CH_TX_MUX, "clk_i2s0_8ch_tx_mux", mux_i2s0_8ch_tx_p, 52, 10, 2, 0),
+ RK_MUX(SCLK_I2S0_8CH_RX_MUX, "clk_i2s0_8ch_rx_mux", mux_i2s0_8ch_rx_p, 54, 10, 2, 0),
+ RK_MUX(SCLK_I2S1_8CH_TX_MUX, "clk_i2s1_8ch_tx_mux", mux_i2s1_8ch_tx_p, 56, 10, 2, 0),
+ RK_MUX(SCLK_I2S1_8CH_RX_MUX, "clk_i2s1_8ch_rx_mux", mux_i2s1_8ch_rx_p, 58, 10, 2, 0),
+ RK_MUX(SCLK_I2S2_8CH_TX_MUX, "clk_i2s2_8ch_tx_mux", mux_i2s2_8ch_tx_p, 60, 10, 2, 0),
+ RK_MUX(SCLK_I2S2_8CH_RX_MUX, "clk_i2s2_8ch_rx_mux", mux_i2s2_8ch_rx_p, 62, 10, 2, 0),
+ RK_MUX(SCLK_I2S3_8CH_TX_MUX, "clk_i2s3_8ch_tx_mux", mux_i2s3_8ch_tx_p, 64, 10, 2, 0),
+ RK_MUX(SCLK_I2S3_8CH_RX_MUX, "clk_i2s3_8ch_rx_mux", mux_i2s3_8ch_rx_p, 66, 10, 2, 0),
+ RK_MUX(0, "clk_i2s0_2ch_mux", mux_i2s0_2ch_p, 68, 10, 2, 0),
+ RK_MUX(0, "clk_i2s1_2ch_mux", mux_i2s1_2ch_p, 70, 10, 2, 0),
+ RK_MUX(0, "clk_spdif_tx_mux", mux_spdif_tx_p, 48, 14, 2, 0),
+ RK_MUX(0, "clk_spdif_rx_mux", mux_spdif_rx_p, 50, 15, 1, 0),
+};
+
+/* GATES */
+static struct rk_cru_gate rk3308_gates[] = {
+ RK_GATE(0, "apll_core", "apll", 0, 0),
+ RK_GATE(0, "vpll0_core", "vpll0", 0, 0),
+ RK_GATE(0, "vpll1_core", "vpll1", 0, 0),
+// RK_GATE(0, "clk_jtag", "jtag_clkin", 0, 3),
+ RK_GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, 4),
+ RK_GATE(PCLK_DDR, "pclk_ddr", "pclk_bus", 4, 15),
+ RK_GATE(SCLK_UART0, "clk_uart0", "clk_uart0_mux", 1, 12),
+ RK_GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", 2, 0),
+ RK_GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", 2, 4),
+ RK_GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", 2, 8),
+ RK_GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", 2, 12),
+ RK_GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 3, 10),
+ RK_GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 3, 11),
+ RK_GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 3, 12),
+ RK_GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 3, 13),
+ RK_GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 3, 14),
+ RK_GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 3, 15),
+ RK_GATE(SCLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 3, 9),
+ RK_GATE(DCLK_VOP, "dclk_vop", "dclk_vop_mux", 1, 8),
+ RK_GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k", 8, 13),
+ RK_GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_mac", 9, 1),
+ RK_GATE(SCLK_MAC_RX_TX, "clk_mac_rx_tx", "clk_mac", 9, 0),
+ RK_GATE(0, "clk_ddr_mon_timer", "xin24m", 0, 12),
+ RK_GATE(0, "clk_ddr_mon", "clk_ddrphy1x_out", 4, 10),
+ RK_GATE(0, "clk_ddr_upctrl", "clk_ddrphy1x_out", 4, 11),
+ RK_GATE(0, "clk_ddr_msch", "clk_ddrphy1x_out", 4, 12),
+ RK_GATE(0, "clk_ddr_msch_peribus", "clk_ddrphy1x_out", 4, 13),
+ RK_GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", 0, 11),
+ RK_GATE(PCLK_PMU, "pclk_pmu", "pclk_bus", 4, 5),
+ RK_GATE(SCLK_PMU, "clk_pmu", "pclk_bus", 4, 6),
+ RK_GATE(0, "clk_wifi_dpll", "dpll", 15, 2),
+ RK_GATE(0, "clk_wifi_vpll0", "vpll0", 15, 3),
+ RK_GATE(0, "clk_wifi_osc", "xin24m", 15, 4),
+ RK_GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 4, 4),
+ RK_GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", 10, 5),
+ RK_GATE(SCLK_I2S0_8CH_RX_OUT, "clk_i2s0_8ch_rx_out", "clk_i2s0_8ch_rx", 11, 3),
+ RK_GATE(SCLK_I2S1_8CH_RX_OUT, "clk_i2s1_8ch_rx_out", "clk_i2s1_8ch_rx", 11, 11),
+ RK_GATE(SCLK_I2S2_8CH_RX_OUT, "clk_i2s2_8ch_rx_out", "clk_i2s2_8ch_rx", 12, 3),
+ RK_GATE(SCLK_I2S3_8CH_RX_OUT, "clk_i2s3_8ch_rx_out", "clk_i2s3_8ch_rx", 12, 11),
+ RK_GATE(SCLK_I2S0_2CH, "clk_i2s0_2ch", "clk_i2s0_2ch_mux", 12, 14),
+ RK_GATE(SCLK_I2S1_2CH, "clk_i2s1_2ch", "clk_i2s1_2ch_mux", 13, 2),
+ RK_GATE(SCLK_SPDIF_TX, "clk_spdif_tx", "clk_spdif_tx_mux", 10, 8),
+ RK_GATE(SCLK_SPDIF_RX, "clk_spdif_rx", "clk_spdif_rx_mux", 10, 11),
+ RK_GATE(0, "aclk_core_niu", "aclk_core", 0, 5),
+ RK_GATE(0, "pclk_core_dbg_niu", "aclk_core", 0, 6),
+ RK_GATE(0, "pclk_core_dbg_daplite", "pclk_core_dbg", 0, 7),
+ RK_GATE(0, "aclk_core_perf", "pclk_core_dbg", 0, 8),
+ RK_GATE(0, "pclk_core_grf", "pclk_core_dbg", 0, 9),
+ RK_GATE(0, "aclk_peri_niu", "aclk_peri", 9, 2),
+ RK_GATE(0, "aclk_peribus_niu", "aclk_peri", 9, 3),
+ RK_GATE(ACLK_MAC, "aclk_mac", "aclk_peri", 9, 4),
+ RK_GATE(0, "hclk_peri_niu", "hclk_peri", 9, 5),
+ RK_GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 9, 6),
+ RK_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 9, 7),
+ RK_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 9, 8),
+ RK_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 9, 9),
+ RK_GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 9, 10),
+ RK_GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 9, 11),
+ RK_GATE(HCLK_HOST, "hclk_host", "hclk_peri", 9, 12),
+ RK_GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_peri", 9, 13),
+ RK_GATE(0, "pclk_peri_niu", "pclk_peri", 9, 14),
+ RK_GATE(PCLK_MAC, "pclk_mac", "pclk_peri", 9, 15),
+ RK_GATE(0, "hclk_audio_niu", "hclk_audio", 14, 0),
+ RK_GATE(HCLK_PDM, "hclk_pdm", "hclk_audio", 14, 1),
+ RK_GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_audio", 14, 2),
+ RK_GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_audio", 14, 3),
+ RK_GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio", 14, 4),
+ RK_GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_audio", 14, 5),
+ RK_GATE(HCLK_I2S2_8CH, "hclk_i2s2_8ch", "hclk_audio", 14, 6),
+ RK_GATE(HCLK_I2S3_8CH, "hclk_i2s3_8ch", "hclk_audio", 14, 7),
+ RK_GATE(HCLK_I2S0_2CH, "hclk_i2s0_2ch", "hclk_audio", 14, 8),
+ RK_GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_audio", 14, 9),
+ RK_GATE(HCLK_VAD, "hclk_vad", "hclk_audio", 14, 10),
+ RK_GATE(0, "pclk_audio_niu", "pclk_audio", 14, 11),
+ RK_GATE(PCLK_ACODEC, "pclk_acodec", "pclk_audio", 14, 12),
+ RK_GATE(0, "aclk_bus_niu", "aclk_bus", 5, 0),
+ RK_GATE(0, "aclk_intmem", "aclk_bus", 5, 1),
+ RK_GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_bus", 5, 2),
+ RK_GATE(ACLK_VOP, "aclk_vop", "aclk_bus", 5, 3),
+ RK_GATE(0, "aclk_gic", "aclk_bus", 5, 4),
+ RK_GATE(0, "hclk_bus_niu", "hclk_bus", 5, 5),
+ RK_GATE(0, "hclk_rom", "hclk_bus", 5, 6),
+ RK_GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_bus", 5, 7),
+ RK_GATE(HCLK_VOP, "hclk_vop", "hclk_bus", 5, 8),
+ RK_GATE(0, "pclk_bus_niu", "pclk_bus", 5, 9),
+ RK_GATE(PCLK_UART0, "pclk_uart0", "pclk_bus", 5, 10),
+ RK_GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 5, 11),
+ RK_GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 5, 12),
+ RK_GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 5, 13),
+ RK_GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 5, 14),
+ RK_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 5, 15),
+ RK_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 6, 0),
+ RK_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 6, 1),
+ RK_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 6, 2),
+ RK_GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus", 6, 3),
+ RK_GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 6, 4),
+ RK_GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 6, 5),
+ RK_GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 6, 6),
+ RK_GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 6, 7),
+ RK_GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 6, 8),
+ RK_GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 6, 9),
+ RK_GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus", 6, 10),
+ RK_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 6, 12),
+ RK_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 6, 13),
+ RK_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 6, 14),
+ RK_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 6, 15),
+ RK_GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 7, 0),
+ RK_GATE(PCLK_SGRF, "pclk_sgrf", "pclk_bus", 7, 1),
+ RK_GATE(PCLK_GRF, "pclk_grf", "pclk_bus", 7, 2),
+ RK_GATE(PCLK_USBSD_DET, "pclk_usbsd_det", "pclk_bus", 7, 3),
+ RK_GATE(PCLK_DDR_UPCTL, "pclk_ddr_upctl", "pclk_bus", 7, 4),
+ RK_GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_bus", 7, 5),
+ RK_GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_bus", 7, 6),
+ RK_GATE(PCLK_DDR_STDBY, "pclk_ddr_stdby", "pclk_bus", 7, 7),
+ RK_GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_bus", 7, 8),
+ RK_GATE(PCLK_CRU, "pclk_cru", "pclk_bus", 7, 9),
+ RK_GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_bus", 7, 10),
+ RK_GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_bus", 7, 11),
+ RK_GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 7, 12),
+ RK_GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 7, 13),
+ RK_GATE(PCLK_CAN, "pclk_can", "pclk_bus", 7, 14),
+ RK_GATE(PCLK_OWIRE, "pclk_owire", "pclk_bus", 7, 15),
+};
+
+
+static int
+rk3308_cru_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_is_compatible(dev, "rockchip,rk3308-cru")) {
+ device_set_desc(dev, "Rockchip RK3308 Clock & Reset Unit");
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+static int
+rk3308_cru_attach(device_t dev)
+{
+ struct rk_cru_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+ sc->clks = rk3308_clks;
+ sc->nclks = nitems(rk3308_clks);
+ sc->gates = rk3308_gates;
+ sc->ngates = nitems(rk3308_gates);
+ sc->reset_offset = 0x400;
+ sc->reset_num = 478;
+
+ return (rk_cru_attach(dev));
+}
+
+static device_method_t methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, rk3308_cru_probe),
+ DEVMETHOD(device_attach, rk3308_cru_attach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(rk3308_cru, rk3308_cru_driver, methods,
+ sizeof(struct rk_cru_softc), rk_cru_driver);
+
+EARLY_DRIVER_MODULE(rk3308_cru, simplebus, rk3308_cru_driver,
+ 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
Index: sys/arm64/rockchip/if_dwc_rk.c
===================================================================
--- sys/arm64/rockchip/if_dwc_rk.c
+++ sys/arm64/rockchip/if_dwc_rk.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
*
@@ -103,6 +103,13 @@
#define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15)
#define SOC_CON6_RX_DL_CFG_SHIFT 8
+/* RK3308 registers */
+#define RK3308_GRF_MAC_CON0 0x04a0
+#define RK3308_MAC_SPEED_100M ((0x1 << 0) << 16 | (0x1 << 0))
+#define RK3308_MAC_SPEED_10M ((0x1 << 0) << 16 | (0x0 << 0))
+#define RK3308_INTF_SEL_RMII ((0x1 << 4) << 16 | (0x1 << 4))
+
+
struct if_dwc_rk_softc;
typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
@@ -147,9 +154,13 @@
static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
+static int rk3308_set_speed(struct if_dwc_rk_softc *sc, int speed);
+static void rk3308_set_phy_mode(struct if_dwc_rk_softc *sc);
+
static struct if_dwc_rk_ops rk3288_ops = {
};
+
static struct if_dwc_rk_ops rk3328_ops = {
.set_delays = rk3328_set_delays,
.set_speed = rk3328_set_speed,
@@ -162,10 +173,17 @@
.set_speed = rk3399_set_speed,
};
+static struct if_dwc_rk_ops rk3308_ops = {
+ .set_speed = rk3308_set_speed,
+ .set_phy_mode = rk3308_set_phy_mode,
+};
+
static struct ofw_compat_data compat_data[] = {
{"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
{"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
{"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
+ {"rockchip,rk3308-gmac", (uintptr_t)&rk3308_ops},
+ {"rockchip,rk3308-mac", (uintptr_t)&rk3308_ops},
{NULL, 0}
};
@@ -337,6 +355,46 @@
((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
return (0);
}
+static int
+rk3308_set_speed(struct if_dwc_rk_softc *sc, int speed)
+{
+ uint32_t reg;
+
+ switch (sc->base.phy_mode) {
+ case PHY_MODE_RGMII:
+ break;
+ case PHY_MODE_RMII:
+ switch (speed) {
+ case IFM_100_TX:
+ reg = RK3308_INTF_SEL_RMII | RK3308_MAC_SPEED_100M;
+ break;
+ case IFM_10_T:
+ reg = RK3308_INTF_SEL_RMII | RK3308_MAC_SPEED_10M;
+ break;
+ default:
+ device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
+ return (-1);
+ }
+
+ SYSCON_WRITE_4(sc->grf, RK3308_GRF_MAC_CON0, reg);
+ break;
+ }
+
+ return (0);
+}
+
+static void
+rk3308_set_phy_mode(struct if_dwc_rk_softc *sc)
+{
+ switch (sc->base.phy_mode) {
+ case PHY_MODE_RGMII:
+ break;
+ case PHY_MODE_RMII:
+ SYSCON_WRITE_4(sc->grf, RK3308_GRF_MAC_CON0,RK3308_INTF_SEL_RMII);
+
+ break;
+ }
+}
static int
if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
@@ -407,6 +465,8 @@
if (error != 0) {
device_printf(dev, "could not find clock stmmaceth\n");
return (error);
+ } else {
+// clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
}
if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
@@ -440,7 +500,6 @@
device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
sc->clk_mac_refout = NULL;
}
-
clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
}
}
@@ -464,8 +523,9 @@
if (sc->clk_mac_refout)
clk_enable(sc->clk_mac_refout);
}
- if (sc->clk_phy)
+ if (sc->clk_phy) {
clk_enable(sc->clk_phy);
+ }
if (sc->aclk_mac)
clk_enable(sc->aclk_mac);
if (sc->pclk_mac)
@@ -615,9 +675,11 @@
DEVMETHOD_END
};
+static devclass_t dwc_rk_devclass;
+
extern driver_t dwc_driver;
DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
sizeof(struct if_dwc_rk_softc), dwc_driver);
-DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0);
+DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, dwc_rk_devclass, 0, 0);
MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);
Index: sys/arm64/rockchip/rk_grf.c
===================================================================
--- sys/arm64/rockchip/rk_grf.c
+++ sys/arm64/rockchip/rk_grf.c
@@ -55,6 +55,7 @@
{"rockchip,rk3568-pipe-grf", 1},
{"rockchip,rk3568-pipe-phy-grf", 1},
{"rockchip,rk3568-pcie3-phy-grf", 1},
+ {"rockchip,rk3308-grf", 1},
{NULL, 0}
};
Index: sys/arm64/rockchip/rk_pinctrl.c
===================================================================
--- sys/arm64/rockchip/rk_pinctrl.c
+++ sys/arm64/rockchip/rk_pinctrl.c
@@ -1004,11 +1004,195 @@
.get_bias_value = rk3568_get_bias_value,
};
+static struct rk_pinctrl_gpio rk3308_gpio_bank[] = {
+ RK_GPIO(0, "gpio0"),
+ RK_GPIO(1, "gpio1"),
+ RK_GPIO(2, "gpio2"),
+ RK_GPIO(3, "gpio3"),
+ RK_GPIO(4, "gpio4"),
+
+};
+
+static struct rk_pinctrl_bank rk3308_iomux_bank[] = {
+ /* bank sub offs nbits */
+ RK_IOMUX(0, 0, 0x0000, 2),
+ RK_IOMUX(0, 1, 0x0004, 2),
+ RK_IOMUX(0, 2, 0x0008, 2),
+ RK_IOMUX(0, 3, 0x000C, 2),
+ RK_IOMUX(1, 0, 0x0010, 2),
+ RK_IOMUX(1, 1, 0x0014, 2),
+ RK_IOMUX(1, 2, 0x0018, 2),
+ RK_IOMUX(1, 3, 0x001C, 2),
+ RK_IOMUX(2, 0, 0x0020, 2),
+ RK_IOMUX(2, 1, 0x0024, 2),
+ RK_IOMUX(2, 2, 0x0028, 2),
+ RK_IOMUX(2, 3, 0x002C, 2),
+ RK_IOMUX(3, 0, 0x0030, 2),
+ RK_IOMUX(3, 1, 0x0034, 2),
+ RK_IOMUX(3, 2, 0x0038, 2),
+ RK_IOMUX(3, 3, 0x003C, 2),
+ RK_IOMUX(4, 0, 0x0040, 2),
+ RK_IOMUX(4, 1, 0x0044, 2),
+ RK_IOMUX(4, 2, 0x0048, 2),
+ RK_IOMUX(4, 3, 0x004C, 2),
+};
+#define RK_PINFIX_MS(bank,pin,reg,bit,mask) RK_PINFIX(bank,pin,reg,bit,(mask << bit))
+static struct rk_pinctrl_pin_fixup rk3308_pin_fixup[] = {
+ /* bank pin reg bit mask */
+ RK_PINFIX_MS(1, 14, 0x28, 12, 0xf),
+ RK_PINFIX_MS(1, 15, 0x2c, 0, 0x3),
+ RK_PINFIX_MS(1, 18, 0x30, 4, 0xf),
+ RK_PINFIX_MS(1, 19, 0x30, 8, 0xf),
+ RK_PINFIX_MS(1, 20, 0x30, 12, 0xf),
+ RK_PINFIX_MS(1, 21, 0x34, 0, 0xf),
+ RK_PINFIX_MS(1, 22, 0x34, 4, 0xf),
+ RK_PINFIX_MS(1, 23, 0x34, 8, 0xf),
+ RK_PINFIX_MS(2, 2, 0x40, 4, 0x3),
+ RK_PINFIX_MS(2, 3, 0x40, 6, 0x3),
+ RK_PINFIX_MS(2, 16, 0x50, 0, 0x3),
+ RK_PINFIX_MS(3, 10, 0x68, 4, 0x3),
+ RK_PINFIX_MS(3, 11, 0x68, 6, 0x3),
+ RK_PINFIX_MS(3, 12, 0x68, 8, 0xf),
+ RK_PINFIX_MS(3, 13, 0x68, 12, 0xf),
+};
+static struct rk_pinctrl_pin_drive rk3308_pin_drive[] = {
+ /* bank sub offs val ma */
+ RK_PINDRIVE(0, 0, 0x100, 0, 2),
+ RK_PINDRIVE(0, 0, 0x100, 1, 4),
+ RK_PINDRIVE(0, 0, 0x100, 2, 8),
+ RK_PINDRIVE(0, 0, 0x100, 3, 12),
+
+ RK_PINDRIVE(0, 1, 0x104, 0, 2),
+ RK_PINDRIVE(0, 1, 0x104, 1, 4),
+ RK_PINDRIVE(0, 1, 0x104, 2, 8),
+ RK_PINDRIVE(0, 1, 0x104, 3, 12),
+
+ RK_PINDRIVE(0, 2, 0x108, 0, 2),
+ RK_PINDRIVE(0, 2, 0x108, 1, 4),
+ RK_PINDRIVE(0, 2, 0x108, 2, 8),
+ RK_PINDRIVE(0, 2, 0x108, 3, 12),
+
+ RK_PINDRIVE(0, 3, 0x10C, 0, 2),
+ RK_PINDRIVE(0, 3, 0x10C, 1, 4),
+ RK_PINDRIVE(0, 3, 0x10C, 2, 8),
+ RK_PINDRIVE(0, 3, 0x10C, 3, 12),
+
+ RK_PINDRIVE(1, 0, 0x110, 0, 2),
+ RK_PINDRIVE(1, 0, 0x110, 1, 4),
+ RK_PINDRIVE(1, 0, 0x110, 2, 8),
+ RK_PINDRIVE(1, 0, 0x110, 3, 12),
+
+ RK_PINDRIVE(1, 1, 0x114, 0, 2),
+ RK_PINDRIVE(1, 1, 0x114, 1, 4),
+ RK_PINDRIVE(1, 1, 0x114, 2, 8),
+ RK_PINDRIVE(1, 1, 0x114, 3, 12),
+
+ RK_PINDRIVE(1, 2, 0x118, 0, 2),
+ RK_PINDRIVE(1, 2, 0x118, 1, 4),
+ RK_PINDRIVE(1, 2, 0x118, 2, 8),
+ RK_PINDRIVE(1, 2, 0x118, 3, 12),
+
+ RK_PINDRIVE(1, 3, 0x11C, 0, 2),
+ RK_PINDRIVE(1, 3, 0x11C, 1, 4),
+ RK_PINDRIVE(1, 3, 0x11C, 2, 8),
+ RK_PINDRIVE(1, 3, 0x11C, 3, 12),
+
+ RK_PINDRIVE(2, 0, 0x120, 0, 2),
+ RK_PINDRIVE(2, 0, 0x120, 1, 4),
+ RK_PINDRIVE(2, 0, 0x120, 2, 8),
+ RK_PINDRIVE(2, 0, 0x120, 3, 12),
+
+ RK_PINDRIVE(2, 1, 0x124, 0, 2),
+ RK_PINDRIVE(2, 1, 0x124, 1, 4),
+ RK_PINDRIVE(2, 1, 0x124, 2, 8),
+ RK_PINDRIVE(2, 1, 0x124, 3, 12),
+
+ RK_PINDRIVE(2, 2, 0x128, 0, 2),
+ RK_PINDRIVE(2, 2, 0x128, 1, 4),
+ RK_PINDRIVE(2, 2, 0x128, 2, 8),
+ RK_PINDRIVE(2, 2, 0x128, 3, 12),
+
+ RK_PINDRIVE(2, 3, 0x12C, 0, 2),
+ RK_PINDRIVE(2, 3, 0x12C, 1, 4),
+ RK_PINDRIVE(2, 3, 0x12C, 2, 8),
+ RK_PINDRIVE(2, 3, 0x12C, 3, 12),
+
+ RK_PINDRIVE(3, 0, 0x130, 0, 2),
+ RK_PINDRIVE(3, 0, 0x130, 1, 4),
+ RK_PINDRIVE(3, 0, 0x130, 2, 8),
+ RK_PINDRIVE(3, 0, 0x130, 3, 12),
+
+ RK_PINDRIVE(3, 1, 0x134, 0, 2),
+ RK_PINDRIVE(3, 1, 0x134, 1, 4),
+ RK_PINDRIVE(3, 1, 0x134, 2, 8),
+ RK_PINDRIVE(3, 1, 0x134, 3, 12),
+
+ RK_PINDRIVE(3, 2, 0x138, 0, 2),
+ RK_PINDRIVE(3, 2, 0x138, 1, 4),
+ RK_PINDRIVE(3, 2, 0x138, 2, 8),
+ RK_PINDRIVE(3, 2, 0x138, 3, 12),
+
+ RK_PINDRIVE(3, 3, 0x13C, 0, 2),
+ RK_PINDRIVE(3, 3, 0x13C, 1, 4),
+ RK_PINDRIVE(3, 3, 0x13C, 2, 8),
+ RK_PINDRIVE(3, 3, 0x13C, 3, 12),
+
+ RK_PINDRIVE(4, 0, 0x140, 0, 2),
+ RK_PINDRIVE(4, 0, 0x140, 1, 4),
+ RK_PINDRIVE(4, 0, 0x140, 2, 8),
+ RK_PINDRIVE(4, 0, 0x140, 4, 12),
+
+ RK_PINDRIVE(4, 1, 0x144, 0, 2),
+ RK_PINDRIVE(4, 1, 0x144, 1, 4),
+ RK_PINDRIVE(4, 1, 0x144, 2, 8),
+ RK_PINDRIVE(4, 1, 0x144, 4, 12),
+
+ RK_PINDRIVE(4, 2, 0x148, 0, 2),
+ RK_PINDRIVE(4, 2, 0x148, 1, 4),
+ RK_PINDRIVE(4, 2, 0x148, 2, 8),
+ RK_PINDRIVE(4, 2, 0x148, 4, 12),
+
+ RK_PINDRIVE(4, 4, 0x14C, 0, 2),
+ RK_PINDRIVE(4, 4, 0x14C, 1, 4),
+ RK_PINDRIVE(4, 4, 0x14C, 2, 8),
+ RK_PINDRIVE(4, 4, 0x14C, 4, 12),
+
+};
+
+static uint32_t
+rk3308_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
+{
+ return (0xA0);
+}
+
+static struct syscon *
+rk3308_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
+{
+ return (sc->grf);
+}
+
+struct rk_pinctrl_conf rk3308_conf = {
+ .iomux_conf = rk3308_iomux_bank,
+ .iomux_nbanks = nitems(rk3308_iomux_bank),
+ .pin_fixup = rk3308_pin_fixup,
+ .npin_fixup = nitems(rk3308_pin_fixup),
+ .pin_drive = rk3308_pin_drive,
+ .npin_drive = nitems(rk3308_pin_drive),
+ .gpio_bank = rk3308_gpio_bank,
+ .ngpio_bank = nitems(rk3308_gpio_bank),
+ .get_pd_offset = rk3308_get_pd_offset,
+ .get_syscon = rk3308_get_syscon,
+ .parse_bias = rk3288_parse_bias,
+ .resolv_bias_value = rk3288_resolv_bias_value,
+ .get_bias_value = rk3288_get_bias_value,
+};
+
static struct ofw_compat_data compat_data[] = {
{"rockchip,rk3288-pinctrl", (uintptr_t)&rk3288_conf},
{"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf},
{"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf},
{"rockchip,rk3568-pinctrl", (uintptr_t)&rk3568_conf},
+ {"rockchip,rk3308-pinctrl", (uintptr_t)&rk3308_conf},
{NULL, 0}
};
Index: sys/arm64/rockchip/rk_pwm.c
===================================================================
--- sys/arm64/rockchip/rk_pwm.c
+++ sys/arm64/rockchip/rk_pwm.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
* Copyright (c) 2019 Brandon Bergren <git@bdragon.rtk0.net>
@@ -100,6 +100,7 @@
static struct ofw_compat_data compat_data[] = {
{ "rockchip,rk3288-pwm", 1 },
+ { "rockchip,rk3328-pwm", 1 },
{ "rockchip,rk3399-pwm", 1 },
{ NULL, 0 }
};
@@ -398,5 +399,7 @@
sizeof(struct rk_pwm_softc),
};
-DRIVER_MODULE(rk_pwm, simplebus, rk_pwm_driver, 0, 0);
+static devclass_t rk_pwm_devclass;
+
+EARLY_DRIVER_MODULE(rk_pwm, simplebus, rk_pwm_driver, rk_pwm_devclass, 0, 0,BUS_PASS_BUS + BUS_PASS_ORDER_LATE);
SIMPLEBUS_PNP_INFO(compat_data);
Index: sys/arm64/rockchip/rk_spi.c
===================================================================
--- sys/arm64/rockchip/rk_spi.c
+++ sys/arm64/rockchip/rk_spi.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2019 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
*
@@ -92,7 +92,7 @@
static struct ofw_compat_data compat_data[] = {
{ "rockchip,rk3328-spi", 1 },
{ "rockchip,rk3399-spi", 1 },
- { "rockchip,rk3568-spi", 1 },
+ { "rockchip,rk3308-spi", 1 },
{ NULL, 0 }
};
@@ -475,7 +475,9 @@
sizeof(struct rk_spi_softc),
};
-DRIVER_MODULE(rk_spi, simplebus, rk_spi_driver, 0, 0);
-DRIVER_MODULE(ofw_spibus, rk_spi, ofw_spibus_driver, 0, 0);
+static devclass_t rk_spi_devclass;
+
+DRIVER_MODULE(rk_spi, simplebus, rk_spi_driver, rk_spi_devclass, 0, 0);
+DRIVER_MODULE(ofw_spibus, rk_spi, ofw_spibus_driver, ofw_spibus_devclass, 0, 0);
MODULE_DEPEND(rk_spi, ofw_spibus, 1, 1, 1);
OFWBUS_PNP_INFO(compat_data);
Index: sys/arm64/rockchip/rk_tsadc.c
===================================================================
--- sys/arm64/rockchip/rk_tsadc.c
+++ sys/arm64/rockchip/rk_tsadc.c
@@ -262,6 +262,7 @@
}
};
+
static struct rk_calib_entry rk3399_calib_data[] = {
{402, -40000},
{410, -35000},
@@ -375,11 +376,33 @@
}
};
+static struct tsensor rk3308_tsensors[] = {
+ { .channel = 0, .id = 0, .name = "CPU"},
+ { .channel = 1, .id = 1, .name = "GPU"},
+};
+
+static struct tsadc_conf rk3308_tsadc_conf = {
+ .version = TSADC_V2,
+ .q_sel_ntc = 1,
+ .shutdown_temp = 95000,
+ .shutdown_mode = 0, /* CRU */
+ .shutdown_pol = 0, /* Low */
+ .tsensors = rk3308_tsensors,
+ .ntsensors = nitems(rk3308_tsensors),
+ .calib_info = {
+ .table = rk3328_calib_data,
+ .nentries = nitems(rk3328_calib_data),
+ }
+};
+
+
static struct ofw_compat_data compat_data[] = {
{"rockchip,rk3288-tsadc", (uintptr_t)&rk3288_tsadc_conf},
{"rockchip,rk3328-tsadc", (uintptr_t)&rk3328_tsadc_conf},
+ {"rockchip,rk3308-tsadc", (uintptr_t)&rk3328_tsadc_conf},
{"rockchip,rk3399-tsadc", (uintptr_t)&rk3399_tsadc_conf},
{"rockchip,rk3568-tsadc", (uintptr_t)&rk3568_tsadc_conf},
+ {"rockchip,rk3308-tsadc", (uintptr_t)&rk3308_tsadc_conf},
{NULL, 0}
};
Index: sys/arm64/rockchip/rk_usb2phy.c
===================================================================
--- sys/arm64/rockchip/rk_usb2phy.c
+++ sys/arm64/rockchip/rk_usb2phy.c
@@ -81,10 +81,19 @@
.disable_mask = 0x100010,
}
};
+struct rk_usb2phy_regs rk3308_regs = {
+ .clk_ctl = {
+ .offset = 0x0108,
+ .enable_mask = 0x100000,
+ /* bit 4 put pll in suspend */
+ .disable_mask = 0x100010,
+ }
+};
static struct ofw_compat_data compat_data[] = {
{ "rockchip,rk3399-usb2phy", (uintptr_t)&rk3399_regs },
{ "rockchip,rk3568-usb2phy", (uintptr_t)&rk3568_regs },
+ { "rockchip,rk3308-usb2phy", (uintptr_t)&rk3308_regs },
{ NULL, 0 }
};
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -1709,6 +1709,7 @@
dev/extres/regulator/regulator.c optional regulator
dev/extres/regulator/regulator_bus.c optional regulator fdt
dev/extres/regulator/regulator_fixed.c optional regulator
+dev/extres/regulator/regulator_pwm.c optional regulator fdt
dev/extres/syscon/syscon.c optional syscon
dev/extres/syscon/syscon_generic.c optional syscon fdt
dev/extres/syscon/syscon_if.m optional syscon
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -690,6 +690,7 @@
arm64/rockchip/clk/rk3399_pmucru.c optional fdt soc_rockchip_rk3399
arm64/rockchip/clk/rk3568_cru.c optional fdt soc_rockchip_rk3568
arm64/rockchip/clk/rk3568_pmucru.c optional fdt soc_rockchip_rk3568
+arm64/rockchip/clk/rk3308_cru.c optional fdt soc_rockchip_rk3308
# Xilinx
arm/xilinx/uart_dev_cdnc.c optional uart soc_xilinx_zynq fdt
Index: sys/dev/extres/regulator/regulator_pwm.h
===================================================================
--- /dev/null
+++ sys/dev/extres/regulator/regulator_pwm.h
@@ -0,0 +1,16 @@
+#ifndef _DEV_EXTRES_REGULATOR_PWM_H_
+#define _DEV_EXTRES_REGULATOR_PWM_H_
+
+#include <dev/gpio/gpiobusvar.h>
+#include <dev/extres/regulator/regulator.h>
+
+struct regnode_pwm_init_def {
+ struct regnode_init_def reg_init_def;
+ bool gpio_open_drain;
+ struct gpiobus_pin *gpio_pin;
+};
+
+int regnode_pwm_register(device_t dev,
+ struct regnode_pwm_init_def *init_def);
+
+#endif /*_DEV_EXTRES_REGULATOR_PWM_H_*/
Index: sys/dev/extres/regulator/regulator_pwm.c
===================================================================
--- /dev/null
+++ sys/dev/extres/regulator/regulator_pwm.c
@@ -0,0 +1,560 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_platform.h"
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/gpio.h>
+#include <sys/kernel.h>
+#include <sys/kobj.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include "pwmbus_if.h"
+#endif
+#include <dev/gpio/gpiobusvar.h>
+#include <dev/pwm/pwmbus.h>
+#include <dev/extres/regulator/regulator_pwm.h>
+
+#include "regdev_if.h"
+
+MALLOC_DEFINE(M_PWMREGULATOR, "pwmregulator", "PWM regulator");
+
+/* GPIO list for shared pins. */
+typedef TAILQ_HEAD(gpio_list, gpio_entry) gpio_list_t;
+struct gpio_entry {
+ TAILQ_ENTRY(gpio_entry) link;
+ struct gpiobus_pin gpio_pin;
+ int use_cnt;
+ int enable_cnt;
+ bool always_on;
+};
+static gpio_list_t gpio_list = TAILQ_HEAD_INITIALIZER(gpio_list);
+static struct mtx gpio_list_mtx;
+MTX_SYSINIT(gpio_list_lock, &gpio_list_mtx, "Regulator GPIO lock", MTX_DEF);
+
+struct regnode_pwm_sc {
+ struct regnode_std_param *param;
+ bool gpio_open_drain;
+ struct gpio_entry *gpio_entry;
+};
+
+static int regnode_pwm_init(struct regnode *regnode);
+static int regnode_pwm_enable(struct regnode *regnode, bool enable,
+ int *udelay);
+static int regnode_pwm_status(struct regnode *regnode, int *status);
+static int regnode_pwm_stop(struct regnode *regnode, int *udelay);
+static int regnode_pwm_get_voltage(struct regnode *regnode, int *uvolt);
+static int regnode_pwm_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt,int *udelay);
+
+static regnode_method_t regnode_pwm_methods[] = {
+ /* Regulator interface */
+ REGNODEMETHOD(regnode_init, regnode_pwm_init),
+ REGNODEMETHOD(regnode_enable, regnode_pwm_enable),
+ REGNODEMETHOD(regnode_status, regnode_pwm_status),
+ REGNODEMETHOD(regnode_stop, regnode_pwm_stop),
+ REGNODEMETHOD(regnode_get_voltage, regnode_pwm_get_voltage),
+ REGNODEMETHOD(regnode_set_voltage, regnode_pwm_set_voltage),
+ REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage),
+ REGNODEMETHOD_END
+};
+DEFINE_CLASS_1(regnode_pwm, regnode_pwm_class, regnode_pwm_methods,
+ sizeof(struct regnode_pwm_sc), regnode_class);
+
+/*
+ * GPIO list functions.
+ * Two or more regulators can share single GPIO pins, so we must track all
+ * GPIOs in gpio_list.
+ * The GPIO pin is registerd and reseved for first consumer, all others share
+ * gpio_entry with it.
+ */
+static struct gpio_entry *
+regnode_get_gpio_entry(struct gpiobus_pin *gpio_pin)
+{
+ struct gpio_entry *entry, *tmp;
+ device_t busdev;
+ int rv;
+
+ busdev = GPIO_GET_BUS(gpio_pin->dev);
+ if (busdev == NULL)
+ return (NULL);
+ entry = malloc(sizeof(struct gpio_entry), M_PWMREGULATOR,
+ M_WAITOK | M_ZERO);
+
+ mtx_lock(&gpio_list_mtx);
+
+ TAILQ_FOREACH(tmp, &gpio_list, link) {
+ if (tmp->gpio_pin.dev == gpio_pin->dev &&
+ tmp->gpio_pin.pin == gpio_pin->pin) {
+ tmp->use_cnt++;
+ mtx_unlock(&gpio_list_mtx);
+ free(entry, M_PWMREGULATOR);
+ return (tmp);
+ }
+ }
+
+ /* Reserve pin. */
+ /* XXX Can we call gpiobus_acquire_pin() with gpio_list_mtx held? */
+ rv = gpiobus_acquire_pin(busdev, gpio_pin->pin);
+ if (rv != 0) {
+ mtx_unlock(&gpio_list_mtx);
+ free(entry, M_PWMREGULATOR);
+ return (NULL);
+ }
+ /* Everything is OK, build new entry and insert it to list. */
+ entry->gpio_pin = *gpio_pin;
+ entry->use_cnt = 1;
+ TAILQ_INSERT_TAIL(&gpio_list, entry, link);
+
+ mtx_unlock(&gpio_list_mtx);
+ return (entry);
+}
+
+#ifdef FDT
+#include <dev/pwm/ofw_pwm.h>
+struct regpwm_softc
+{
+ device_t dev;
+ bool attach_done;
+ struct regnode_pwm_init_def init_def;
+ phandle_t gpio_prodxref;
+ pcell_t *gpio_cells;
+ int gpio_ncells;
+ struct gpiobus_pin gpio_pin;
+ pwm_channel_t channel;
+ uint32_t sc_dutycycle_unit;
+ uint32_t sc_dutycycle_range[2];
+};
+#endif
+/*
+ * Regulator class implementation.
+ */
+static int
+regnode_pwm_init(struct regnode *regnode)
+{
+ device_t dev;
+ struct regnode_pwm_sc *sc;
+ struct gpiobus_pin *pin;
+ uint32_t flags;
+ int rv;
+
+ sc = regnode_get_softc(regnode);
+ dev = regnode_get_device(regnode);
+ sc->param = regnode_get_stdparam(regnode);
+ if (sc->gpio_entry == NULL)
+ return (0);
+ pin = &sc->gpio_entry->gpio_pin;
+
+ flags = GPIO_PIN_OUTPUT;
+ if (sc->gpio_open_drain)
+ flags |= GPIO_PIN_OPENDRAIN;
+ if (sc->param->boot_on || sc->param->always_on) {
+ rv = GPIO_PIN_SET(pin->dev, pin->pin, sc->param->enable_active_high);
+ if (rv != 0) {
+ device_printf(dev, "Cannot set GPIO pin: %d\n",
+ pin->pin);
+ return (rv);
+ }
+ }
+
+ rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags);
+ if (rv != 0) {
+ device_printf(dev, "Cannot configure GPIO pin: %d\n", pin->pin);
+ return (rv);
+ }
+
+ return (0);
+}
+
+/*
+ * Enable/disable regulator.
+ * Take shared GPIO pins in account
+ */
+static int
+regnode_pwm_enable(struct regnode *regnode, bool enable, int *udelay)
+{
+ device_t dev;
+ struct regnode_pwm_sc *sc;
+ struct gpiobus_pin *pin;
+ int rv;
+
+ sc = regnode_get_softc(regnode);
+ dev = regnode_get_device(regnode);
+
+ *udelay = 0;
+ if (sc->gpio_entry == NULL)
+ return (0);
+ pin = &sc->gpio_entry->gpio_pin;
+ if (enable) {
+ sc->gpio_entry->enable_cnt++;
+ if (sc->gpio_entry->enable_cnt > 1)
+ return (0);
+ } else {
+ KASSERT(sc->gpio_entry->enable_cnt > 0,
+ ("Invalid enable count"));
+ sc->gpio_entry->enable_cnt--;
+ if (sc->gpio_entry->enable_cnt >= 1)
+ return (0);
+ }
+ if (sc->gpio_entry->always_on && !enable)
+ return (0);
+ if (!sc->param->enable_active_high)
+ enable = !enable;
+ rv = GPIO_PIN_SET(pin->dev, pin->pin, enable);
+ if (rv != 0) {
+ device_printf(dev, "Cannot set GPIO pin: %d\n", pin->pin);
+ return (rv);
+ }
+ *udelay = sc->param->enable_delay;
+ return (0);
+}
+
+/*
+ * Stop (physicaly shutdown) regulator.
+ * Take shared GPIO pins in account
+ */
+static int
+regnode_pwm_stop(struct regnode *regnode, int *udelay)
+{
+ device_t dev;
+ struct regnode_pwm_sc *sc;
+ struct gpiobus_pin *pin;
+ int rv;
+
+ sc = regnode_get_softc(regnode);
+ dev = regnode_get_device(regnode);
+
+ *udelay = 0;
+ if (sc->gpio_entry == NULL)
+ return (0);
+ if (sc->gpio_entry->always_on)
+ return (0);
+ pin = &sc->gpio_entry->gpio_pin;
+ if (sc->gpio_entry->enable_cnt > 0) {
+ /* Other regulator(s) are enabled. */
+ /* XXXX Any diagnostic message? Or error? */
+ return (0);
+ }
+ rv = GPIO_PIN_SET(pin->dev, pin->pin,
+ sc->param->enable_active_high ? false: true);
+ if (rv != 0) {
+ device_printf(dev, "Cannot set GPIO pin: %d\n", pin->pin);
+ return (rv);
+ }
+ *udelay = sc->param->enable_delay;
+ return (0);
+}
+
+static int
+regnode_pwm_status(struct regnode *regnode, int *status)
+{
+ struct regnode_pwm_sc *sc;
+ struct gpiobus_pin *pin;
+ uint32_t val;
+ int rv;
+
+ sc = regnode_get_softc(regnode);
+
+ *status = 0;
+ if (sc->gpio_entry == NULL) {
+ *status = REGULATOR_STATUS_ENABLED;
+ return (0);
+ }
+ pin = &sc->gpio_entry->gpio_pin;
+
+ rv = GPIO_PIN_GET(pin->dev, pin->pin, &val);
+ if (rv == 0) {
+ if (!sc->param->enable_active_high ^ (val != 0))
+ *status = REGULATOR_STATUS_ENABLED;
+ }
+ return (rv);
+}
+static int
+regnode_pwm_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt, int * udelay)
+{
+ struct regnode_pwm_sc *sc;
+ struct regpwm_softc *dsc;
+ int32_t x0, x1, y0, y1;
+ int32_t x, y;
+ bool enabled;
+
+ sc = regnode_get_softc(regnode);
+ dsc = device_get_softc(regnode_get_device(regnode));
+ PWMBUS_CHANNEL_IS_ENABLED(dsc->channel->dev,dsc->channel->channel, &enabled);
+ if(!enabled)
+ return 0;
+
+ x0 = sc->param->min_uvolt;
+ x1 = sc->param->max_uvolt;
+ y0 = dsc->sc_dutycycle_range[0];
+ y1 = dsc->sc_dutycycle_range[1];
+ x = min_uvolt;
+ y = y0 + (x - x0) * (y1 - y0) / (x1 - x0);
+ dsc->channel->duty = (y * dsc->channel->period) / dsc->sc_dutycycle_unit;
+ PWMBUS_CHANNEL_CONFIG(dsc->channel->dev,dsc->channel->channel,
+ dsc->channel->period, dsc->channel->duty);
+ return 0;
+}
+
+static int
+regnode_pwm_get_voltage(struct regnode *regnode, int *uvolt)
+{
+ struct regnode_pwm_sc *sc;
+ struct regpwm_softc *dsc;
+ int32_t x0, x1, y0, y1;
+ int32_t x, y;
+ bool enabled;
+
+ sc = regnode_get_softc(regnode);
+ dsc = device_get_softc(regnode_get_device(regnode));
+ PWMBUS_CHANNEL_IS_ENABLED(dsc->channel->dev,dsc->channel->channel, &enabled);
+ if(!enabled)
+ return 0;
+
+ PWMBUS_CHANNEL_GET_CONFIG(dsc->channel->dev,dsc->channel->channel,
+ (u_int *) &dsc->channel->period, (u_int *)&dsc->channel->duty);
+
+ x0 = dsc->sc_dutycycle_range[0];
+ x1 = dsc->sc_dutycycle_range[1];
+ y0 = sc->param->min_uvolt;
+ y1 = sc->param->max_uvolt;
+ x = (dsc->channel->duty * dsc->sc_dutycycle_unit) / dsc->channel->period;
+ y = y0 + (x - x0) * (y1 - y0) / (x1 - x0);
+
+ *uvolt = y;
+ return (0);
+}
+
+int
+regnode_pwm_register(device_t dev, struct regnode_pwm_init_def *init_def)
+{
+ struct regnode *regnode;
+ struct regnode_pwm_sc *sc;
+
+ regnode = regnode_create(dev, ®node_pwm_class,
+ &init_def->reg_init_def);
+ if (regnode == NULL) {
+ device_printf(dev, "Cannot create regulator.\n");
+ return(ENXIO);
+ }
+ sc = regnode_get_softc(regnode);
+ sc->gpio_open_drain = init_def->gpio_open_drain;
+ if (init_def->gpio_pin != NULL) {
+ sc->gpio_entry = regnode_get_gpio_entry(init_def->gpio_pin);
+ if (sc->gpio_entry == NULL)
+ return(ENXIO);
+ }
+ regnode = regnode_register(regnode);
+ if (regnode == NULL) {
+ device_printf(dev, "Cannot register regulator.\n");
+ return(ENXIO);
+ }
+
+ if (sc->gpio_entry != NULL)
+ sc->gpio_entry->always_on |= sc->param->always_on;
+
+ return (0);
+}
+
+/*
+ * OFW Driver implementation.
+ */
+#ifdef FDT
+static struct ofw_compat_data compat_data[] = {
+ {"pwm-regulator", 1},
+ {NULL, 0},
+};
+
+static int
+regpwm_get_gpio(struct regpwm_softc * sc)
+{
+ device_t busdev;
+ phandle_t node;
+
+ int rv;
+
+ if (sc->gpio_prodxref == 0)
+ return (0);
+
+ node = ofw_bus_get_node(sc->dev);
+
+ /* Test if controller exist. */
+ sc->gpio_pin.dev = OF_device_from_xref(sc->gpio_prodxref);
+ if (sc->gpio_pin.dev == NULL)
+ return (ENODEV);
+
+ /* Test if GPIO bus already exist. */
+ busdev = GPIO_GET_BUS(sc->gpio_pin.dev);
+ if (busdev == NULL)
+ return (ENODEV);
+
+ rv = gpio_map_gpios(sc->gpio_pin.dev, node,
+ OF_node_from_xref(sc->gpio_prodxref), sc->gpio_ncells,
+ sc->gpio_cells, &(sc->gpio_pin.pin), &(sc->gpio_pin.flags));
+ if (rv != 0) {
+ device_printf(sc->dev, "Cannot map the gpio property.\n");
+ return (ENXIO);
+ }
+ sc->init_def.gpio_pin = &sc->gpio_pin;
+ return (0);
+}
+
+static int
+regpwm_parse_fdt(struct regpwm_softc * sc)
+{
+ phandle_t node;
+ int rv;
+ int len;
+ struct regnode_init_def *init_def;
+
+ node = ofw_bus_get_node(sc->dev);
+ init_def = &sc->init_def.reg_init_def;
+
+ rv = regulator_parse_ofw_stdparam(sc->dev, node, init_def);
+ if (rv != 0) {
+ device_printf(sc->dev, "Cannot parse standard parameters.\n");
+ return(rv);
+ }
+ len = OF_getproplen(node, "pwms");
+ if (len <= 4) {
+ device_printf(sc->dev, ": no pwms property\n");
+ return ENXIO;
+ }
+
+ if (OF_getproplen(node, "voltage-tables") > 0) {
+ device_printf(sc->dev, ": voltage table mode unsupported\n");
+ return ENXIO;
+ }
+
+ if (init_def->std_param.min_uvolt > init_def->std_param.max_uvolt) {
+ device_printf(sc->dev, "min_uvolt > max_uvolt\n");
+ return (ENXIO);
+ }
+ rv = pwm_get_by_ofw_propidx(sc->dev, node, "pwms", 0, &sc->channel);
+ if (rv != 0) {
+ device_printf(sc->dev, "Cannot map pwm channel %d\n", rv);
+ return (ENXIO);
+ }
+
+ rv = OF_getencprop(node, "pwm-dutycycle-unit", &sc->sc_dutycycle_unit,
+ sizeof(sc->sc_dutycycle_unit));
+ if(rv <= 0) sc->sc_dutycycle_unit = 100;
+ sc->sc_dutycycle_range[0] = 0;
+ sc->sc_dutycycle_range[1] = 100;
+ rv = OF_getencprop(node, "pwm-dutycycle-range",
+ sc->sc_dutycycle_range, sizeof(sc->sc_dutycycle_range));
+// device_printf(sc->dev,"%x %x\n",sc->sc_dutycycle_range[0],sc->sc_dutycycle_range[1]);
+ /* PWM regulator uses 'startup-delay-us' property for enable_delay */
+/*
+ if (!OF_hasprop(node, "gpio"))
+ return (0);
+ rv = ofw_bus_parse_xref_list_alloc(node, "gpio", "#gpio-cells", 0,
+ &sc->gpio_prodxref, &sc->gpio_ncells, &sc->gpio_cells);
+ if (rv != 0) {
+ sc->gpio_prodxref = 0;
+ device_printf(sc->dev, "Malformed gpio property\n");
+ return (ENXIO);
+ }
+*/
+ return (0);
+}
+
+static void
+regpwm_new_pass(device_t dev)
+{
+ struct regpwm_softc * sc;
+ int rv;
+
+ sc = device_get_softc(dev);
+ bus_generic_new_pass(dev);
+
+ if (sc->attach_done)
+ return;
+
+ /* Try to get and configure GPIO. */
+ rv = regpwm_get_gpio(sc);
+ if (rv != 0)
+ return;
+
+ /* Register regulator. */
+ regnode_pwm_register(sc->dev, &sc->init_def);
+ sc->attach_done = true;
+}
+
+static int
+regpwm_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, "PWM Regulator");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+regpwm_detach(device_t dev)
+{
+
+ /* This device is always present. */
+ return (EBUSY);
+}
+
+static int
+regpwm_attach(device_t dev)
+{
+ struct regpwm_softc * sc;
+ int rv;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Parse FDT data. */
+ rv = regpwm_parse_fdt(sc);
+ if (rv != 0)
+ return(ENXIO);
+
+ /* Fill reset of init. */
+ sc->init_def.reg_init_def.id = 1;
+ sc->init_def.reg_init_def.flags = REGULATOR_FLAGS_STATIC;
+
+ /* Try to get and configure GPIO. */
+ rv = regpwm_get_gpio(sc);
+ if (rv != 0)
+ return (bus_generic_attach(dev));
+
+ /* Register regulator. */
+ regnode_pwm_register(sc->dev, &sc->init_def);
+ sc->attach_done = true;
+
+ return (bus_generic_attach(dev));
+}
+
+static device_method_t regpwm_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, regpwm_probe),
+ DEVMETHOD(device_attach, regpwm_attach),
+ DEVMETHOD(device_detach, regpwm_detach),
+ /* Bus interface */
+ DEVMETHOD(bus_new_pass, regpwm_new_pass),
+ /* Regdev interface */
+ DEVMETHOD(regdev_map, regdev_default_ofw_map),
+
+ DEVMETHOD_END
+};
+
+static devclass_t regpwm_devclass;
+DEFINE_CLASS_0(regpwm, regpwm_driver, regpwm_methods,
+ sizeof(struct regpwm_softc));
+EARLY_DRIVER_MODULE(regpwm, simplebus, regpwm_driver,
+ regpwm_devclass, 0, 0, BUS_PASS_BUS);
+
+#endif /* FDT */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 22, 11:03 AM (9 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37072401
Default Alt Text
D40712.id123644.diff (64 KB)
Attached To
Mode
D40712: support for rockchip rk3308
Attached
Detach File
Event Timeline
Log In to Comment