Page MenuHomeFreeBSD

D40712.diff
No OneTemporary

D40712.diff

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, &regnode_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

Mime Type
text/plain
Expires
Sat, Aug 22, 11:01 AM (1 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37072401
Default Alt Text
D40712.diff (64 KB)

Event Timeline