/* $NetBSD: mesong12_clkc.c,v 1.6 2021/02/04 22:55:36 joerg Exp $ */ /*- * Copyright (c) 2019 Jared McNeill * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: mesong12_clkc.c,v 1.6 2021/02/04 22:55:36 joerg Exp $"); #include #include #include #include #include #include #include #define CBUS_REG(x) ((x) << 2) #define HHI_GP0_PLL_CNTL0 CBUS_REG(0x10) #define HHI_GP0_PLL_CNTL1 CBUS_REG(0x11) #define HHI_GP0_PLL_CNTL2 CBUS_REG(0x12) #define HHI_GP0_PLL_CNTL3 CBUS_REG(0x13) #define HHI_GP0_PLL_CNTL4 CBUS_REG(0x14) #define HHI_GP0_PLL_CNTL5 CBUS_REG(0x15) #define HHI_GP0_PLL_CNTL6 CBUS_REG(0x16) #define HHI_GP1_PLL_CNTL0 CBUS_REG(0x18) #define HHI_GP1_PLL_CNTL1 CBUS_REG(0x19) #define HHI_PCIE_PLL_CNTL0 CBUS_REG(0x26) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_LOCK __BIT(31) #define HHI_PCIE_PLL_CNTL0_PCIE_HCSL_CAL_DONE __BIT(30) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_RESET __BIT(29) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_EN __BIT(28) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_VCO_DIV_SEL __BIT(27) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_AFC_START __BIT(26) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_OD __BITS(20,16) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_PREDIV_SEL __BITS(14,10) #define HHI_PCIE_PLL_CNTL0_PCIE_APLL_FBKDIV __BITS(7,0) #define HHI_PCIE_PLL_CNTL1 CBUS_REG(0x27) #define HHI_PCIE_PLL_CNTL1_PCIE_APLL_SDM_EN __BIT(12) #define HHI_PCIE_PLL_CNTL1_PCIE_APLL_SDM_FRAC __BITS(11,0) #define HHI_PCIE_PLL_CNTL2 CBUS_REG(0x28) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_SSC_DEP_SEL __BITS(31,28) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_SSC_FREF_SEL __BITS(25,24) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_SSC_MODE __BITS(23,22) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_SSC_OFFSET __BITS(21,20) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_STR_M __BITS(19,18) #define HHI_PCIE_PLL_CNTL2_PCIE_APLL_RESERVE __BITS(15,0) #define HHI_PCIE_PLL_CNTL3 CBUS_REG(0x29) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_BYPASS_EN __BIT(31) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_HOLD_T __BITS(29,28) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_IN __BITS(26,20) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_NT __BIT(19) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_DIV __BITS(18,17) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_BIAS_LPF_EN __BIT(16) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_CP_ICAP __BITS(15,12) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_CP_IRES __BITS(11,8) #define HHI_PCIE_PLL_CNTL3_PCIE_APLL_CPI __BITS(5,4) #define HHI_PCIE_PLL_CNTL4 CBUS_REG(0x2a) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_SHIFT_EN __BIT(31) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_SHIFT_T __BITS(27,26) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_SHIFT_V __BITS(25,24) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_VCTRL_MON_EN __BIT(23) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LPF_CAP __BITS(21,20) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LPF_CAPADJ __BITS(19,16) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LPF_RES __BITS(13,12) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LPF_SF __BIT(11) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LVR_OD_EN __BIT(10) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_REFCLK_MON_EN __BIT(9) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_FBKCLK_MON_EN __BIT(8) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LOAD __BIT(7) #define HHI_PCIE_PLL_CNTL4_PCIE_APLL_LOAD_EN __BIT(6) #define HHI_PCIE_PLL_CNTL5 CBUS_REG(0x2b) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_ADJ_LDO __BITS(30,28) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BGP_EN __BIT(27) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BGR_ADJ __BITS(24,20) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BGR_START __BIT(19) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BGR_VREF __BITS(16,12) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BY_IMP_IN __BITS(11,8) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BY_IMP __BIT(7) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_CAL_EN __BIT(6) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_CAL_RSTN __BIT(5) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_EDGEDRV_EN __BIT(4) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_EN0 __BIT(3) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_IN_EN __BIT(2) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_SEL_PW __BIT(1) #define HHI_PCIE_PLL_CNTL5_PCIE_HCSL_SEL_STR __BIT(0) #define HHI_HIFI_PLL_CNTL0 CBUS_REG(0x36) #define HHI_HIFI_PLL_CNTL1 CBUS_REG(0x37) #define HHI_HIFI_PLL_CNTL2 CBUS_REG(0x38) #define HHI_HIFI_PLL_CNTL3 CBUS_REG(0x39) #define HHI_HIFI_PLL_CNTL4 CBUS_REG(0x3a) #define HHI_HIFI_PLL_CNTL5 CBUS_REG(0x3b) #define HHI_HIFI_PLL_CNTL6 CBUS_REG(0x3c) #define HHI_MEM_PD_REG0 CBUS_REG(0x40) #define HHI_GCLK_MPEG0 CBUS_REG(0x50) #define HHI_GCLK_MPEG1 CBUS_REG(0x51) #define HHI_GCLK_MPEG2 CBUS_REG(0x52) #define HHI_GCLK_OTHER CBUS_REG(0x54) #define HHI_GCLK_OTHER2 CBUS_REG(0x55) #define HHI_SYS_CPU_CLK_CNTL1 CBUS_REG(0x57) #define HHI_MPEG_CLK_CNTL CBUS_REG(0x5d) #define HHI_TS_CLK_CNTL CBUS_REG(0x64) #define HHI_SYS_CPU_CLK_CNTL0 CBUS_REG(0x67) #define HHI_VID_PLL_CLK_DIV CBUS_REG(0x68) #define HHI_SYS_CPUB_CLK_CNTL1 CBUS_REG(0x80) #define HHI_SYS_CPUB_CLK_CNTL CBUS_REG(0x82) #define HHI_NAND_CLK_CNTL CBUS_REG(0x97) #define HHI_SD_EMMC_CLK_CNTL CBUS_REG(0x99) #define HHI_MPLL_CNTL0 CBUS_REG(0x9e) #define HHI_MPLL_CNTL1 CBUS_REG(0x9f) #define HHI_MPLL_CNTL2 CBUS_REG(0xa0) #define HHI_MPLL_CNTL3 CBUS_REG(0xa1) #define HHI_MPLL_CNTL4 CBUS_REG(0xa2) #define HHI_MPLL_CNTL5 CBUS_REG(0xa3) #define HHI_MPLL_CNTL6 CBUS_REG(0xa4) #define HHI_MPLL_CNTL7 CBUS_REG(0xa5) #define HHI_MPLL_CNTL8 CBUS_REG(0xa6) #define HHI_FIX_PLL_CNTL0 CBUS_REG(0xa8) #define HHI_FIX_PLL_CNTL1 CBUS_REG(0xa9) #define HHI_FIX_PLL_CNTL2 CBUS_REG(0xaa) #define HHI_FIX_PLL_CNTL3 CBUS_REG(0xab) #define HHI_SYS_PLL_CNTL0 CBUS_REG(0xbd) #define HHI_SYS_PLL_CNTL1 CBUS_REG(0xbe) #define HHI_SYS_PLL_CNTL2 CBUS_REG(0xbf) #define HHI_SYS_PLL_CNTL3 CBUS_REG(0xc0) #define HHI_SYS_PLL_CNTL4 CBUS_REG(0xc1) #define HHI_SYS_PLL_CNTL5 CBUS_REG(0xc2) #define HHI_SYS_PLL_CNTL6 CBUS_REG(0xc3) #define HHI_HDMI_PLL_CNTL0 CBUS_REG(0xc8) #define HHI_HDMI_PLL_CNTL1 CBUS_REG(0xc9) #define HHI_SYS1_PLL_CNTL0 CBUS_REG(0xe0) #define HHI_SYS1_PLL_CNTL1 CBUS_REG(0xe1) #define HHI_SYS1_PLL_CNTL2 CBUS_REG(0xe2) #define HHI_SYS1_PLL_CNTL3 CBUS_REG(0xe3) #define HHI_SYS1_PLL_CNTL4 CBUS_REG(0xe4) #define HHI_SYS1_PLL_CNTL5 CBUS_REG(0xe5) #define HHI_SYS1_PLL_CNTL6 CBUS_REG(0xe6) static int mesong12_clkc_match(device_t, cfdata_t, void *); static void mesong12_clkc_attach(device_t, device_t, void *); static u_int mesong12_cpuclk_get_rate(struct meson_clk_softc *, struct meson_clk_clk *); static int mesong12_cpuclk_set_rate(struct meson_clk_softc *, struct meson_clk_clk *, u_int); static int mesong12_clk_pcie_pll_set_rate(struct meson_clk_softc *, struct meson_clk_clk *, u_int); struct mesong12_clkc_config { const char *name; struct meson_clk_clk *clks; int nclks; }; #define PARENTS(args...) ((const char *[]){ args }) /* fixed pll */ #define G12_CLK_fixed_pll_dco \ MESON_CLK_PLL(MESONG12_CLOCK_FIXED_PLL_DCO, "fixed_pll_dco", \ "xtal", /* parent */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL0, __BIT(28)), /* enable */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL0, __BITS(7,0)), /* m */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL0, __BITS(14,10)),/* n */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL1, __BITS(16,0)), /* frac */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL0, __BIT(31)), /* l */ \ MESON_CLK_PLL_REG(HHI_FIX_PLL_CNTL0, __BIT(29)), /* reset */ \ 0) #define G12_CLK_fixed_pll \ MESON_CLK_DIV(MESONG12_CLOCK_FIXED_PLL, "fixed_pll", \ "fixed_pll_dco", /* parent */ \ HHI_FIX_PLL_CNTL0, /* reg */ \ __BITS(17,16), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO) /* sys pll */ #define G12_CLK_sys_pll_dco \ MESON_CLK_PLL(MESONG12_CLOCK_SYS_PLL_DCO, "sys_pll_dco", \ "xtal", /* parent */ \ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL0, __BIT(28)), /* enable */ \ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL0, __BITS(7,0)), /* m */ \ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL0, __BITS(14,10)),/* n */ \ MESON_CLK_PLL_REG_INVALID, /* frac */ \ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL0, __BIT(31)), /* l */ \ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL0, __BIT(29)), /* reset */ \ 0) #define G12_CLK_sys_pll \ MESON_CLK_DIV(MESONG12_CLOCK_SYS_PLL, "sys_pll", \ "sys_pll_dco", /* parent */ \ HHI_SYS_PLL_CNTL0, /* reg */ \ __BITS(18,16), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO | MESON_CLK_DIV_SET_RATE_PARENT) /* sys1 pll */ #define G12B_CLK_sys1_pll_dco \ MESON_CLK_PLL(MESONG12_CLOCK_SYS1_PLL_DCO, "sys1_pll_dco", \ "xtal", /* parent */ \ MESON_CLK_PLL_REG(HHI_SYS1_PLL_CNTL0, __BIT(28)), /* enable */ \ MESON_CLK_PLL_REG(HHI_SYS1_PLL_CNTL0, __BITS(7,0)), /* m */ \ MESON_CLK_PLL_REG(HHI_SYS1_PLL_CNTL0, __BITS(14,10)),/* n */ \ MESON_CLK_PLL_REG_INVALID, /* frac */ \ MESON_CLK_PLL_REG(HHI_SYS1_PLL_CNTL0, __BIT(31)), /* l */ \ MESON_CLK_PLL_REG(HHI_SYS1_PLL_CNTL0, __BIT(29)), /* reset */ \ 0) #define G12B_CLK_sys1_pll \ MESON_CLK_DIV(MESONG12_CLOCK_SYS1_PLL, "sys1_pll", \ "sys1_pll_dco", /* parent */ \ HHI_SYS1_PLL_CNTL0, /* reg */ \ __BITS(18,16), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO | MESON_CLK_DIV_SET_RATE_PARENT) /* fclk div */ #define G12_CLK_fclk_div2_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV2_DIV, "fclk_div2_div", \ "fixed_pll", /* parent */ \ 2, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div2 \ MESON_CLK_GATE(MESONG12_CLOCK_FCLK_DIV2, "fclk_div2", \ "fclk_div2_div", /* parent */ \ HHI_FIX_PLL_CNTL1, /* reg */ \ 24) /* bit */ #define G12_CLK_fclk_div2p5_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV2P5_DIV, \ "fclk_div2p5_div", \ "fixed_pll_dco", /* parent */ \ 5, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div3_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV3_DIV, \ "fclk_div3_div", \ "fixed_pll", /* parent */ \ 3, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div3 \ MESON_CLK_GATE(MESONG12_CLOCK_FCLK_DIV3, "fclk_div3", \ "fclk_div3_div", /* parent */ \ HHI_FIX_PLL_CNTL1, /* reg */ \ 20) /* bit */ #define G12_CLK_fclk_div4_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV4_DIV, "fclk_div4_div", \ "fixed_pll", /* parent */ \ 4, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div4 \ MESON_CLK_GATE(MESONG12_CLOCK_FCLK_DIV4, "fclk_div4", \ "fclk_div4_div", /* parent */ \ HHI_FIX_PLL_CNTL1, /* reg */ \ 21) /* bit */ #define G12_CLK_fclk_div5_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV5_DIV, "fclk_div5_div", \ "fixed_pll", /* parent */ \ 5, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div5 \ MESON_CLK_GATE(MESONG12_CLOCK_FCLK_DIV5, "fclk_div5", \ "fclk_div5_div", /* parent */ \ HHI_FIX_PLL_CNTL1, /* reg */ \ 22) /* bit */ #define G12_CLK_fclk_div7_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_FCLK_DIV7_DIV, "fclk_div7_div", \ "fixed_pll", /* parent */ \ 7, /* div */ \ 1) /* mult */ #define G12_CLK_fclk_div7 \ MESON_CLK_GATE(MESONG12_CLOCK_FCLK_DIV7, "fclk_div7", \ "fclk_div7_div", /* parent */ \ HHI_FIX_PLL_CNTL1, /* reg */ \ 23) /* bit */ /* mpll */ #define G12_CLK_mpll_prediv \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_MPLL_PREDIV, "mpll_prediv", \ "fixed_pll_dco", /* parent */ \ 2, /* div */ \ 1) /* mult */ #define G12_CLK_mpll0_div \ MESON_CLK_MPLL(MESONG12_CLOCK_MPLL0_DIV, "mpll0_div", \ "mpll_prediv", /* parent */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL1, __BITS(13,0)), /* sdm */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL1, __BIT(30)), /* sdm_enable */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL1, __BITS(28,20)), /* n2 */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL1, __BIT(29)), /* ssen */ \ 0) #define G12_CLK_mpll1_div \ MESON_CLK_MPLL(MESONG12_CLOCK_MPLL1_DIV, "mpll1_div", \ "mpll_prediv", /* parent */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL3, __BITS(13,0)), /* sdm */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL3, __BIT(30)), /* sdm_enable */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL3, __BITS(28,20)), /* n2 */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL3, __BIT(29)), /* ssen */ \ 0) #define G12_CLK_mpll2_div \ MESON_CLK_MPLL(MESONG12_CLOCK_MPLL2_DIV, "mpll2_div", \ "mpll_prediv", /* parent */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL5, __BITS(13,0)), /* sdm */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL5, __BIT(30)), /* sdm_enable */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL5, __BITS(28,20)), /* n2 */ \ MESON_CLK_PLL_REG(HHI_MPLL_CNTL5, __BIT(29)), /* ssen */ \ 0) #define G12_CLK_mpll0 \ MESON_CLK_GATE(MESONG12_CLOCK_MPLL0, "mpll0", \ "mpll0_div", /* parent */ \ HHI_MPLL_CNTL1, /* reg */ \ 31) /* bit */ #define G12_CLK_mpll1 \ MESON_CLK_GATE(MESONG12_CLOCK_MPLL1, "mpll1", \ "mpll1_div", /* parent */ \ HHI_MPLL_CNTL3, /* reg */ \ 31) /* bit */ #define G12_CLK_mpll2 \ MESON_CLK_GATE(MESONG12_CLOCK_MPLL2, "mpll2", \ "mpll2_div", /* parent */ \ HHI_MPLL_CNTL5, /* reg */ \ 31) /* bit */ #define G12_CLK_mpll_50m_div \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_MPLL_50M_DIV, "mpll_50m_div", \ "fixed_pll_dco", /* parent */ \ 80, /* div */ \ 1) /* mult */ #define G12_CLK_mpll_50m \ MESON_CLK_MUX(MESONG12_CLOCK_MPLL_50M, "mpll_50m", \ PARENTS("mpll_50m_div", "xtal"), \ HHI_FIX_PLL_CNTL3, /* reg */ \ __BIT(5), /* sel */ \ 0) /* sd/emmc */ #define G12_CLK_sd_emmc_a_clk0_sel \ MESON_CLK_MUX(MESONG12_CLOCK_SD_EMMC_A_CLK0_SEL, "sd_emmc_a_clk0_sel", \ PARENTS("xtal", "fclk_div2", "fclk_div3", \ "fclk_div5", "fclk_div7"), \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ __BITS(11,9), /* sel */ \ 0) #define G12_CLK_sd_emmc_b_clk0_sel \ MESON_CLK_MUX(MESONG12_CLOCK_SD_EMMC_B_CLK0_SEL, "sd_emmc_b_clk0_sel", \ PARENTS("xtal", "fclk_div2", "fclk_div3", \ "fclk_div5", "fclk_div7"), \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ __BITS(27,25), /* sel */ \ 0) #define G12_CLK_sd_emmc_c_clk0_sel \ MESON_CLK_MUX(MESONG12_CLOCK_SD_EMMC_C_CLK0_SEL, "sd_emmc_c_clk0_sel", \ PARENTS("xtal", "fclk_div2", "fclk_div3", \ "fclk_div5", "fclk_div7"), \ HHI_NAND_CLK_CNTL, /* reg */ \ __BITS(11,9), /* sel */ \ 0) #define G12_CLK_sd_emmc_a_clk0_div \ MESON_CLK_DIV(MESONG12_CLOCK_SD_EMMC_A_CLK0_DIV, "sd_emmc_a_clk0_div", \ "sd_emmc_a_clk0_sel", /* parent */ \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ __BITS(6,0), /* div */ \ 0) #define G12_CLK_sd_emmc_b_clk0_div \ MESON_CLK_DIV(MESONG12_CLOCK_SD_EMMC_B_CLK0_DIV, "sd_emmc_b_clk0_div", \ "sd_emmc_b_clk0_sel", /* parent */ \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ __BITS(22,16), /* div */ \ 0) #define G12_CLK_sd_emmc_c_clk0_div \ MESON_CLK_DIV(MESONG12_CLOCK_SD_EMMC_C_CLK0_DIV, "sd_emmc_c_clk0_div", \ "sd_emmc_c_clk0_sel", /* parent */ \ HHI_NAND_CLK_CNTL, /* reg */ \ __BITS(6,0), /* div */ \ 0) #define G12_CLK_sd_emmc_a_clk0 \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_A_CLK0, "sd_emmc_a_clk0", \ "sd_emmc_a_clk0_div", /* parent */ \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ 7) /* bit */ #define G12_CLK_sd_emmc_b_clk0 \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_B_CLK0, "sd_emmc_b_clk0", \ "sd_emmc_b_clk0_div", /* parent */ \ HHI_SD_EMMC_CLK_CNTL, /* reg */ \ 23) /* bit */ #define G12_CLK_sd_emmc_c_clk0 \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_C_CLK0, "sd_emmc_c_clk0", \ "sd_emmc_c_clk0_div", /* parent */ \ HHI_NAND_CLK_CNTL, /* reg */ \ 7) /* bit */ /* source as mpeg_clk */ #define G12_CLK_mpeg_sel \ MESON_CLK_MUX(MESONG12_CLOCK_MPEG_SEL, "mpeg_sel", \ PARENTS("xtal", NULL, "fclk_div7", "mpll1", \ "mpll2", "fclk_div4", "fclk_div3", "fclk_div5"), \ HHI_MPEG_CLK_CNTL, /* reg */ \ __BITS(14,12), /* sel */ \ 0) #define G12_CLK_mpeg_clk_div \ MESON_CLK_DIV(MESONG12_CLOCK_MPEG_DIV, "mpeg_clk_div", \ "mpeg_sel", /* parent */ \ HHI_MPEG_CLK_CNTL, /* reg */ \ __BITS(6,0), /* div */ \ MESON_CLK_DIV_SET_RATE_PARENT) #define G12_CLK_clk81 \ MESON_CLK_GATE(MESONG12_CLOCK_CLK81, "clk81", \ "mpeg_clk_div", /* parent */ \ HHI_MPEG_CLK_CNTL, /* reg */ \ 7) /* bit */ #define G12_CLK_ddr \ MESON_CLK_GATE(MESONG12_CLOCK_DDR, "ddr", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 0) /* bit */ #define G12_CLK_dos \ MESON_CLK_GATE(MESONG12_CLOCK_DOS, "dos", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 1) /* bit */ #define G12_CLK_audio_locker \ MESON_CLK_GATE(MESONG12_CLOCK_AUDIO_LOCKER, "audio_locker", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 2) /* bit */ #define G12_CLK_mipi_dsi_host \ MESON_CLK_GATE(MESONG12_CLOCK_MIPI_DSI_HOST, "mipi_dsi_host", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 3) /* bit */ #define G12_CLK_eth_phy \ MESON_CLK_GATE(MESONG12_CLOCK_ETH_PHY, "eth_phy", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 4) /* bit */ #define G12_CLK_isa \ MESON_CLK_GATE(MESONG12_CLOCK_ISA, "isa", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 5) /* bit */ #define G12_CLK_pl301 \ MESON_CLK_GATE(MESONG12_CLOCK_PL301, "pl301", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 6) /* bit */ #define G12_CLK_periphs \ MESON_CLK_GATE(MESONG12_CLOCK_PERIPHS, "periphs", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 7) /* bit */ #define G12_CLK_spicc0 \ MESON_CLK_GATE(MESONG12_CLOCK_SPICC0, "spicc0", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 8) /* bit */ #define G12_CLK_i2c \ MESON_CLK_GATE(MESONG12_CLOCK_I2C, "i2c", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 9) /* bit */ #define G12_CLK_sana \ MESON_CLK_GATE(MESONG12_CLOCK_SANA, "sana", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 10) /* bit */ #define G12_CLK_sd \ MESON_CLK_GATE(MESONG12_CLOCK_SD, "sd", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 11) /* bit */ #define G12_CLK_rng0 \ MESON_CLK_GATE(MESONG12_CLOCK_RNG0, "rng0", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 12) /* bit */ #define G12_CLK_uart0 \ MESON_CLK_GATE(MESONG12_CLOCK_UART0, "uart0", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 13) /* bit */ #define G12_CLK_spicc1 \ MESON_CLK_GATE(MESONG12_CLOCK_SPICC1, "spicc1", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 14) /* bit */ #define G12_CLK_hiu_iface \ MESON_CLK_GATE(MESONG12_CLOCK_HIU_IFACE, "hiu_iface", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 19) /* bit */ #define G12_CLK_mipi_dsi_phy \ MESON_CLK_GATE(MESONG12_CLOCK_MIPI_DSI_PHY, "mipi_dsi_phy", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 20) /* bit */ #define G12_CLK_assist_misc \ MESON_CLK_GATE(MESONG12_CLOCK_ASSIST_MISC, "assist_misc", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 23) /* bit */ #define G12_CLK_sd_emmc_a \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_A, "sd_emmc_a", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 4) /* bit */ #define G12_CLK_sd_emmc_b \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_B, "sd_emmc_b", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 25) /* bit */ #define G12_CLK_sd_emmc_c \ MESON_CLK_GATE(MESONG12_CLOCK_SD_EMMC_C, "sd_emmc_c", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 26) /* bit */ #define G12_CLK_audio_codec \ MESON_CLK_GATE(MESONG12_CLOCK_AUDIO_CODEC, "audio_codec", \ "clk81", /* parent */ \ HHI_GCLK_MPEG0, /* reg */ \ 28) /* bit */ #define G12_CLK_audio \ MESON_CLK_GATE(MESONG12_CLOCK_AUDIO, "audio", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 0) /* bit */ #define G12_CLK_eth \ MESON_CLK_GATE(MESONG12_CLOCK_ETH, "eth", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 3) /* bit */ #define G12_CLK_demux \ MESON_CLK_GATE(MESONG12_CLOCK_DEMUX, "demux", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 4) /* bit */ #define G12_CLK_audio_ififo \ MESON_CLK_GATE(MESONG12_CLOCK_AUDIO_IFIFO, "audio_ififo", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 11) /* bit */ #define G12_CLK_adc \ MESON_CLK_GATE(MESONG12_CLOCK_ADC, "adc", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 13) /* bit */ #define G12_CLK_uart1 \ MESON_CLK_GATE(MESONG12_CLOCK_UART1, "uart1", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 16) /* bit */ #define G12_CLK_g2d \ MESON_CLK_GATE(MESONG12_CLOCK_G2D, "g2d", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 20) /* bit */ #define G12_CLK_reset \ MESON_CLK_GATE(MESONG12_CLOCK_RESET, "reset", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 23) /* bit */ #define G12_CLK_pcie_comb \ MESON_CLK_GATE(MESONG12_CLOCK_PCIE_COMB, "pcie_comb", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 24) /* bit */ #define G12_CLK_parser \ MESON_CLK_GATE(MESONG12_CLOCK_PARSER, "parser", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 25) /* bit */ #define G12_CLK_usb \ MESON_CLK_GATE(MESONG12_CLOCK_USB, "usb", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 26) /* bit */ #define G12_CLK_pcie_phy \ MESON_CLK_GATE(MESONG12_CLOCK_PCIE_PHY, "pcie_phy", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 27) /* bit */ #define G12_CLK_ahb_arb0 \ MESON_CLK_GATE(MESONG12_CLOCK_AHB_ARB0, "ahb_arb0", \ "clk81", /* parent */ \ HHI_GCLK_MPEG1, /* reg */ \ 29) /* bit */ #define G12_CLK_ahb_data_bus \ MESON_CLK_GATE(MESONG12_CLOCK_AHB_DATA_BUS, "ahb_data_bus", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 1) /* bit */ #define G12_CLK_ahb_ctrl_bus \ MESON_CLK_GATE(MESONG12_CLOCK_AHB_CTRL_BUS, "ahb_ctrl_bus", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 2) /* bit */ #define G12_CLK_htx_hdcp22 \ MESON_CLK_GATE(MESONG12_CLOCK_HTX_HDCP22, "htx_hdcp22", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 3) /* bit */ #define G12_CLK_htx_pclk \ MESON_CLK_GATE(MESONG12_CLOCK_HTX_PCLK, "htx_pclk", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 4) /* bit */ #define G12_CLK_bt656 \ MESON_CLK_GATE(MESONG12_CLOCK_BT656, "bt656", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 6) /* bit */ #define G12_CLK_usb1_ddr_bridge \ MESON_CLK_GATE(MESONG12_CLOCK_USB1_DDR_BRIDGE, "usb1_ddr_bridge", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 8) /* bit */ #define G12_CLK_mmc_pclk \ MESON_CLK_GATE(MESONG12_CLOCK_MMC_PCLK, "mmc_pclk", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 11) /* bit */ #define G12_CLK_uart2 \ MESON_CLK_GATE(MESONG12_CLOCK_UART2, "uart2", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 15) /* bit */ #define G12_CLK_vpu_intr \ MESON_CLK_GATE(MESONG12_CLOCK_VPU_INTR, "vpu_intr", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 25) /* bit */ #define G12_CLK_gic \ MESON_CLK_GATE(MESONG12_CLOCK_GIC, "gic", \ "clk81", /* parent */ \ HHI_GCLK_MPEG2, /* reg */ \ 30) /* bit */ #define G12_CLK_vclk2_venci0 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCI0, "vclk2_venci0", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 1) /* bit */ #define G12_CLK_vclk2_venci1 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCI1, "vclk2_venci1", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 2) /* bit */ #define G12_CLK_vclk2_vencp0 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCP0, "vclk2_vencp0", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 3) /* bit */ #define G12_CLK_vclk2_vencp1 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCP1, "vclk2_vencp1", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 4) /* bit */ #define G12_CLK_vclk2_venct0 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCT0, "vclk2_venct0", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 5) /* bit */ #define G12_CLK_vclk2_venct1 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCT1, "vclk2_venct1", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 6) /* bit */ #define G12_CLK_vclk2_other \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_OTHER, "vclk2_other", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 7) /* bit */ #define G12_CLK_vclk2_enci \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_ENCI, "vclk2_enci", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 8) /* bit */ #define G12_CLK_vclk2_encp \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_ENCP, "vclk2_encp", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 9) /* bit */ #define G12_CLK_dac_clk \ MESON_CLK_GATE(MESONG12_CLOCK_DAC_CLK, "dac_clk", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 10) /* bit */ #define G12_CLK_aoclk \ MESON_CLK_GATE(MESONG12_CLOCK_AOCLK, "aoclk", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 14) /* bit */ #define G12_CLK_iec958 \ MESON_CLK_GATE(MESONG12_CLOCK_IEC958, "iec958", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 16) /* bit */ #define G12_CLK_enc480p \ MESON_CLK_GATE(MESONG12_CLOCK_ENC480P, "enc480p", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 20) /* bit */ #define G12_CLK_rng1 \ MESON_CLK_GATE(MESONG12_CLOCK_RNG1, "rng1", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 21) /* bit */ #define G12_CLK_vclk2_enct \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_ENCT, "vclk2_enct", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 22) /* bit */ #define G12_CLK_vclk2_encl \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_ENCL, "vclk2_encl", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 23) /* bit */ #define G12_CLK_vclk2_venclmmc \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCLMMC, "vclk2_venclmmc", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 24) /* bit */ #define G12_CLK_vclk2_vencl \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_VENCL, "vclk2_vencl", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 25) /* bit */ #define G12_CLK_vclk2_other1 \ MESON_CLK_GATE(MESONG12_CLOCK_VCLK2_OTHER1, "vclk2_other1", \ "clk81", /* parent */ \ HHI_GCLK_OTHER, /* reg */ \ 26) /* bit */ #define G12_CLK_dma \ MESON_CLK_GATE(MESONG12_CLOCK_DMA, "dma", \ "clk81", /* parent */ \ HHI_GCLK_OTHER2, /* reg */ \ 0) /* bit */ #define G12_CLK_efuse \ MESON_CLK_GATE(MESONG12_CLOCK_EFUSE, "efuse", \ "clk81", /* parent */ \ HHI_GCLK_OTHER2, /* reg */ \ 1) /* bit */ #define G12_CLK_rom_boot \ MESON_CLK_GATE(MESONG12_CLOCK_ROM_BOOT, "rom_boot", \ "clk81", /* parent */ \ HHI_GCLK_OTHER2, /* reg */ \ 2) /* bit */ #define G12_CLK_reset_sec \ MESON_CLK_GATE(MESONG12_CLOCK_RESET_SEC, "reset_sec", \ "clk81", /* parent */ \ HHI_GCLK_OTHER2, /* reg */ \ 3) /* bit */ #define G12_CLK_sec_ahb_apb3 \ MESON_CLK_GATE(MESONG12_CLOCK_SEC_AHB_APB3, "sec_ahb_apb3", \ "clk81", /* parent */ \ HHI_GCLK_OTHER2, /* reg */ \ 4) /* bit */ /* little cpu cluster */ #define G12_CLK_cpu_clk_dyn0_sel \ MESON_CLK_MUX(MESONG12_CLOCK_CPU_CLK_DYN0_SEL, "cpu_clk_dyn0_sel", \ PARENTS("fclk_div2", "fclk_div3", "xtal"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BITS(1,0), /* sel */ \ 0) #define G12_CLK_cpu_clk_dyn1_sel \ MESON_CLK_MUX(MESONG12_CLOCK_CPU_CLK_DYN1_SEL, "cpu_clk_dyn1_sel", \ PARENTS("fclk_div2", "fclk_div3", "xtal"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BITS(17,16), /* sel */ \ 0) #define G12_CLK_cpu_clk_dyn0_div \ MESON_CLK_DIV(MESONG12_CLOCK_CPU_CLK_DYN0_DIV, "cpu_clk_dyn0_div", \ "cpu_clk_dyn0_sel", /* parent */ \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(26), /* div */ \ 0) #define G12_CLK_cpu_clk_dyn1_div \ MESON_CLK_DIV(MESONG12_CLOCK_CPU_CLK_DYN1_DIV, "cpu_clk_dyn1_div", \ "cpu_clk_dyn1_sel", /* parent */ \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BITS(25,20), /* div */ \ 0) #define G12_CLK_cpu_clk_dyn0 \ MESON_CLK_MUX(MESONG12_CLOCK_CPU_CLK_DYN0, "cpu_clk_dyn0", \ PARENTS("cpu_clk_dyn0_div", "cpu_clk_dyn0_sel"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(2), /* sel */ \ 0) #define G12_CLK_cpu_clk_dyn1 \ MESON_CLK_MUX(MESONG12_CLOCK_CPU_CLK_DYN1, "cpu_clk_dyn1", \ PARENTS("cpu_clk_dyn1_div", "cpu_clk_dyn1_sel"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(18), /* sel */ \ 0) #define G12_CLK_cpu_clk_dyn \ MESON_CLK_MUX(MESONG12_CLOCK_CPU_CLK_DYN, "cpu_clk_dyn", \ PARENTS("cpu_clk_dyn0", "cpu_clk_dyn1"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(10), /* sel */ \ 0) #define G12A_CLK_cpu_clk \ MESON_CLK_MUX_RATE(MESONG12_CLOCK_CPU_CLK, "cpu_clk", \ PARENTS("cpu_clk_dyn", "sys_pll"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(11), /* sel */ \ mesong12_cpuclk_get_rate, \ mesong12_cpuclk_set_rate, \ 0) #define G12B_CLK_cpu_clk \ MESON_CLK_MUX_RATE(MESONG12_CLOCK_CPU_CLK, "cpu_clk", \ PARENTS("cpu_clk_dyn", "sys1_pll"), \ HHI_SYS_CPU_CLK_CNTL0, /* reg */ \ __BIT(11), /* sel */ \ mesong12_cpuclk_get_rate, \ mesong12_cpuclk_set_rate, \ 0) /* big cpu cluster */ #define G12_CLK_cpub_clk_dyn0_sel \ MESON_CLK_MUX(MESONG12_CLOCK_CPUB_CLK_DYN0_SEL, "cpub_clk_dyn0_sel", \ PARENTS("fclk_div2", "fclk_div3", "xtal"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BITS(1,0), /* sel */ \ 0) #define G12_CLK_cpub_clk_dyn0_div \ MESON_CLK_DIV(MESONG12_CLOCK_CPUB_CLK_DYN0_DIV, "cpub_clk_dyn0_div", \ "cpub_clk_dyn0_sel", /* parent */ \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BITS(9,4), /* div */ \ 0) #define G12_CLK_cpub_clk_dyn0 \ MESON_CLK_MUX(MESONG12_CLOCK_CPUB_CLK_DYN0, "cpub_clk_dyn0", \ PARENTS("cpub_clk_dyn0_div", "cpub_clk_dyn0_sel"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BIT(2), /* sel */ \ 0) #define G12_CLK_cpub_clk_dyn1_sel \ MESON_CLK_MUX(MESONG12_CLOCK_CPUB_CLK_DYN1_SEL, "cpub_clk_dyn1_sel", \ PARENTS("fclk_div2", "fclk_div3", "xtal", "xtal"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BITS(17,16), /* sel */ \ 0) #define G12_CLK_cpub_clk_dyn1_div \ MESON_CLK_DIV(MESONG12_CLOCK_CPUB_CLK_DYN1_DIV, "cpub_clk_dyn1_div", \ "cpub_clk_dyn1_sel", /* parent */ \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BITS(25,20), /* div */ \ 0) #define G12_CLK_cpub_clk_dyn1 \ MESON_CLK_MUX(MESONG12_CLOCK_CPUB_CLK_DYN1, "cpub_clk_dyn1", \ PARENTS("cpub_clk_dyn1_div", "cpub_clk_dyn1_sel"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BIT(18), /* sel */ \ 0) #define G12_CLK_cpub_clk_dyn \ MESON_CLK_MUX(MESONG12_CLOCK_CPUB_CLK_DYN, "cpub_clk_dyn", \ PARENTS("cpub_clk_dyn0", "cpub_clk_dyn1"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BIT(10), /* sel */ \ 0) #define G12_CLK_cpub_clk \ MESON_CLK_MUX_RATE(MESONG12_CLOCK_CPUB_CLK, "cpub_clk", \ PARENTS("cpub_clk_dyn", "sys_pll"), \ HHI_SYS_CPUB_CLK_CNTL, /* reg */ \ __BIT(11), /* sel */ \ mesong12_cpuclk_get_rate, \ mesong12_cpuclk_set_rate, \ 0) /* ts */ #define G12_CLK_ts_div \ MESON_CLK_DIV(MESONG12_CLOCK_TS_DIV, "ts_div", \ "xtal", /* parent */ \ HHI_TS_CLK_CNTL, /* reg */ \ __BITS(7,0), /* div */ \ 0) #define G12_CLK_ts \ MESON_CLK_GATE(MESONG12_CLOCK_TS, "ts", \ "ts_div", /* parent */ \ HHI_TS_CLK_CNTL, /* ret */ \ 8) /* bit */ /* hdmi */ #define G12_CLK_hdmi_pll_dco \ MESON_CLK_PLL(MESONG12_CLOCK_HDMI_PLL_DCO, "hdmi_pll_dco", \ "xtal", /* parent */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL0, __BIT(28)), /* enable */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL0, __BITS(7,0)), /* m */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL0, __BITS(14,10)),/* n */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL1, __BITS(15,0)),/* frac */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL0, __BIT(30)), /* l */ \ MESON_CLK_PLL_REG(HHI_HDMI_PLL_CNTL0, __BIT(29)), /* reset */ \ 0) #define G12_CLK_hdmi_pll_od \ MESON_CLK_DIV(MESONG12_CLOCK_HDMI_PLL_OD, "hdmi_pll_od", \ "hdmi_pll_dco", /* parent */ \ HHI_HDMI_PLL_CNTL0, /* reg */ \ __BITS(17,16), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO) #define G12_CLK_hdmi_pll_od2 \ MESON_CLK_DIV(MESONG12_CLOCK_HDMI_PLL_OD2, "hdmi_pll_od2", \ "hdmi_pll_od", /* parent */ \ HHI_HDMI_PLL_CNTL0, /* reg */ \ __BITS(19,18), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO) #define G12_CLK_hdmi_pll \ MESON_CLK_DIV(MESONG12_CLOCK_HDMI_PLL, "hdmi_pll", \ "hdmi_pll_od2", /* parent */ \ HHI_HDMI_PLL_CNTL0, /* reg */ \ __BITS(21,20), /* div */ \ MESON_CLK_DIV_POWER_OF_TWO) #define G12_CLK_vid_pll_div \ MESON_CLK_DIV(MESONG12_CLOCK_VID_PLL_DIV, "vid_pll_div", \ "hdmi_pll", /* parent */ \ HHI_FIX_PLL_CNTL0, /* reg */ \ __BITS(17,16), /* div */ \ 0) #define G12_CLK_vid_pll_sel \ MESON_CLK_MUX(MESONG12_CLOCK_VID_PLL_SEL, "vid_pll_sel", \ PARENTS("vid_pll_div", "hdmi_pll"), \ HHI_VID_PLL_CLK_DIV, /* reg */ \ __BIT(18), /* sel */ \ 0) #define G12_CLK_vid_pll \ MESON_CLK_GATE(MESONG12_CLOCK_VID_PLL, "vid_pll", \ "vid_pll_sel", /* parent */ \ HHI_VID_PLL_CLK_DIV, /* reg */ \ 19) /* bit */ /* USB3/PCIe */ #define G12_CLK_pcie_pll_dco \ MESON_CLK_PLL_RATE(MESONG12_CLOCK_PCIE_PLL_DCO, "pcie_pll_dco", \ "xtal", /* parent */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL0, __BIT(28)), /* enable */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL0, __BITS(7,0)), /* m */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL0, __BITS(14,10)),/* n */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL1, __BITS(11,0)),/* frac */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL0, __BIT(31)), /* l */ \ MESON_CLK_PLL_REG(HHI_PCIE_PLL_CNTL0, __BIT(29)), /* reset */ \ mesong12_clk_pcie_pll_set_rate, \ 0) #define G12_CLK_pcie_pll_dco_div2 \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_PCIE_PLL_DCO_DIV2, \ "pcie_pll_dco_div2", \ "pcie_pll_dco", /* parent */ \ 2, /* div */ \ 1) /* mult */ #define G12_CLK_pcie_pll_od \ MESON_CLK_DIV(MESONG12_CLOCK_PCIE_PLL_OD, "pcie_pll_od", \ "pcie_pll_dco_div2", /* parent */ \ HHI_PCIE_PLL_CNTL0, /* reg */ \ __BITS(20,16), /* div */ \ MESON_CLK_DIV_SET_RATE_PARENT) #define G12_CLK_pcie_pll_pll \ MESON_CLK_FIXED_FACTOR(MESONG12_CLOCK_PCIE_PLL, "pcie_pll_pll", \ "pcie_pll_od", /* parent */ \ 2, /* div */ \ 1) /* mult */ /* not all clocks are defined */ static struct meson_clk_clk mesong12a_clkc_clks[] = { G12_CLK_fixed_pll_dco, G12_CLK_fixed_pll, G12_CLK_sys_pll_dco, G12_CLK_sys_pll, G12_CLK_fclk_div2_div, G12_CLK_fclk_div2, G12_CLK_fclk_div2p5_div, G12_CLK_fclk_div3_div, G12_CLK_fclk_div3, G12_CLK_fclk_div4_div, G12_CLK_fclk_div4, G12_CLK_fclk_div5_div, G12_CLK_fclk_div5, G12_CLK_fclk_div7_div, G12_CLK_fclk_div7, G12_CLK_mpll_prediv, G12_CLK_mpll0_div, G12_CLK_mpll1_div, G12_CLK_mpll2_div, G12_CLK_mpll0, G12_CLK_mpll1, G12_CLK_mpll2, G12_CLK_mpeg_sel, G12_CLK_mpeg_clk_div, G12_CLK_clk81, G12_CLK_mpll_50m_div, G12_CLK_mpll_50m, G12_CLK_sd_emmc_a_clk0_sel, G12_CLK_sd_emmc_b_clk0_sel, G12_CLK_sd_emmc_c_clk0_sel, G12_CLK_sd_emmc_a_clk0_div, G12_CLK_sd_emmc_b_clk0_div, G12_CLK_sd_emmc_c_clk0_div, G12_CLK_sd_emmc_a_clk0, G12_CLK_sd_emmc_b_clk0, G12_CLK_sd_emmc_c_clk0, G12_CLK_ddr, G12_CLK_dos, G12_CLK_audio_locker, G12_CLK_mipi_dsi_host, G12_CLK_eth_phy, G12_CLK_isa, G12_CLK_pl301, G12_CLK_periphs, G12_CLK_spicc0, G12_CLK_i2c, G12_CLK_sana, G12_CLK_sd, G12_CLK_rng0, G12_CLK_uart0, G12_CLK_spicc1, G12_CLK_hiu_iface, G12_CLK_mipi_dsi_phy, G12_CLK_assist_misc, G12_CLK_sd_emmc_a, G12_CLK_sd_emmc_b, G12_CLK_sd_emmc_c, G12_CLK_audio_codec, G12_CLK_audio, G12_CLK_eth, G12_CLK_demux, G12_CLK_audio_ififo, G12_CLK_adc, G12_CLK_uart1, G12_CLK_g2d, G12_CLK_reset, G12_CLK_pcie_comb, G12_CLK_parser, G12_CLK_usb, G12_CLK_pcie_phy, G12_CLK_ahb_arb0, G12_CLK_ahb_data_bus, G12_CLK_ahb_ctrl_bus, G12_CLK_htx_hdcp22, G12_CLK_htx_pclk, G12_CLK_bt656, G12_CLK_usb1_ddr_bridge, G12_CLK_mmc_pclk, G12_CLK_uart2, G12_CLK_vpu_intr, G12_CLK_gic, G12_CLK_vclk2_venci0, G12_CLK_vclk2_venci1, G12_CLK_vclk2_vencp0, G12_CLK_vclk2_vencp1, G12_CLK_vclk2_venct0, G12_CLK_vclk2_venct1, G12_CLK_vclk2_other, G12_CLK_vclk2_enci, G12_CLK_vclk2_encp, G12_CLK_dac_clk, G12_CLK_aoclk, G12_CLK_iec958, G12_CLK_enc480p, G12_CLK_rng1, G12_CLK_vclk2_enct, G12_CLK_vclk2_encl, G12_CLK_vclk2_venclmmc, G12_CLK_vclk2_vencl, G12_CLK_vclk2_other1, G12_CLK_dma, G12_CLK_efuse, G12_CLK_rom_boot, G12_CLK_reset_sec, G12_CLK_sec_ahb_apb3, G12_CLK_cpu_clk_dyn0_sel, G12_CLK_cpu_clk_dyn1_sel, G12_CLK_cpu_clk_dyn0_div, G12_CLK_cpu_clk_dyn1_div, G12_CLK_cpu_clk_dyn0, G12_CLK_cpu_clk_dyn1, G12_CLK_cpu_clk_dyn, G12A_CLK_cpu_clk, G12_CLK_ts_div, G12_CLK_ts, G12_CLK_hdmi_pll_dco, G12_CLK_hdmi_pll_od, G12_CLK_hdmi_pll_od2, G12_CLK_hdmi_pll, G12_CLK_vid_pll_div, G12_CLK_vid_pll_sel, G12_CLK_vid_pll, G12_CLK_pcie_pll_dco, G12_CLK_pcie_pll_dco_div2, G12_CLK_pcie_pll_od, G12_CLK_pcie_pll_pll }; static struct meson_clk_clk mesong12b_clkc_clks[] = { G12_CLK_fixed_pll_dco, G12_CLK_fixed_pll, G12_CLK_sys_pll_dco, G12_CLK_sys_pll, G12B_CLK_sys1_pll_dco, G12B_CLK_sys1_pll, G12_CLK_fclk_div2_div, G12_CLK_fclk_div2, G12_CLK_fclk_div2p5_div, G12_CLK_fclk_div3_div, G12_CLK_fclk_div3, G12_CLK_fclk_div4_div, G12_CLK_fclk_div4, G12_CLK_fclk_div5_div, G12_CLK_fclk_div5, G12_CLK_fclk_div7_div, G12_CLK_fclk_div7, G12_CLK_mpll_prediv, G12_CLK_mpll0_div, G12_CLK_mpll1_div, G12_CLK_mpll2_div, G12_CLK_mpll0, G12_CLK_mpll1, G12_CLK_mpll2, G12_CLK_mpeg_sel, G12_CLK_mpeg_clk_div, G12_CLK_clk81, G12_CLK_mpll_50m_div, G12_CLK_mpll_50m, G12_CLK_sd_emmc_a_clk0_sel, G12_CLK_sd_emmc_b_clk0_sel, G12_CLK_sd_emmc_c_clk0_sel, G12_CLK_sd_emmc_a_clk0_div, G12_CLK_sd_emmc_b_clk0_div, G12_CLK_sd_emmc_c_clk0_div, G12_CLK_sd_emmc_a_clk0, G12_CLK_sd_emmc_b_clk0, G12_CLK_sd_emmc_c_clk0, G12_CLK_ddr, G12_CLK_dos, G12_CLK_audio_locker, G12_CLK_mipi_dsi_host, G12_CLK_eth_phy, G12_CLK_isa, G12_CLK_pl301, G12_CLK_periphs, G12_CLK_spicc0, G12_CLK_i2c, G12_CLK_sana, G12_CLK_sd, G12_CLK_rng0, G12_CLK_uart0, G12_CLK_spicc1, G12_CLK_hiu_iface, G12_CLK_mipi_dsi_phy, G12_CLK_assist_misc, G12_CLK_sd_emmc_a, G12_CLK_sd_emmc_b, G12_CLK_sd_emmc_c, G12_CLK_audio_codec, G12_CLK_audio, G12_CLK_eth, G12_CLK_demux, G12_CLK_audio_ififo, G12_CLK_adc, G12_CLK_uart1, G12_CLK_g2d, G12_CLK_reset, G12_CLK_pcie_comb, G12_CLK_parser, G12_CLK_usb, G12_CLK_pcie_phy, G12_CLK_ahb_arb0, G12_CLK_ahb_data_bus, G12_CLK_ahb_ctrl_bus, G12_CLK_htx_hdcp22, G12_CLK_htx_pclk, G12_CLK_bt656, G12_CLK_usb1_ddr_bridge, G12_CLK_mmc_pclk, G12_CLK_uart2, G12_CLK_vpu_intr, G12_CLK_gic, G12_CLK_vclk2_venci0, G12_CLK_vclk2_venci1, G12_CLK_vclk2_vencp0, G12_CLK_vclk2_vencp1, G12_CLK_vclk2_venct0, G12_CLK_vclk2_venct1, G12_CLK_vclk2_other, G12_CLK_vclk2_enci, G12_CLK_vclk2_encp, G12_CLK_dac_clk, G12_CLK_aoclk, G12_CLK_iec958, G12_CLK_enc480p, G12_CLK_rng1, G12_CLK_vclk2_enct, G12_CLK_vclk2_encl, G12_CLK_vclk2_venclmmc, G12_CLK_vclk2_vencl, G12_CLK_vclk2_other1, G12_CLK_dma, G12_CLK_efuse, G12_CLK_rom_boot, G12_CLK_reset_sec, G12_CLK_sec_ahb_apb3, G12_CLK_cpu_clk_dyn0_sel, G12_CLK_cpu_clk_dyn1_sel, G12_CLK_cpu_clk_dyn0_div, G12_CLK_cpu_clk_dyn1_div, G12_CLK_cpu_clk_dyn0, G12_CLK_cpu_clk_dyn1, G12_CLK_cpu_clk_dyn, G12B_CLK_cpu_clk, G12_CLK_cpub_clk_dyn0_sel, G12_CLK_cpub_clk_dyn0_div, G12_CLK_cpub_clk_dyn0, G12_CLK_cpub_clk_dyn1_sel, G12_CLK_cpub_clk_dyn1_div, G12_CLK_cpub_clk_dyn1, G12_CLK_cpub_clk_dyn, G12_CLK_cpub_clk, G12_CLK_ts_div, G12_CLK_ts, G12_CLK_hdmi_pll_dco, G12_CLK_hdmi_pll_od, G12_CLK_hdmi_pll_od2, G12_CLK_hdmi_pll, G12_CLK_vid_pll_div, G12_CLK_vid_pll_sel, G12_CLK_vid_pll, G12_CLK_pcie_pll_dco, G12_CLK_pcie_pll_dco_div2, G12_CLK_pcie_pll_od, G12_CLK_pcie_pll_pll }; /* * XXX: * mesong12_cpuclk_get_rate() is needed because the source clock exceeds 32bit * and sys/dev/clk cannot handle it. * By modifying sys/dev/clk to be able to handle 64-bit clocks, this function * will no longer be needed. */ static u_int mesong12_cpuclk_get_rate(struct meson_clk_softc *sc, struct meson_clk_clk *clk) { bus_size_t reg_cntl0; uint64_t freq; uint32_t val, m, n, div_shift, div; uint64_t xtal_clock = clk_get_rate(fdtbus_clock_byname("xtal")); KASSERT(clk->type == MESON_CLK_MUX); if (sc->sc_clks == mesong12a_clkc_clks) { reg_cntl0 = HHI_SYS_PLL_CNTL0; } else { switch (clk->u.mux.reg) { case HHI_SYS_CPU_CLK_CNTL0: reg_cntl0 = HHI_SYS1_PLL_CNTL0; break; case HHI_SYS_CPUB_CLK_CNTL: reg_cntl0 = HHI_SYS_PLL_CNTL0; break; default: panic("%s: illegal clk table\n", __func__); } } CLK_LOCK(sc); if ((CLK_READ(sc, clk->u.mux.reg) & __BIT(11)) == 0) { CLK_UNLOCK(sc); /* use dyn clock instead of sys1?_pll */ struct clk *clkp; switch (clk->u.mux.reg) { case HHI_SYS_CPU_CLK_CNTL0: clkp = (struct clk *)meson_clk_clock_find(sc, "cpu_clk_dyn"); freq = clk_get_rate(clkp); break; case HHI_SYS_CPUB_CLK_CNTL: clkp = (struct clk *)meson_clk_clock_find(sc, "cpub_clk_dyn"); freq = clk_get_rate(clkp); break; default: freq = 0; break; } return freq; } val = CLK_READ(sc, reg_cntl0); m = __SHIFTOUT(val, __BITS(7,0)); n = __SHIFTOUT(val, __BITS(14,10)); div_shift = __SHIFTOUT(val, __BITS(18,16)); div = 1 << div_shift; CLK_UNLOCK(sc); freq = xtal_clock * m / n / div; return freq; } static int mesong12_cpuclk_set_rate(struct meson_clk_softc *sc, struct meson_clk_clk *clk, u_int rate) { bus_size_t reg_cntl0; uint32_t val; uint64_t xtal_clock = clk_get_rate(fdtbus_clock_byname("xtal")); int new_m, new_n, new_div, i, error; KASSERT(clk->type == MESON_CLK_MUX); if (sc->sc_clks == mesong12a_clkc_clks) { reg_cntl0 = HHI_SYS_PLL_CNTL0; } else { switch (clk->u.mux.reg) { case HHI_SYS_CPU_CLK_CNTL0: reg_cntl0 = HHI_SYS1_PLL_CNTL0; break; case HHI_SYS_CPUB_CLK_CNTL: reg_cntl0 = HHI_SYS_PLL_CNTL0; break; default: panic("%s: illegal clk table\n", __func__); } } new_div = 7; new_n = 1; new_m = (uint64_t)rate * (1 << new_div) / xtal_clock; while (new_m >= 250 && (new_div > 0)) { new_div--; new_m /= 2; } if (new_m >= 256) return EINVAL; CLK_LOCK(sc); /* use cpub?_clk_dyn temporary */ val = CLK_READ(sc, clk->u.mux.reg); CLK_WRITE(sc, clk->u.mux.reg, val & ~__BIT(11)); DELAY(100); #define MESON_PLL_CNTL_REG_LOCK __BIT(31) #define MESON_PLL_CNTL_REG_RST __BIT(29) #define MESON_PLL_CNTL_REG_EN __BIT(28) /* disable */ val = CLK_READ(sc, reg_cntl0); CLK_WRITE(sc, reg_cntl0, val | MESON_PLL_CNTL_REG_RST); val = CLK_READ(sc, reg_cntl0); CLK_WRITE(sc, reg_cntl0, val & ~MESON_PLL_CNTL_REG_EN); /* HHI_SYS{,1}_PLL_CNTL{1,2,3,4,5} */ CLK_WRITE(sc, reg_cntl0 + CBUS_REG(1), 0x00000000); CLK_WRITE(sc, reg_cntl0 + CBUS_REG(2), 0x00000000); CLK_WRITE(sc, reg_cntl0 + CBUS_REG(3), 0x48681c00); CLK_WRITE(sc, reg_cntl0 + CBUS_REG(4), 0x88770290); CLK_WRITE(sc, reg_cntl0 + CBUS_REG(5), 0x39272000); DELAY(100); /* write new M, N, and DIV */ val = CLK_READ(sc, reg_cntl0); val &= ~__BITS(7,0); val |= __SHIFTIN(new_m, __BITS(7,0)); val &= ~__BITS(14,10); val |= __SHIFTIN(new_n, __BITS(14,10)); val &= ~__BITS(18,16); val |= __SHIFTIN(new_div, __BITS(18,16)); CLK_WRITE(sc, reg_cntl0, val); /* enable */ val = CLK_READ(sc, reg_cntl0); CLK_WRITE(sc, reg_cntl0, val | MESON_PLL_CNTL_REG_RST); val = CLK_READ(sc, reg_cntl0); CLK_WRITE(sc, reg_cntl0, val | MESON_PLL_CNTL_REG_EN); DELAY(1000); val = CLK_READ(sc, reg_cntl0); CLK_WRITE(sc, reg_cntl0, val & ~MESON_PLL_CNTL_REG_RST); error = ETIMEDOUT; for (i = 24000000; i > 0; i--) { if ((CLK_READ(sc, reg_cntl0) & MESON_PLL_CNTL_REG_LOCK) != 0) { error = 0; break; } } /* XXX: always use sys1?_pll. cpub?_clk_dyn should be used for <1GHz */ val = CLK_READ(sc, clk->u.mux.reg); CLK_WRITE(sc, clk->u.mux.reg, val | __BIT(11)); DELAY(100); CLK_UNLOCK(sc); return error; } static int mesong12_clk_pcie_pll_set_rate(struct meson_clk_softc *sc, struct meson_clk_clk *clk, u_int new_rate) { struct meson_clk_pll *pll = &clk->u.pll; KASSERT(clk->type == MESON_CLK_PLL); /* * A strict register sequence is required to set the PLL to the * fine-tuned 100MHz for PCIe */ if (new_rate == (100000000 * 2 * 2)) { /* "2*2" is fixed factor */ uint32_t cntl0, cntl4, cntl3, cntl5; cntl0 = __SHIFTIN(9, HHI_PCIE_PLL_CNTL0_PCIE_APLL_OD) | __SHIFTIN(1, HHI_PCIE_PLL_CNTL0_PCIE_APLL_PREDIV_SEL) | __SHIFTIN(150, HHI_PCIE_PLL_CNTL0_PCIE_APLL_FBKDIV); cntl4 = __SHIFTIN(1, HHI_PCIE_PLL_CNTL4_PCIE_APLL_LPF_CAPADJ) | HHI_PCIE_PLL_CNTL4_PCIE_APLL_LOAD | HHI_PCIE_PLL_CNTL4_PCIE_APLL_LOAD_EN; cntl3 = __SHIFTIN(1, HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_HOLD_T) | __SHIFTIN(2, HHI_PCIE_PLL_CNTL3_PCIE_APLL_AFC_DIV) | HHI_PCIE_PLL_CNTL3_PCIE_APLL_BIAS_LPF_EN | __SHIFTIN(8, HHI_PCIE_PLL_CNTL3_PCIE_APLL_CP_ICAP) | __SHIFTIN(14, HHI_PCIE_PLL_CNTL3_PCIE_APLL_CP_IRES); cntl5 = __SHIFTIN(6, HHI_PCIE_PLL_CNTL5_PCIE_HCSL_ADJ_LDO) | HHI_PCIE_PLL_CNTL5_PCIE_HCSL_BGP_EN | HHI_PCIE_PLL_CNTL5_PCIE_HCSL_CAL_EN | HHI_PCIE_PLL_CNTL5_PCIE_HCSL_EN0; CLK_LOCK(sc); CLK_WRITE_BITS(sc, pll->reset.reg, pll->reset.mask, 1); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL0, cntl0 | HHI_PCIE_PLL_CNTL0_PCIE_APLL_RESET); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL0, cntl0 | HHI_PCIE_PLL_CNTL0_PCIE_APLL_RESET | HHI_PCIE_PLL_CNTL0_PCIE_APLL_EN); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL1, 0); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL2, __SHIFTIN(0x1100, HHI_PCIE_PLL_CNTL2_PCIE_APLL_RESERVE)); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL3, cntl3); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL4, cntl4); delay(20); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL5, cntl5); delay(10); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL5, cntl5 | HHI_PCIE_PLL_CNTL5_PCIE_HCSL_CAL_RSTN); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL4, cntl4 | HHI_PCIE_PLL_CNTL4_PCIE_APLL_VCTRL_MON_EN); delay(10); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL0, cntl0 | HHI_PCIE_PLL_CNTL0_PCIE_APLL_RESET | HHI_PCIE_PLL_CNTL0_PCIE_APLL_EN | HHI_PCIE_PLL_CNTL0_PCIE_APLL_AFC_START); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL0, cntl0 | HHI_PCIE_PLL_CNTL0_PCIE_APLL_EN | HHI_PCIE_PLL_CNTL0_PCIE_APLL_AFC_START); CLK_WRITE(sc, HHI_PCIE_PLL_CNTL2, __SHIFTIN(0x1000, HHI_PCIE_PLL_CNTL2_PCIE_APLL_RESERVE)); CLK_WRITE_BITS(sc, pll->reset.reg, pll->reset.mask, 0); /* XXX: pll_wait_lock() sometimes times out? but ignore it */ meson_clk_pll_wait_lock(sc, pll); CLK_UNLOCK(sc); return 0; } return meson_clk_pll_set_rate(sc, clk, new_rate); } static const struct mesong12_clkc_config g12a_config = { .name = "Meson G12A", .clks = mesong12a_clkc_clks, .nclks = __arraycount(mesong12a_clkc_clks), }; static const struct mesong12_clkc_config g12b_config = { .name = "Meson G12B", .clks = mesong12b_clkc_clks, .nclks = __arraycount(mesong12b_clkc_clks), }; static const struct device_compatible_entry compat_data[] = { { .compat = "amlogic,g12a-clkc", .data = &g12a_config }, { .compat = "amlogic,g12b-clkc", .data = &g12b_config }, DEVICE_COMPAT_EOL }; CFATTACH_DECL_NEW(mesong12_clkc, sizeof(struct meson_clk_softc), mesong12_clkc_match, mesong12_clkc_attach, NULL, NULL); static int mesong12_clkc_match(device_t parent, cfdata_t cf, void *aux) { struct fdt_attach_args * const faa = aux; return of_compatible_match(faa->faa_phandle, compat_data); } static void mesong12_clkc_attach(device_t parent, device_t self, void *aux) { struct meson_clk_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; const struct mesong12_clkc_config *conf; const int phandle = faa->faa_phandle; sc->sc_dev = self; sc->sc_phandle = faa->faa_phandle; sc->sc_syscon = fdtbus_syscon_lookup(OF_parent(sc->sc_phandle)); if (sc->sc_syscon == NULL) { aprint_error(": couldn't get syscon registers\n"); return; } conf = of_compatible_lookup(phandle, compat_data)->data; sc->sc_clks = conf->clks; sc->sc_nclks = conf->nclks; aprint_naive("\n"); aprint_normal(": %s clock controller\n", conf->name); meson_clk_attach(sc); meson_clk_print(sc); }