diff --git a/sys/arm/allwinner/clkng/aw_clk.h b/sys/arm/allwinner/clkng/aw_clk.h index 027766dc5a80..35b2b26d70ee 100644 --- a/sys/arm/allwinner/clkng/aw_clk.h +++ b/sys/arm/allwinner/clkng/aw_clk.h @@ -64,6 +64,7 @@ struct aw_clk_init { #define AW_CLK_REPARENT 0x0008 #define AW_CLK_SCALE_CHANGE 0x0010 #define AW_CLK_HAS_FRAC 0x0020 +#define AW_CLK_HAS_UPDATE 0x0040 #define AW_CLK_FACTOR_POWER_OF_TWO 0x0001 #define AW_CLK_FACTOR_ZERO_BASED 0x0002 @@ -218,6 +219,48 @@ aw_clk_factor_get_value(struct aw_clk_factor *factor, uint32_t raw) .flags = _flags, \ } +#define NKMP_CLK_WITH_UPDATE(_clkname, \ + _id, _name, _pnames, \ + _offset, \ + _n_shift, _n_width, _n_value, _n_flags, \ + _k_shift, _k_width, _k_value, _k_flags, \ + _m_shift, _m_width, _m_value, _m_flags, \ + _p_shift, _p_width, _p_value, _p_flags, \ + _gate, \ + _lock, _lock_retries, \ + _update, \ + _flags) \ + static struct aw_clk_nkmp_def _clkname = { \ + .clkdef = { \ + .id = _id, \ + .name = _name, \ + .parent_names = _pnames, \ + .parent_cnt = nitems(_pnames), \ + }, \ + .offset = _offset, \ + .n.shift = _n_shift, \ + .n.width = _n_width, \ + .n.value = _n_value, \ + .n.flags = _n_flags, \ + .k.shift = _k_shift, \ + .k.width = _k_width, \ + .k.value = _k_value, \ + .k.flags = _k_flags, \ + .m.shift = _m_shift, \ + .m.width = _m_width, \ + .m.value = _m_value, \ + .m.flags = _m_flags, \ + .p.shift = _p_shift, \ + .p.width = _p_width, \ + .p.value = _p_value, \ + .p.flags = _p_flags, \ + .gate_shift = _gate, \ + .lock_shift = _lock, \ + .lock_retries = _lock_retries, \ + .update_shift = _update, \ + .flags = _flags | AW_CLK_HAS_UPDATE, \ + } + #define NM_CLK(_clkname, _id, _name, _pnames, \ _offset, \ _nshift, _nwidth, _nvalue, _nflags, \ diff --git a/sys/arm/allwinner/clkng/aw_clk_nkmp.c b/sys/arm/allwinner/clkng/aw_clk_nkmp.c index 668406e49b35..b72b89b33c7a 100644 --- a/sys/arm/allwinner/clkng/aw_clk_nkmp.c +++ b/sys/arm/allwinner/clkng/aw_clk_nkmp.c @@ -58,6 +58,7 @@ struct aw_clk_nkmp_sc { uint32_t gate_shift; uint32_t lock_shift; uint32_t lock_retries; + uint32_t update_shift; uint32_t flags; }; @@ -263,6 +264,14 @@ aw_clk_nkmp_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, WRITE4(clk, sc->offset, val); DELAY(2000); + if ((sc->flags & AW_CLK_HAS_UPDATE) != 0) { + DEVICE_LOCK(clk); + READ4(clk, sc->offset, &val); + val |= 1 << sc->update_shift; + WRITE4(clk, sc->offset, val); + DELAY(2000); + } + if ((sc->flags & AW_CLK_HAS_LOCK) != 0) { for (retry = 0; retry < sc->lock_retries; retry++) { READ4(clk, sc->offset, &val); @@ -354,6 +363,7 @@ aw_clk_nkmp_register(struct clkdom *clkdom, struct aw_clk_nkmp_def *clkdef) sc->gate_shift = clkdef->gate_shift; sc->lock_shift = clkdef->lock_shift; sc->lock_retries = clkdef->lock_retries; + sc->update_shift = clkdef->update_shift; sc->flags = clkdef->flags; clknode_register(clkdom, clk); diff --git a/sys/arm/allwinner/clkng/aw_clk_nkmp.h b/sys/arm/allwinner/clkng/aw_clk_nkmp.h index 4f38efab7e14..a0b9b780ffaf 100644 --- a/sys/arm/allwinner/clkng/aw_clk_nkmp.h +++ b/sys/arm/allwinner/clkng/aw_clk_nkmp.h @@ -44,6 +44,7 @@ struct aw_clk_nkmp_def { uint32_t gate_shift; uint32_t lock_shift; uint32_t lock_retries; + uint32_t update_shift; uint32_t flags; }; diff --git a/sys/arm/allwinner/clkng/ccu_h3.c b/sys/arm/allwinner/clkng/ccu_h3.c index ea497cdab646..8158964e670c 100644 --- a/sys/arm/allwinner/clkng/ccu_h3.c +++ b/sys/arm/allwinner/clkng/ccu_h3.c @@ -177,15 +177,17 @@ static struct aw_ccung_gate h3_ccu_gates[] = { CCU_GATE(H3_CLK_I2S1, "i2s1", "i2s1mux", 0xB4, 31) CCU_GATE(H3_CLK_I2S2, "i2s2", "i2s2mux", 0xB8, 31) - /* CCU_GATE(H3_CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) */ - /* CCU_GATE(H3_CLK_DRAM_VE, "dram-csi", "dram", 0x100, 1) */ - /* CCU_GATE(H3_CLK_DRAM_VE, "dram-deinterlace", "dram", 0x100, 2) */ - /* CCU_GATE(H3_CLK_DRAM_VE, "dram-ts", "dram", 0x100, 3) */ + CCU_GATE(H3_CLK_DRAM_VE, "dram-ve", "dram", 0x100, 0) + CCU_GATE(H3_CLK_DRAM_CSI, "dram-csi", "dram", 0x100, 1) + CCU_GATE(H3_CLK_DRAM_DEINTERLACE, "dram-deinterlace", "dram", 0x100, 2) + CCU_GATE(H3_CLK_DRAM_TS, "dram-ts", "dram", 0x100, 3) CCU_GATE(H3_CLK_AC_DIG, "ac-dig", "pll_audio", 0x140, 31) CCU_GATE(H3_CLK_AVS, "avs", "osc24M", 0x144, 31) + CCU_GATE(H3_CLK_CSI_MISC, "csi-misc", "osc24M", 0x130, 31) + CCU_GATE(H3_CLK_HDMI_DDC, "hdmi-ddc", "osc24M", 0x154, 31) }; @@ -265,10 +267,19 @@ NM_CLK_WITH_FRAC(pll_ve_clk, 270000000, 297000000, /* freq0, freq1 */ 24, 25); /* mode sel, freq sel */ -/* - * Needs a update bit on nkmp or special clk static const char *pll_ddr_parents[] = {"osc24M"}; - */ +NKMP_CLK_WITH_UPDATE(pll_ddr_clk, + H3_CLK_PLL_DDR, /* id */ + "pll_ddr", pll_ddr_parents, /* name, parents */ + 0x20, /* offset */ + 8, 5, 0, 0, /* n factor */ + 4, 2, 0, 0, /* k factor */ + 0, 2, 0, 0, /* m factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* p factor (fake) */ + 31, /* gate */ + 28, 1000, /* lock */ + 20, /* update */ + AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ static const char *pll_periph0_parents[] = {"osc24M"}; static const char *pll_periph0_2x_parents[] = {"pll_periph0"}; @@ -283,6 +294,14 @@ NKMP_CLK(pll_periph0_clk, 31, /* gate */ 28, 1000, /* lock */ AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ +FIXED_CLK(pll_periph0_2x_clk, + H3_CLK_PLL_PERIPH0_2X, /* id */ + "pll_periph0-2x", /* name */ + pll_periph0_2x_parents, /* parent */ + 0, /* freq */ + 2, /* mult */ + 1, /* div */ + 0); /* flags */ static const char *pll_gpu_parents[] = {"osc24M"}; NM_CLK_WITH_FRAC(pll_gpu_clk, @@ -496,32 +515,122 @@ NM_CLK(spdif_clk, 31, /* gate */ AW_CLK_HAS_GATE); /* flags */ -FIXED_CLK(pll_periph0_2x_clk, - H3_CLK_PLL_PERIPH0_2X, /* id */ - "pll_periph0-2x", /* name */ - pll_periph0_2x_parents, /* parent */ - 0, /* freq */ - 2, /* mult */ - 1, /* div */ - 0); /* flags */ +static const char *dram_parents[] = {"pll_ddr", "pll_periph0-2x"}; +NM_CLK(dram_clk, + H3_CLK_DRAM, "dram", dram_parents, /* id, name, parents */ + 0xF4, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 20, 2, /* mux */ + 0, /* gate */ + AW_CLK_HAS_MUX); /* flags */ -/* DRAM clock 0xF4 */ -/* DE gating 0x104 */ -/* TCON0 0x118 */ -/* TVE 0x120 */ -/* Deinterlace 0x124 */ -/* CSI_MISC 0x130 */ -/* CSI 0x134 */ -/* VE 0x13C */ -/* HDMI 0x150 */ -/* MBUS 0x15C */ -/* GPU 0x1A0 */ +static const char *de_parents[] = {"pll_periph0-2x", "pll_de"}; +NM_CLK(de_clk, + H3_CLK_DE, "de", de_parents, /* id, name, parents */ + 0x104, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *tcon0_parents[] = {"pll_video"}; +NM_CLK(tcon0_clk, + H3_CLK_TCON0, "tcon0", tcon0_parents, /* id, name, parents */ + 0x118, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *tve_parents[] = {"pll_de", "pll_periph1"}; +NM_CLK(tve_clk, + H3_CLK_TVE, "tve", tve_parents, /* id, name, parents */ + 0x120, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *deinterlace_parents[] = {"pll_periph0", "pll_periph1"}; +NM_CLK(deinterlace_clk, + H3_CLK_DEINTERLACE, "deinterlace", deinterlace_parents, /* id, name, parents */ + 0x124, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *csi_sclk_parents[] = {"pll_periph0", "pll_periph1"}; +NM_CLK(csi_sclk_clk, + H3_CLK_CSI_SCLK, "csi-sclk", csi_sclk_parents, /* id, name, parents */ + 0x134, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 16, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *csi_mclk_parents[] = {"osc24M", "pll_video", "pll_periph1"}; +NM_CLK(csi_mclk_clk, + H3_CLK_CSI_MCLK, "csi-mclk", csi_mclk_parents, /* id, name, parents */ + 0x134, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 8, 2, /* mux */ + 15, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *ve_parents[] = {"pll_ve"}; +NM_CLK(ve_clk, + H3_CLK_VE, "ve", ve_parents, /* id, name, parents */ + 0x13C, /* offset */ + 16, 3, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE); /* flags */ + +static const char *hdmi_parents[] = {"pll_video"}; +NM_CLK(hdmi_clk, + H3_CLK_HDMI, "hdmi", hdmi_parents, /* id, name, parents */ + 0x150, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 4, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *mbus_parents[] = {"osc24M", "pll_periph0-2x", "pll_ddr"}; +NM_CLK(mbus_clk, + H3_CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ + 0x15C, /* offset */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* n factor (fake) */ + 0, 3, 0, 0, /* m factor */ + 24, 2, /* mux */ + 31, /* gate */ + AW_CLK_HAS_MUX | AW_CLK_HAS_GATE); /* flags */ + +static const char *gpu_parents[] = {"pll_gpu"}; +NM_CLK(gpu_clk, + H3_CLK_GPU, "gpu", gpu_parents, /* id, name, parents */ + 0x1A0, /* offset */ + 0, 2, 0, 0, /* n factor */ + 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor (fake) */ + 0, 0, /* mux */ + 31, /* gate */ + AW_CLK_HAS_GATE); /* flags */ static struct aw_clk_nkmp_def *nkmp_clks[] = { &pll_cpux_clk, &pll_audio_clk, &pll_periph0_clk, &pll_periph1_clk, + &pll_ddr_clk, }; static struct aw_clk_nm_def *nm_clks[] = { @@ -539,6 +648,17 @@ static struct aw_clk_nm_def *nm_clks[] = { &spi0_clk, &spi1_clk, &spdif_clk, + &dram_clk, + &de_clk, + &tcon0_clk, + &tve_clk, + &deinterlace_clk, + &csi_sclk_clk, + &csi_mclk_clk, + &ve_clk, + &hdmi_clk, + &mbus_clk, + &gpu_clk, }; static struct aw_clk_prediv_mux_def *prediv_mux_clks[] = { @@ -569,6 +689,7 @@ static struct clk_fixed_def *fixed_factor_clks[] = { static struct aw_clk_init init_clks[] = { {"ahb1", "pll_periph0", 0, false}, {"ahb2", "pll_periph0", 0, false}, + {"dram", "pll_ddr", 0, false}, }; void diff --git a/sys/arm/allwinner/clkng/ccu_h3.h b/sys/arm/allwinner/clkng/ccu_h3.h index c5b7caf00800..0144255f74cb 100644 --- a/sys/arm/allwinner/clkng/ccu_h3.h +++ b/sys/arm/allwinner/clkng/ccu_h3.h @@ -98,14 +98,12 @@ #define H3_CLK_PLL_GPU 11 #define H3_CLK_PLL_PERIPH1 12 #define H3_CLK_PLL_DE 13 - #define H3_CLK_CPUX 14 #define H3_CLK_AXI 15 #define H3_CLK_AHB1 16 #define H3_CLK_APB1 17 #define H3_CLK_APB2 18 #define H3_CLK_AHB2 19 - #define H3_CLK_BUS_CE 20 #define H3_CLK_BUS_DMA 21 #define H3_CLK_BUS_MMC0 22 @@ -155,7 +153,6 @@ #define H3_CLK_BUS_SCR 66 #define H3_CLK_BUS_EPHY 67 #define H3_CLK_BUS_DBG 68 - #define H3_CLK_THS 69 #define H3_CLK_NAND 70 #define H3_CLK_MMC0 71 @@ -183,7 +180,7 @@ #define H3_CLK_USBOHCI1 93 #define H3_CLK_USBOHCI2 94 #define H3_CLK_USBOHCI3 95 - +#define H3_CLK_DRAM 96 #define H3_CLK_DRAM_VE 97 #define H3_CLK_DRAM_CSI 98 #define H3_CLK_DRAM_DEINTERLACE 99 @@ -200,7 +197,7 @@ #define H3_CLK_AVS 110 #define H3_CLK_HDMI 111 #define H3_CLK_HDMI_DDC 112 - +#define H3_CLK_MBUS 113 #define H3_CLK_GPU 114 void ccu_h3_register_clocks(struct aw_ccung_softc *sc);