Index: head/sys/arm64/rockchip/clk/rk3328_cru.c =================================================================== --- head/sys/arm64/rockchip/clk/rk3328_cru.c (revision 352849) +++ head/sys/arm64/rockchip/clk/rk3328_cru.c (revision 352850) @@ -1,1103 +1,1106 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot * 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GATES */ #define ACLK_PERI 153 #define PCLK_GPIO0 200 #define PCLK_GPIO1 201 #define PCLK_GPIO2 202 #define PCLK_GPIO3 203 #define PCLK_I2C0 205 #define PCLK_I2C1 206 #define PCLK_I2C2 207 #define PCLK_I2C3 208 #define HCLK_SDMMC 317 #define HCLK_SDIO 318 #define HCLK_EMMC 319 #define HCLK_SDMMC_EXT 320 static struct rk_cru_gate rk3328_gates[] = { /* CRU_CLKGATE_CON0 */ CRU_GATE(0, "apll_core", "apll", 0x200, 0) CRU_GATE(0, "dpll_core", "dpll", 0x200, 1) CRU_GATE(0, "gpll_core", "gpll", 0x200, 2) CRU_GATE(0, "npll_core", "npll", 0x200, 12) /* CRU_CLKGATE_CON4 */ CRU_GATE(0, "gpll_peri", "gpll", 0x210, 0) CRU_GATE(0, "cpll_peri", "cpll", 0x210, 1) /* CRU_CLKGATE_CON8 */ CRU_GATE(0, "pclk_bus", "pclk_bus_pre", 0x220, 3) CRU_GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0x220, 4) /* CRU_CLKGATE_CON10 */ CRU_GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0x228, 0) /* CRU_CLKGATE_CON15*/ CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0x23C, 10) /* CRU_CLKGATE_CON16 */ CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0x23C, 0) CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0x23C, 1) CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0x23C, 2) CRU_GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0x240, 7) CRU_GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0x240, 8) CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0x240, 9) CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0x240, 10) /* CRU_CLKGATE_CON19 */ CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0x24C, 0) CRU_GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0x24C, 1) CRU_GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0x24C, 2) CRU_GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0x24C, 15) }; /* * PLLs */ #define PLL_APLL 1 #define PLL_DPLL 2 #define PLL_CPLL 3 #define PLL_GPLL 4 #define PLL_NPLL 5 static struct rk_clk_pll_rate rk3328_pll_rates[] = { { .freq = 1608000000, .refdiv = 1, .fbdiv = 67, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1584000000, .refdiv = 1, .fbdiv = 66, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1560000000, .refdiv = 1, .fbdiv = 65, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1536000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1512000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1488000000, .refdiv = 1, .fbdiv = 62, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1464000000, .refdiv = 1, .fbdiv = 61, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1440000000, .refdiv = 1, .fbdiv = 60, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1416000000, .refdiv = 1, .fbdiv = 59, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1392000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1368000000, .refdiv = 1, .fbdiv = 57, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1344000000, .refdiv = 1, .fbdiv = 56, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1320000000, .refdiv = 1, .fbdiv = 55, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1296000000, .refdiv = 1, .fbdiv = 54, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1272000000, .refdiv = 1, .fbdiv = 53, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1248000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1200000000, .refdiv = 1, .fbdiv = 50, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1188000000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1104000000, .refdiv = 1, .fbdiv = 46, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1100000000, .refdiv = 12, .fbdiv = 550, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1008000000, .refdiv = 1, .fbdiv = 84, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1000000000, .refdiv = 6, .fbdiv = 500, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 984000000, .refdiv = 1, .fbdiv = 82, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 960000000, .refdiv = 1, .fbdiv = 80, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 936000000, .refdiv = 1, .fbdiv = 78, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 912000000, .refdiv = 1, .fbdiv = 76, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 900000000, .refdiv = 4, .fbdiv = 300, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 888000000, .refdiv = 1, .fbdiv = 74, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 864000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 840000000, .refdiv = 1, .fbdiv = 70, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 816000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 800000000, .refdiv = 6, .fbdiv = 400, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 700000000, .refdiv = 6, .fbdiv = 350, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 696000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 600000000, .refdiv = 1, .fbdiv = 75, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 594000000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 504000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 500000000, .refdiv = 6, .fbdiv = 250, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 408000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 312000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 216000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 4, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 96000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, {}, }; static struct rk_clk_pll_rate rk3328_pll_frac_rates[] = { { .freq = 1016064000, .refdiv = 3, .fbdiv = 127, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 0, .frac = 134217, }, { .freq = 983040000, .refdiv = 24, .fbdiv = 983, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 0, .frac = 671088, }, { .freq = 491520000, .refdiv = 24, .fbdiv = 983, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 0, .frac = 671088, }, { .freq = 61440000, .refdiv = 6, .fbdiv = 215, .postdiv1 = 7, .postdiv2 = 2, .dsmpd = 0, .frac = 671088, }, { .freq = 56448000, .refdiv = 12, .fbdiv = 451, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 0, .frac = 9797894, }, { .freq = 40960000, .refdiv = 12, .fbdiv = 409, .postdiv1 = 4, .postdiv2 = 5, .dsmpd = 0, .frac = 10066329, }, {}, }; static const char *pll_parents[] = {"xin24m"}; static struct rk_clk_pll_def apll = { .clkdef = { .id = PLL_APLL, .name = "apll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x00, .gate_offset = 0x200, .gate_shift = 0, .mode_reg = 0x80, .mode_shift = 1, .flags = RK_CLK_PLL_HAVE_GATE, .frac_rates = rk3328_pll_frac_rates, }; static struct rk_clk_pll_def dpll = { .clkdef = { .id = PLL_DPLL, .name = "dpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x20, .gate_offset = 0x200, .gate_shift = 1, .mode_reg = 0x80, .mode_shift = 4, .flags = RK_CLK_PLL_HAVE_GATE, }; static struct rk_clk_pll_def cpll = { .clkdef = { .id = PLL_CPLL, .name = "cpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x40, .mode_reg = 0x80, .mode_shift = 8, .rates = rk3328_pll_rates, }; static struct rk_clk_pll_def gpll = { .clkdef = { .id = PLL_GPLL, .name = "gpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x60, .gate_offset = 0x200, .gate_shift = 2, .mode_reg = 0x80, .mode_shift = 12, .flags = RK_CLK_PLL_HAVE_GATE, .frac_rates = rk3328_pll_frac_rates, }; static struct rk_clk_pll_def npll = { .clkdef = { .id = PLL_NPLL, .name = "npll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0xa0, .gate_offset = 0x200, .gate_shift = 12, .mode_reg = 0x80, .mode_shift = 1, .flags = RK_CLK_PLL_HAVE_GATE, .rates = rk3328_pll_rates, }; /* CRU_CLKSEL_CON0 */ #define ACLK_BUS_PRE 136 /* Needs hdmiphy as parent too*/ static const char *aclk_bus_pre_parents[] = {"cpll", "gpll"}; static struct rk_clk_composite_def aclk_bus_pre = { .clkdef = { .id = ACLK_BUS_PRE, .name = "aclk_bus_pre", .parent_names = aclk_bus_pre_parents, .parent_cnt = nitems(aclk_bus_pre_parents), }, .muxdiv_offset = 0x100, .mux_shift = 13, .mux_width = 2, .div_shift = 8, .div_width = 5, .gate_offset = 0x220, .gate_shift = 0, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_armclk_rates rk3328_armclk_rates[] = { { .freq = 1296000000, .div = 1, }, { .freq = 1200000000, .div = 1, }, { .freq = 1104000000, .div = 1, }, { .freq = 1008000000, .div = 1, }, { .freq = 912000000, .div = 1, }, { .freq = 816000000, .div = 1, }, { .freq = 696000000, .div = 1, }, { .freq = 600000000, .div = 1, }, { .freq = 408000000, .div = 1, }, { .freq = 312000000, .div = 1, }, { .freq = 216000000, .div = 1, }, { .freq = 96000000, .div = 1, }, }; #define ARMCLK 6 static const char *armclk_parents[] = {"apll", "gpll", "dpll", "npll" }; static struct rk_clk_armclk_def armclk = { .clkdef = { .id = ARMCLK, .name = "armclk", .parent_names = armclk_parents, .parent_cnt = nitems(armclk_parents), }, .muxdiv_offset = 0x100, .mux_shift = 6, .mux_width = 2, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, .main_parent = 3, /* npll */ .alt_parent = 0, /* apll */ .rates = rk3328_armclk_rates, .nrates = nitems(rk3328_armclk_rates), }; /* CRU_CLKSEL_CON1 */ #define PCLK_BUS_PRE 216 #define HCLK_BUS_PRE 328 static const char *hclk_bus_pre_parents[] = {"aclk_bus_pre"}; static struct rk_clk_composite_def hclk_bus_pre = { .clkdef = { .id = HCLK_BUS_PRE, .name = "hclk_bus_pre", .parent_names = hclk_bus_pre_parents, .parent_cnt = nitems(hclk_bus_pre_parents), }, .muxdiv_offset = 0x104, .div_shift = 8, .div_width = 2, .gate_offset = 0x220, .gate_shift = 1, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; static const char *pclk_bus_pre_parents[] = {"aclk_bus_pre"}; static struct rk_clk_composite_def pclk_bus_pre = { .clkdef = { .id = PCLK_BUS_PRE, .name = "pclk_bus_pre", .parent_names = pclk_bus_pre_parents, .parent_cnt = nitems(pclk_bus_pre_parents), }, .muxdiv_offset = 0x104, .div_shift = 12, .div_width = 3, .gate_offset = 0x220, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON28 */ #define ACLK_PERI_PRE 137 static const char *aclk_peri_pre_parents[] = {"cpll", "gpll"/* , "hdmiphy" */}; static struct rk_clk_composite_def aclk_peri_pre = { .clkdef = { .id = ACLK_PERI_PRE, .name = "aclk_peri_pre", .parent_names = aclk_peri_pre_parents, .parent_cnt = nitems(aclk_peri_pre_parents), }, .muxdiv_offset = 0x170, .mux_shift = 6, .mux_width = 2, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, }; /* CRU_CLKSEL_CON29 */ #define PCLK_PERI 230 #define HCLK_PERI 308 static const char *phclk_peri_parents[] = {"aclk_peri_pre"}; static struct rk_clk_composite_def pclk_peri = { .clkdef = { .id = PCLK_PERI, .name = "pclk_peri", .parent_names = phclk_peri_parents, .parent_cnt = nitems(phclk_peri_parents), }, .div_shift = 0, .div_width = 2, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x228, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def hclk_peri = { .clkdef = { .id = HCLK_PERI, .name = "hclk_peri", .parent_names = phclk_peri_parents, .parent_cnt = nitems(phclk_peri_parents), }, .div_shift = 4, .div_width = 3, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x228, .gate_shift = 1, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON30 */ #define SCLK_SDMMC 33 static const char *mmc_parents[] = {"cpll", "gpll", "xin24m"/* , "usb480m" */}; static struct rk_clk_composite_def sdmmc = { .clkdef = { .id = SCLK_SDMMC, .name = "clk_sdmmc", .parent_names = mmc_parents, .parent_cnt = nitems(mmc_parents), }, .muxdiv_offset = 0x178, .mux_shift = 8, .mux_width = 2, .div_shift = 0, .div_width = 8, /* CRU_CLKGATE_CON4 */ .gate_offset = 0x210, .gate_shift = 3, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON31 */ #define SCLK_SDIO 34 static struct rk_clk_composite_def sdio = { .clkdef = { .id = SCLK_SDIO, .name = "clk_sdio", .parent_names = mmc_parents, .parent_cnt = nitems(mmc_parents), }, .muxdiv_offset = 0x17C, .mux_shift = 8, .mux_width = 2, .div_shift = 0, .div_width = 8, /* CRU_CLKGATE_CON4 */ .gate_offset = 0x210, .gate_shift = 4, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON32 */ #define SCLK_EMMC 35 static struct rk_clk_composite_def emmc = { .clkdef = { .id = SCLK_EMMC, .name = "clk_emmc", .parent_names = mmc_parents, .parent_cnt = nitems(mmc_parents), }, .muxdiv_offset = 0x180, .mux_shift = 8, .mux_width = 2, .div_shift = 0, .div_width = 8, /* CRU_CLKGATE_CON4 */ .gate_offset = 0x210, .gate_shift = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON34 */ #define SCLK_I2C0 55 #define SCLK_I2C1 56 static const char *i2c_parents[] = {"cpll", "gpll"}; static struct rk_clk_composite_def i2c0 = { .clkdef = { .id = SCLK_I2C0, .name = "clk_i2c0", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, .muxdiv_offset = 0x188, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 6, /* CRU_CLKGATE_CON2 */ .gate_offset = 0x208, .gate_shift = 9, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c1 = { .clkdef = { .id = SCLK_I2C1, .name = "clk_i2c1", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, .muxdiv_offset = 0x188, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 6, /* CRU_CLKGATE_CON2 */ .gate_offset = 0x208, .gate_shift = 10, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* CRU_CLKSEL_CON35 */ #define SCLK_I2C2 57 #define SCLK_I2C3 58 static struct rk_clk_composite_def i2c2 = { .clkdef = { .id = SCLK_I2C2, .name = "clk_i2c2", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, .muxdiv_offset = 0x18C, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 6, /* CRU_CLKGATE_CON2 */ .gate_offset = 0x208, .gate_shift = 11, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c3 = { .clkdef = { .id = SCLK_I2C3, .name = "clk_i2c3", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, .muxdiv_offset = 0x18C, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 6, /* CRU_CLKGATE_CON2 */ .gate_offset = 0x208, .gate_shift = 12, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk rk3328_clks[] = { { .type = RK3328_CLK_PLL, .clk.pll = &apll }, { .type = RK3328_CLK_PLL, .clk.pll = &dpll }, { .type = RK3328_CLK_PLL, .clk.pll = &cpll }, { .type = RK3328_CLK_PLL, .clk.pll = &gpll }, { .type = RK3328_CLK_PLL, .clk.pll = &npll }, { .type = RK_CLK_COMPOSITE, .clk.composite = &aclk_bus_pre }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_bus_pre }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_bus_pre }, { .type = RK_CLK_ARMCLK, .clk.armclk = &armclk, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &aclk_peri_pre, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_peri, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_peri, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &sdmmc }, { .type = RK_CLK_COMPOSITE, .clk.composite = &sdio }, { .type = RK_CLK_COMPOSITE, .clk.composite = &emmc }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c0 }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c1 }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c2 }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c3 }, }; static int rk3328_cru_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_is_compatible(dev, "rockchip,rk3328-cru")) { device_set_desc(dev, "Rockchip RK3328 Clock and Reset Unit"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } static int rk3328_cru_attach(device_t dev) { struct rk_cru_softc *sc; sc = device_get_softc(dev); sc->dev = dev; sc->gates = rk3328_gates; sc->ngates = nitems(rk3328_gates); sc->clks = rk3328_clks; sc->nclks = nitems(rk3328_clks); + sc->reset_offset = 0x300; + sc->reset_num = 184; + return (rk_cru_attach(dev)); } static device_method_t rk3328_cru_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk3328_cru_probe), DEVMETHOD(device_attach, rk3328_cru_attach), DEVMETHOD_END }; static devclass_t rk3328_cru_devclass; DEFINE_CLASS_1(rk3328_cru, rk3328_cru_driver, rk3328_cru_methods, sizeof(struct rk_cru_softc), rk_cru_driver); EARLY_DRIVER_MODULE(rk3328_cru, simplebus, rk3328_cru_driver, rk3328_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); Index: head/sys/arm64/rockchip/clk/rk3399_cru.c =================================================================== --- head/sys/arm64/rockchip/clk/rk3399_cru.c (revision 352849) +++ head/sys/arm64/rockchip/clk/rk3399_cru.c (revision 352850) @@ -1,1693 +1,1696 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot * Copyright (c) 2018 Greg V * * 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GATES */ #define SCLK_USB2PHY0_REF 123 #define SCLK_USB2PHY1_REF 124 #define ACLK_EMMC_CORE 241 #define ACLK_EMMC_NOC 242 #define ACLK_EMMC_GRF 243 #define PCLK_GPIO2 336 #define PCLK_GPIO3 337 #define PCLK_GPIO4 338 #define PCLK_I2C1 341 #define PCLK_I2C2 342 #define PCLK_I2C3 343 #define PCLK_I2C5 344 #define PCLK_I2C6 345 #define PCLK_I2C7 346 #define HCLK_HOST0 456 #define HCLK_HOST0_ARB 457 #define HCLK_HOST1 458 #define HCLK_HOST1_ARB 459 #define HCLK_SDMMC 462 static struct rk_cru_gate rk3399_gates[] = { /* CRU_CLKGATE_CON0 */ CRU_GATE(0, "clk_core_l_lpll_src", "lpll", 0x300, 0) CRU_GATE(0, "clk_core_l_bpll_src", "bpll", 0x300, 1) CRU_GATE(0, "clk_core_l_dpll_src", "dpll", 0x300, 2) CRU_GATE(0, "clk_core_l_gpll_src", "gpll", 0x300, 3) /* CRU_CLKGATE_CON1 */ CRU_GATE(0, "clk_core_b_lpll_src", "lpll", 0x304, 0) CRU_GATE(0, "clk_core_b_bpll_src", "bpll", 0x304, 1) CRU_GATE(0, "clk_core_b_dpll_src", "dpll", 0x304, 2) CRU_GATE(0, "clk_core_b_gpll_src", "gpll", 0x304, 3) /* CRU_CLKGATE_CON5 */ CRU_GATE(0, "cpll_aclk_perihp_src", "cpll", 0x314, 0) CRU_GATE(0, "gpll_aclk_perihp_src", "gpll", 0x314, 1) /* CRU_CLKGATE_CON6 */ CRU_GATE(0, "gpll_aclk_emmc_src", "gpll", 0x318, 12) CRU_GATE(0, "cpll_aclk_emmc_src", "cpll", 0x318, 13) CRU_GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", 0x318, 5) CRU_GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", 0x318, 6) /* CRU_CLKGATE_CON7 */ CRU_GATE(0, "gpll_aclk_perilp0_src", "gpll", 0x31C, 0) CRU_GATE(0, "cpll_aclk_perilp0_src", "cpll", 0x31C, 1) /* CRU_CLKGATE_CON8 */ CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1) CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0) /* CRU_CLKGATE_CON20 */ CRU_GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0x350, 5) CRU_GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0x350, 6) CRU_GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0x350, 7) CRU_GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0x350, 8) /* CRU_CLKGATE_CON22 */ CRU_GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0x358, 5) CRU_GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0x358, 6) CRU_GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0x358, 7) CRU_GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0x358, 8) CRU_GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0x358, 9) CRU_GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0x358, 10) /* CRU_CLKGATE_CON31 */ CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0x37c, 3) CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0x37c, 4) CRU_GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0x37c, 5) /* CRU_CLKGATE_CON32 */ CRU_GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", 0x380, 8) CRU_GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", 0x380, 9) CRU_GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", 0x380, 10) /* CRU_CLKGATE_CON33 */ CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0x384, 8) }; /* * PLLs */ #define PLL_APLLL 1 #define PLL_APLLB 2 #define PLL_DPLL 3 #define PLL_CPLL 4 #define PLL_GPLL 5 #define PLL_NPLL 6 #define PLL_VPLL 7 static struct rk_clk_pll_rate rk3399_pll_rates[] = { { .freq = 2208000000, .refdiv = 1, .fbdiv = 92, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2184000000, .refdiv = 1, .fbdiv = 91, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2160000000, .refdiv = 1, .fbdiv = 90, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2136000000, .refdiv = 1, .fbdiv = 89, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2112000000, .refdiv = 1, .fbdiv = 88, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2088000000, .refdiv = 1, .fbdiv = 87, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2064000000, .refdiv = 1, .fbdiv = 86, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2040000000, .refdiv = 1, .fbdiv = 85, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2016000000, .refdiv = 1, .fbdiv = 84, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1992000000, .refdiv = 1, .fbdiv = 83, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1968000000, .refdiv = 1, .fbdiv = 82, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1944000000, .refdiv = 1, .fbdiv = 81, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1920000000, .refdiv = 1, .fbdiv = 80, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1896000000, .refdiv = 1, .fbdiv = 79, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1872000000, .refdiv = 1, .fbdiv = 78, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1848000000, .refdiv = 1, .fbdiv = 77, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1824000000, .refdiv = 1, .fbdiv = 76, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1800000000, .refdiv = 1, .fbdiv = 75, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1776000000, .refdiv = 1, .fbdiv = 74, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1752000000, .refdiv = 1, .fbdiv = 73, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1728000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1704000000, .refdiv = 1, .fbdiv = 71, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1680000000, .refdiv = 1, .fbdiv = 70, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1656000000, .refdiv = 1, .fbdiv = 69, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1632000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1608000000, .refdiv = 1, .fbdiv = 67, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1600000000, .refdiv = 3, .fbdiv = 200, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1584000000, .refdiv = 1, .fbdiv = 66, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1560000000, .refdiv = 1, .fbdiv = 65, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1536000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1512000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1488000000, .refdiv = 1, .fbdiv = 62, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1464000000, .refdiv = 1, .fbdiv = 61, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1440000000, .refdiv = 1, .fbdiv = 60, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1416000000, .refdiv = 1, .fbdiv = 59, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1392000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1368000000, .refdiv = 1, .fbdiv = 57, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1344000000, .refdiv = 1, .fbdiv = 56, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1320000000, .refdiv = 1, .fbdiv = 55, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1296000000, .refdiv = 1, .fbdiv = 54, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1272000000, .refdiv = 1, .fbdiv = 53, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1248000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1200000000, .refdiv = 1, .fbdiv = 50, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1188000000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1104000000, .refdiv = 1, .fbdiv = 46, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1100000000, .refdiv = 12, .fbdiv = 550, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1008000000, .refdiv = 1, .fbdiv = 84, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1000000000, .refdiv = 1, .fbdiv = 125, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 984000000, .refdiv = 1, .fbdiv = 82, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 960000000, .refdiv = 1, .fbdiv = 80, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 936000000, .refdiv = 1, .fbdiv = 78, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 912000000, .refdiv = 1, .fbdiv = 76, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 900000000, .refdiv = 4, .fbdiv = 300, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 888000000, .refdiv = 1, .fbdiv = 74, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 864000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 840000000, .refdiv = 1, .fbdiv = 70, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 816000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 800000000, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 700000000, .refdiv = 6, .fbdiv = 350, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 696000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 676000000, .refdiv = 3, .fbdiv = 169, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 600000000, .refdiv = 1, .fbdiv = 75, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 594000000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 533250000, .refdiv = 8, .fbdiv = 711, .postdiv1 = 4, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 504000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 500000000, .refdiv = 6, .fbdiv = 250, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 408000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 312000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 297000000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 216000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 4, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 148500000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 106500000, .refdiv = 1, .fbdiv = 71, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 96000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 74250000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 65000000, .refdiv = 1, .fbdiv = 65, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 54000000, .refdiv = 1, .fbdiv = 54, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 27000000, .refdiv = 1, .fbdiv = 27, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, {}, }; static const char *pll_parents[] = {"xin24m"}; static struct rk_clk_pll_def lpll = { .clkdef = { .id = PLL_APLLL, .name = "lpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x00, .gate_offset = 0x300, .gate_shift = 0, .flags = RK_CLK_PLL_HAVE_GATE, .rates = rk3399_pll_rates, .normal_mode = true, }; static struct rk_clk_pll_def bpll = { .clkdef = { .id = PLL_APLLB, .name = "bpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x20, .gate_offset = 0x300, .gate_shift = 1, .flags = RK_CLK_PLL_HAVE_GATE, .rates = rk3399_pll_rates, .normal_mode = true, }; static struct rk_clk_pll_def dpll = { .clkdef = { .id = PLL_DPLL, .name = "dpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x40, .gate_offset = 0x300, .gate_shift = 2, .flags = RK_CLK_PLL_HAVE_GATE, .rates = rk3399_pll_rates, }; static struct rk_clk_pll_def cpll = { .clkdef = { .id = PLL_CPLL, .name = "cpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x60, .rates = rk3399_pll_rates, }; static struct rk_clk_pll_def gpll = { .clkdef = { .id = PLL_GPLL, .name = "gpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x80, .gate_offset = 0x300, .gate_shift = 3, .flags = RK_CLK_PLL_HAVE_GATE, .rates = rk3399_pll_rates, }; static struct rk_clk_pll_def npll = { .clkdef = { .id = PLL_NPLL, .name = "npll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0xa0, .rates = rk3399_pll_rates, }; static struct rk_clk_pll_def vpll = { .clkdef = { .id = PLL_VPLL, .name = "vpll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0xc0, .rates = rk3399_pll_rates, }; #define ACLK_PERIHP 192 #define HCLK_PERIHP 448 #define PCLK_PERIHP 320 static const char *aclk_perihp_parents[] = {"cpll_aclk_perihp_src", "gpll_aclk_perihp_src"}; static struct rk_clk_composite_def aclk_perihp = { .clkdef = { .id = ACLK_PERIHP, .name = "aclk_perihp", .parent_names = aclk_perihp_parents, .parent_cnt = nitems(aclk_perihp_parents), }, /* CRU_CLKSEL_CON14 */ .muxdiv_offset = 0x138, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 5, /* CRU_CLKGATE_CON5 */ .gate_offset = 0x314, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static const char *hclk_pclk_perihp_parents[] = {"aclk_perihp"}; static struct rk_clk_composite_def hclk_perihp = { .clkdef = { .id = HCLK_PERIHP, .name = "hclk_perihp", .parent_names = hclk_pclk_perihp_parents, .parent_cnt = nitems(hclk_pclk_perihp_parents), }, /* CRU_CLKSEL_CON14 */ .muxdiv_offset = 0x138, .div_shift = 8, .div_width = 2, /* CRU_CLKGATE_CON5 */ .gate_offset = 0x314, .gate_shift = 3, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def pclk_perihp = { .clkdef = { .id = PCLK_PERIHP, .name = "pclk_perihp", .parent_names = hclk_pclk_perihp_parents, .parent_cnt = nitems(hclk_pclk_perihp_parents), }, /* CRU_CLKSEL_CON14 */ .muxdiv_offset = 0x138, .div_shift = 12, .div_width = 3, /* CRU_CLKGATE_CON5 */ .gate_offset = 0x314, .gate_shift = 4, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; #define ACLK_PERILP0 194 #define HCLK_PERILP0 449 #define PCLK_PERILP0 322 static const char *aclk_perilp0_parents[] = {"cpll_aclk_perilp0_src", "gpll_aclk_perilp0_src"}; static struct rk_clk_composite_def aclk_perilp0 = { .clkdef = { .id = ACLK_PERILP0, .name = "aclk_perilp0", .parent_names = aclk_perilp0_parents, .parent_cnt = nitems(aclk_perilp0_parents), }, /* CRU_CLKSEL_CON14 */ .muxdiv_offset = 0x15C, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 5, /* CRU_CLKGATE_CON7 */ .gate_offset = 0x31C, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static const char *hclk_pclk_perilp0_parents[] = {"aclk_perilp0"}; static struct rk_clk_composite_def hclk_perilp0 = { .clkdef = { .id = HCLK_PERILP0, .name = "hclk_perilp0", .parent_names = hclk_pclk_perilp0_parents, .parent_cnt = nitems(hclk_pclk_perilp0_parents), }, /* CRU_CLKSEL_CON23 */ .muxdiv_offset = 0x15C, .div_shift = 8, .div_width = 2, /* CRU_CLKGATE_CON7 */ .gate_offset = 0x31C, .gate_shift = 3, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def pclk_perilp0 = { .clkdef = { .id = PCLK_PERILP0, .name = "pclk_perilp0", .parent_names = hclk_pclk_perilp0_parents, .parent_cnt = nitems(hclk_pclk_perilp0_parents), }, /* CRU_CLKSEL_CON23 */ .muxdiv_offset = 0x15C, .div_shift = 12, .div_width = 3, /* CRU_CLKGATE_CON7 */ .gate_offset = 0x31C, .gate_shift = 4, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* * misc */ #define PCLK_ALIVE 390 static const char *alive_parents[] = {"gpll"}; static struct rk_clk_composite_def pclk_alive = { .clkdef = { .id = PCLK_ALIVE, .name = "pclk_alive", .parent_names = alive_parents, .parent_cnt = nitems(alive_parents), }, /* CRU_CLKSEL_CON57 */ .muxdiv_offset = 0x01e4, .div_shift = 0, .div_width = 5, }; #define HCLK_PERILP1 450 #define PCLK_PERILP1 323 static const char *hclk_perilp1_parents[] = {"cpll", "gpll"}; static struct rk_clk_composite_def hclk_perilp1 = { .clkdef = { .id = HCLK_PERILP1, .name = "hclk_perilp1", .parent_names = hclk_perilp1_parents, .parent_cnt = nitems(hclk_perilp1_parents), }, /* CRU_CLKSEL_CON25 */ .muxdiv_offset = 0x164, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, }; static const char *pclk_perilp1_parents[] = {"hclk_perilp1"}; static struct rk_clk_composite_def pclk_perilp1 = { .clkdef = { .id = PCLK_PERILP1, .name = "pclk_perilp1", .parent_names = pclk_perilp1_parents, .parent_cnt = nitems(pclk_perilp1_parents), }, /* CRU_CLKSEL_CON25 */ .muxdiv_offset = 0x164, .div_shift = 8, .div_width = 3, /* CRU_CLKGATE_CON8 */ .gate_offset = 0x320, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; /* * i2c */ static const char *i2c_parents[] = {"cpll", "gpll"}; #define SCLK_I2C1 65 #define SCLK_I2C2 66 #define SCLK_I2C3 67 #define SCLK_I2C5 68 #define SCLK_I2C6 69 #define SCLK_I2C7 70 static struct rk_clk_composite_def i2c1 = { .clkdef = { .id = SCLK_I2C1, .name = "clk_i2c1", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON61 */ .muxdiv_offset = 0x01f4, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 0, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c2 = { .clkdef = { .id = SCLK_I2C2, .name = "clk_i2c2", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON62 */ .muxdiv_offset = 0x01f8, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 2, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c3 = { .clkdef = { .id = SCLK_I2C3, .name = "clk_i2c3", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON63 */ .muxdiv_offset = 0x01fc, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 4, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c5 = { .clkdef = { .id = SCLK_I2C5, .name = "clk_i2c5", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON61 */ .muxdiv_offset = 0x01f4, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 1, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c6 = { .clkdef = { .id = SCLK_I2C6, .name = "clk_i2c6", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON62 */ .muxdiv_offset = 0x01f8, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 3, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c7 = { .clkdef = { .id = SCLK_I2C7, .name = "clk_i2c7", .parent_names = i2c_parents, .parent_cnt = nitems(i2c_parents), }, /* CRU_CLKSEL_CON63 */ .muxdiv_offset = 0x01fc, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 7, /* CRU_CLKGATE_CON10 */ .gate_offset = 0x0328, .gate_shift = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* * ARM CPU clocks (LITTLE and big) */ #define ARMCLKL 8 #define ARMCLKB 9 static const char *armclk_parents[] = {"lpll", "bpll", "dpll", "gpll"}; static struct rk_clk_armclk_rates rk3399_armclkl_rates[] = { { .freq = 1800000000, .div = 1, }, { .freq = 1704000000, .div = 1, }, { .freq = 1608000000, .div = 1, }, { .freq = 1512000000, .div = 1, }, { .freq = 1488000000, .div = 1, }, { .freq = 1416000000, .div = 1, }, { .freq = 1200000000, .div = 1, }, { .freq = 1008000000, .div = 1, }, { .freq = 816000000, .div = 1, }, { .freq = 696000000, .div = 1, }, { .freq = 600000000, .div = 1, }, { .freq = 408000000, .div = 1, }, { .freq = 312000000, .div = 1, }, { .freq = 216000000, .div = 1, }, { .freq = 96000000, .div = 1, }, }; static struct rk_clk_armclk_def armclk_l = { .clkdef = { .id = ARMCLKL, .name = "armclkl", .parent_names = armclk_parents, .parent_cnt = nitems(armclk_parents), }, /* CRU_CLKSEL_CON0 */ .muxdiv_offset = 0x100, .mux_shift = 6, .mux_width = 2, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, .main_parent = 0, .alt_parent = 3, .rates = rk3399_armclkl_rates, .nrates = nitems(rk3399_armclkl_rates), }; static struct rk_clk_armclk_rates rk3399_armclkb_rates[] = { { .freq = 2208000000, .div = 1, }, { .freq = 2184000000, .div = 1, }, { .freq = 2088000000, .div = 1, }, { .freq = 2040000000, .div = 1, }, { .freq = 2016000000, .div = 1, }, { .freq = 1992000000, .div = 1, }, { .freq = 1896000000, .div = 1, }, { .freq = 1800000000, .div = 1, }, { .freq = 1704000000, .div = 1, }, { .freq = 1608000000, .div = 1, }, { .freq = 1512000000, .div = 1, }, { .freq = 1488000000, .div = 1, }, { .freq = 1416000000, .div = 1, }, { .freq = 1200000000, .div = 1, }, { .freq = 1008000000, .div = 1, }, { .freq = 816000000, .div = 1, }, { .freq = 696000000, .div = 1, }, { .freq = 600000000, .div = 1, }, { .freq = 408000000, .div = 1, }, { .freq = 312000000, .div = 1, }, { .freq = 216000000, .div = 1, }, { .freq = 96000000, .div = 1, }, }; static struct rk_clk_armclk_def armclk_b = { .clkdef = { .id = ARMCLKB, .name = "armclkb", .parent_names = armclk_parents, .parent_cnt = nitems(armclk_parents), }, .muxdiv_offset = 0x108, .mux_shift = 6, .mux_width = 2, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, .main_parent = 1, .alt_parent = 3, .rates = rk3399_armclkb_rates, .nrates = nitems(rk3399_armclkb_rates), }; /* * sdmmc */ #define HCLK_SD 461 static const char *hclk_sd_parents[] = {"cpll", "gpll"}; static struct rk_clk_composite_def hclk_sd = { .clkdef = { .id = HCLK_SD, .name = "hclk_sd", .parent_names = hclk_sd_parents, .parent_cnt = nitems(hclk_sd_parents), }, .muxdiv_offset = 0x134, .mux_shift = 15, .mux_width = 1, .div_shift = 8, .div_width = 5, .gate_offset = 0x330, .gate_shift = 13, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; #define SCLK_SDMMC 76 static const char *sclk_sdmmc_parents[] = {"cpll", "gpll", "npll", "ppll"}; static struct rk_clk_composite_def sclk_sdmmc = { .clkdef = { .id = SCLK_SDMMC, .name = "sclk_sdmmc", .parent_names = sclk_sdmmc_parents, .parent_cnt = nitems(sclk_sdmmc_parents), }, .muxdiv_offset = 0x140, .mux_shift = 8, .mux_width = 3, .div_shift = 0, .div_width = 7, .gate_offset = 0x318, .gate_shift = 1, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; /* * emmc */ #define SCLK_EMMC 78 static const char *sclk_emmc_parents[] = {"cpll", "gpll", "npll"}; static struct rk_clk_composite_def sclk_emmc = { .clkdef = { .id = SCLK_EMMC, .name = "sclk_emmc", .parent_names = sclk_emmc_parents, .parent_cnt = nitems(sclk_emmc_parents), }, .muxdiv_offset = 0x158, .mux_shift = 8, .mux_width = 3, .div_shift = 0, .div_width = 7, .gate_offset = 0x318, .gate_shift = 14, .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, }; #define ACLK_EMMC 240 static const char *aclk_emmc_parents[] = { "cpll_aclk_emmc_src", "gpll_aclk_emmc_src" }; static struct rk_clk_composite_def aclk_emmc = { .clkdef = { .id = ACLK_EMMC, .name = "aclk_emmc", .parent_names = aclk_emmc_parents, .parent_cnt = nitems(aclk_emmc_parents), }, .muxdiv_offset = 0x154, .mux_shift = 7, .mux_width = 1, .div_shift = 0, .div_width = 5, .flags = RK_CLK_COMPOSITE_HAVE_MUX, }; static struct rk_clk rk3399_clks[] = { { .type = RK3399_CLK_PLL, .clk.pll = &lpll }, { .type = RK3399_CLK_PLL, .clk.pll = &bpll }, { .type = RK3399_CLK_PLL, .clk.pll = &dpll }, { .type = RK3399_CLK_PLL, .clk.pll = &cpll }, { .type = RK3399_CLK_PLL, .clk.pll = &gpll }, { .type = RK3399_CLK_PLL, .clk.pll = &npll }, { .type = RK3399_CLK_PLL, .clk.pll = &vpll }, { .type = RK_CLK_COMPOSITE, .clk.composite = &aclk_perihp, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_perihp, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_perihp, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &aclk_perilp0, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_perilp0, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_perilp0, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_alive, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_perilp1, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_perilp1, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c1, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c2, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c3, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c5, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c6, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c7, }, { .type = RK_CLK_ARMCLK, .clk.armclk = &armclk_l, }, { .type = RK_CLK_ARMCLK, .clk.armclk = &armclk_b, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &hclk_sd, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &sclk_sdmmc, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &sclk_emmc, }, { .type = RK_CLK_COMPOSITE, .clk.composite = &aclk_emmc, }, }; static int rk3399_cru_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_is_compatible(dev, "rockchip,rk3399-cru")) { device_set_desc(dev, "Rockchip RK3399 Clock and Reset Unit"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } static int rk3399_cru_attach(device_t dev) { struct rk_cru_softc *sc; sc = device_get_softc(dev); sc->dev = dev; sc->gates = rk3399_gates; sc->ngates = nitems(rk3399_gates); sc->clks = rk3399_clks; sc->nclks = nitems(rk3399_clks); + sc->reset_offset = 0x400; + sc->reset_num = 335; + return (rk_cru_attach(dev)); } static device_method_t rk3399_cru_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk3399_cru_probe), DEVMETHOD(device_attach, rk3399_cru_attach), DEVMETHOD_END }; static devclass_t rk3399_cru_devclass; DEFINE_CLASS_1(rk3399_cru, rk3399_cru_driver, rk3399_cru_methods, sizeof(struct rk_cru_softc), rk_cru_driver); EARLY_DRIVER_MODULE(rk3399_cru, simplebus, rk3399_cru_driver, rk3399_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); Index: head/sys/arm64/rockchip/clk/rk3399_pmucru.c =================================================================== --- head/sys/arm64/rockchip/clk/rk3399_pmucru.c (revision 352849) +++ head/sys/arm64/rockchip/clk/rk3399_pmucru.c (revision 352850) @@ -1,866 +1,869 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot * Copyright (c) 2018 Greg V * * 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. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GATES */ #define PCLK_PMU 20 #define PCLK_GPIO0_PMU 23 #define PCLK_GPIO1_PMU 24 #define PCLK_I2C0_PMU 27 #define PCLK_I2C4_PMU 28 #define PCLK_I2C8_PMU 29 static struct rk_cru_gate rk3399_pmu_gates[] = { /* PMUCRU_CLKGATE_CON1 */ CRU_GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", 0x104, 0) CRU_GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 0x104, 3) CRU_GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 0x104, 4) CRU_GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 0x104, 7) CRU_GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 0x104, 8) CRU_GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 0x104, 9) }; /* * PLLs */ #define PLL_PPLL 1 static struct rk_clk_pll_rate rk3399_pll_rates[] = { { .freq = 2208000000, .refdiv = 1, .fbdiv = 92, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2184000000, .refdiv = 1, .fbdiv = 91, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2160000000, .refdiv = 1, .fbdiv = 90, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2136000000, .refdiv = 1, .fbdiv = 89, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2112000000, .refdiv = 1, .fbdiv = 88, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2088000000, .refdiv = 1, .fbdiv = 87, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2064000000, .refdiv = 1, .fbdiv = 86, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2040000000, .refdiv = 1, .fbdiv = 85, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 2016000000, .refdiv = 1, .fbdiv = 84, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1992000000, .refdiv = 1, .fbdiv = 83, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1968000000, .refdiv = 1, .fbdiv = 82, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1944000000, .refdiv = 1, .fbdiv = 81, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1920000000, .refdiv = 1, .fbdiv = 80, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1896000000, .refdiv = 1, .fbdiv = 79, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1872000000, .refdiv = 1, .fbdiv = 78, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1848000000, .refdiv = 1, .fbdiv = 77, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1824000000, .refdiv = 1, .fbdiv = 76, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1800000000, .refdiv = 1, .fbdiv = 75, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1776000000, .refdiv = 1, .fbdiv = 74, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1752000000, .refdiv = 1, .fbdiv = 73, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1728000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1704000000, .refdiv = 1, .fbdiv = 71, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1680000000, .refdiv = 1, .fbdiv = 70, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1656000000, .refdiv = 1, .fbdiv = 69, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1632000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1608000000, .refdiv = 1, .fbdiv = 67, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1600000000, .refdiv = 3, .fbdiv = 200, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1584000000, .refdiv = 1, .fbdiv = 66, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1560000000, .refdiv = 1, .fbdiv = 65, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1536000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1512000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1488000000, .refdiv = 1, .fbdiv = 62, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1464000000, .refdiv = 1, .fbdiv = 61, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1440000000, .refdiv = 1, .fbdiv = 60, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1416000000, .refdiv = 1, .fbdiv = 59, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1392000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1368000000, .refdiv = 1, .fbdiv = 57, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1344000000, .refdiv = 1, .fbdiv = 56, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1320000000, .refdiv = 1, .fbdiv = 55, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1296000000, .refdiv = 1, .fbdiv = 54, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1272000000, .refdiv = 1, .fbdiv = 53, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1248000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1200000000, .refdiv = 1, .fbdiv = 50, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1188000000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1104000000, .refdiv = 1, .fbdiv = 46, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1100000000, .refdiv = 12, .fbdiv = 550, .postdiv1 = 1, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1008000000, .refdiv = 1, .fbdiv = 84, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 1000000000, .refdiv = 1, .fbdiv = 125, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 984000000, .refdiv = 1, .fbdiv = 82, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 960000000, .refdiv = 1, .fbdiv = 80, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 936000000, .refdiv = 1, .fbdiv = 78, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 912000000, .refdiv = 1, .fbdiv = 76, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 900000000, .refdiv = 4, .fbdiv = 300, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 888000000, .refdiv = 1, .fbdiv = 74, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 864000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 840000000, .refdiv = 1, .fbdiv = 70, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 816000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 800000000, .refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 700000000, .refdiv = 6, .fbdiv = 350, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 696000000, .refdiv = 1, .fbdiv = 58, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 676000000, .refdiv = 3, .fbdiv = 169, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 600000000, .refdiv = 1, .fbdiv = 75, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 594000000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 533250000, .refdiv = 8, .fbdiv = 711, .postdiv1 = 4, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 504000000, .refdiv = 1, .fbdiv = 63, .postdiv1 = 3, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 500000000, .refdiv = 6, .fbdiv = 250, .postdiv1 = 2, .postdiv2 = 1, .dsmpd = 1, }, { .freq = 408000000, .refdiv = 1, .fbdiv = 68, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 312000000, .refdiv = 1, .fbdiv = 52, .postdiv1 = 2, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 297000000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 216000000, .refdiv = 1, .fbdiv = 72, .postdiv1 = 4, .postdiv2 = 2, .dsmpd = 1, }, { .freq = 148500000, .refdiv = 1, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 106500000, .refdiv = 1, .fbdiv = 71, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 96000000, .refdiv = 1, .fbdiv = 64, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 74250000, .refdiv = 2, .fbdiv = 99, .postdiv1 = 4, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 65000000, .refdiv = 1, .fbdiv = 65, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 54000000, .refdiv = 1, .fbdiv = 54, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, { .freq = 27000000, .refdiv = 1, .fbdiv = 27, .postdiv1 = 6, .postdiv2 = 4, .dsmpd = 1, }, {}, }; static const char *pll_parents[] = {"xin24m"}; static struct rk_clk_pll_def ppll = { .clkdef = { .id = PLL_PPLL, .name = "ppll", .parent_names = pll_parents, .parent_cnt = nitems(pll_parents), }, .base_offset = 0x00, .rates = rk3399_pll_rates, }; static const char *pmu_parents[] = {"ppll"}; #define PCLK_PMU_SRC 19 static struct rk_clk_composite_def pclk_pmu_src = { .clkdef = { .id = PCLK_PMU_SRC, .name = "pclk_pmu_src", .parent_names = pmu_parents, .parent_cnt = nitems(pmu_parents), }, /* PMUCRU_CLKSEL_CON0 */ .muxdiv_offset = 0x80, .div_shift = 0, .div_width = 5, }; #define SCLK_I2C0_PMU 9 #define SCLK_I2C4_PMU 10 #define SCLK_I2C8_PMU 11 static struct rk_clk_composite_def i2c0 = { .clkdef = { .id = SCLK_I2C0_PMU, .name = "clk_i2c0_pmu", .parent_names = pmu_parents, .parent_cnt = nitems(pmu_parents), }, /* PMUCRU_CLKSEL_CON2 */ .muxdiv_offset = 0x88, .div_shift = 0, .div_width = 7, /* PMUCRU_CLKGATE_CON0 */ .gate_offset = 0x100, .gate_shift = 9, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c8 = { .clkdef = { .id = SCLK_I2C8_PMU, .name = "clk_i2c8_pmu", .parent_names = pmu_parents, .parent_cnt = nitems(pmu_parents), }, /* PMUCRU_CLKSEL_CON2 */ .muxdiv_offset = 0x88, .div_shift = 8, .div_width = 7, /* PMUCRU_CLKGATE_CON0 */ .gate_offset = 0x100, .gate_shift = 11, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk_composite_def i2c4 = { .clkdef = { .id = SCLK_I2C4_PMU, .name = "clk_i2c4_pmu", .parent_names = pmu_parents, .parent_cnt = nitems(pmu_parents), }, /* PMUCRU_CLKSEL_CON3 */ .muxdiv_offset = 0x8c, .div_shift = 0, .div_width = 7, /* PMUCRU_CLKGATE_CON0 */ .gate_offset = 0x100, .gate_shift = 10, .flags = RK_CLK_COMPOSITE_HAVE_GATE, }; static struct rk_clk rk3399_pmu_clks[] = { { .type = RK3399_CLK_PLL, .clk.pll = &ppll }, { .type = RK_CLK_COMPOSITE, .clk.composite = &pclk_pmu_src }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c0 }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c4 }, { .type = RK_CLK_COMPOSITE, .clk.composite = &i2c8 }, }; static int rk3399_pmucru_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_is_compatible(dev, "rockchip,rk3399-pmucru")) { device_set_desc(dev, "Rockchip RK3399 PMU Clock and Reset Unit"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } static int rk3399_pmucru_attach(device_t dev) { struct rk_cru_softc *sc; sc = device_get_softc(dev); sc->dev = dev; sc->gates = rk3399_pmu_gates; sc->ngates = nitems(rk3399_pmu_gates); sc->clks = rk3399_pmu_clks; sc->nclks = nitems(rk3399_pmu_clks); + sc->reset_offset = 0x110; + sc->reset_num = 30; + return (rk_cru_attach(dev)); } static device_method_t rk3399_pmucru_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk3399_pmucru_probe), DEVMETHOD(device_attach, rk3399_pmucru_attach), DEVMETHOD_END }; static devclass_t rk3399_pmucru_devclass; DEFINE_CLASS_1(rk3399_pmucru, rk3399_pmucru_driver, rk3399_pmucru_methods, sizeof(struct rk_cru_softc), rk_cru_driver); EARLY_DRIVER_MODULE(rk3399_pmucru, simplebus, rk3399_pmucru_driver, rk3399_pmucru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); Index: head/sys/arm64/rockchip/clk/rk_cru.c =================================================================== --- head/sys/arm64/rockchip/clk/rk_cru.c (revision 352849) +++ head/sys/arm64/rockchip/clk/rk_cru.c (revision 352850) @@ -1,281 +1,291 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot * 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. * * $FreeBSD$ */ /* * RockChip Clock and Reset Unit */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "clkdev_if.h" #include "hwreset_if.h" static struct resource_spec rk_cru_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { -1, 0 } }; #define CCU_READ4(sc, reg) bus_read_4((sc)->res, (reg)) #define CCU_WRITE4(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) void rk3328_cru_register_clocks(struct rk_cru_softc *sc); static int rk_cru_write_4(device_t dev, bus_addr_t addr, uint32_t val) { struct rk_cru_softc *sc; sc = device_get_softc(dev); CCU_WRITE4(sc, addr, val); return (0); } static int rk_cru_read_4(device_t dev, bus_addr_t addr, uint32_t *val) { struct rk_cru_softc *sc; sc = device_get_softc(dev); *val = CCU_READ4(sc, addr); return (0); } static int rk_cru_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) { struct rk_cru_softc *sc; uint32_t reg; sc = device_get_softc(dev); reg = CCU_READ4(sc, addr); reg &= ~clr; reg |= set; CCU_WRITE4(sc, addr, reg); return (0); } static int rk_cru_reset_assert(device_t dev, intptr_t id, bool reset) { struct rk_cru_softc *sc; + uint32_t reg; + int bit; uint32_t val; sc = device_get_softc(dev); - if (id >= sc->nresets || sc->resets[id].offset == 0) - return (0); + if (id > sc->reset_num) + return (ENXIO); + reg = sc->reset_offset + id / 16 * 4; + bit = id % 16; + mtx_lock(&sc->mtx); - val = CCU_READ4(sc, sc->resets[id].offset); + val = 0; if (reset) - val &= ~(1 << sc->resets[id].shift); - else - val |= 1 << sc->resets[id].shift; - CCU_WRITE4(sc, sc->resets[id].offset, val); + val = (1 << bit); + CCU_WRITE4(sc, reg, val | ((1 << bit) << 16)); mtx_unlock(&sc->mtx); return (0); } static int rk_cru_reset_is_asserted(device_t dev, intptr_t id, bool *reset) { struct rk_cru_softc *sc; + uint32_t reg; + int bit; uint32_t val; sc = device_get_softc(dev); - if (id >= sc->nresets || sc->resets[id].offset == 0) - return (0); + if (id > sc->reset_num) + return (ENXIO); + reg = sc->reset_offset + id / 16 * 4; + bit = id % 16; mtx_lock(&sc->mtx); - val = CCU_READ4(sc, sc->resets[id].offset); - *reset = (val & (1 << sc->resets[id].shift)) != 0 ? false : true; + val = CCU_READ4(sc, reg); mtx_unlock(&sc->mtx); + *reset = true; + if (val & (1 << bit)) + *reset = true; + return (0); } static void rk_cru_device_lock(device_t dev) { struct rk_cru_softc *sc; sc = device_get_softc(dev); mtx_lock(&sc->mtx); } static void rk_cru_device_unlock(device_t dev) { struct rk_cru_softc *sc; sc = device_get_softc(dev); mtx_unlock(&sc->mtx); } static int rk_cru_register_gates(struct rk_cru_softc *sc) { struct rk_clk_gate_def def; int i; for (i = 0; i < sc->ngates; i++) { if (sc->gates[i].name == NULL) continue; memset(&def, 0, sizeof(def)); def.clkdef.id = sc->gates[i].id; def.clkdef.name = sc->gates[i].name; def.clkdef.parent_names = &sc->gates[i].parent_name; def.clkdef.parent_cnt = 1; def.offset = sc->gates[i].offset; def.shift = sc->gates[i].shift; def.mask = 1; def.on_value = 0; def.off_value = 1; rk_clk_gate_register(sc->clkdom, &def); } return (0); } int rk_cru_attach(device_t dev) { struct rk_cru_softc *sc; phandle_t node; int i; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); if (bus_alloc_resources(dev, rk_cru_spec, &sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); return (ENXIO); } mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); sc->clkdom = clkdom_create(dev); if (sc->clkdom == NULL) panic("Cannot create clkdom\n"); for (i = 0; i < sc->nclks; i++) { switch (sc->clks[i].type) { case RK_CLK_UNDEFINED: break; case RK3328_CLK_PLL: rk3328_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll); break; case RK3399_CLK_PLL: rk3399_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll); break; case RK_CLK_COMPOSITE: rk_clk_composite_register(sc->clkdom, sc->clks[i].clk.composite); break; case RK_CLK_MUX: rk_clk_mux_register(sc->clkdom, sc->clks[i].clk.mux); break; case RK_CLK_ARMCLK: rk_clk_armclk_register(sc->clkdom, sc->clks[i].clk.armclk); break; default: device_printf(dev, "Unknown clock type\n"); return (ENXIO); break; } } if (sc->gates) rk_cru_register_gates(sc); if (clkdom_finit(sc->clkdom) != 0) panic("cannot finalize clkdom initialization\n"); if (bootverbose) clkdom_dump(sc->clkdom); clk_set_assigned(dev, node); /* If we have resets, register our self as a reset provider */ - if (sc->resets) - hwreset_register_ofw_provider(dev); + /* if (sc->resets) */ + /* hwreset_register_ofw_provider(dev); */ return (0); } static device_method_t rk_cru_methods[] = { /* clkdev interface */ DEVMETHOD(clkdev_write_4, rk_cru_write_4), DEVMETHOD(clkdev_read_4, rk_cru_read_4), DEVMETHOD(clkdev_modify_4, rk_cru_modify_4), DEVMETHOD(clkdev_device_lock, rk_cru_device_lock), DEVMETHOD(clkdev_device_unlock, rk_cru_device_unlock), /* Reset interface */ DEVMETHOD(hwreset_assert, rk_cru_reset_assert), DEVMETHOD(hwreset_is_asserted, rk_cru_reset_is_asserted), DEVMETHOD_END }; DEFINE_CLASS_0(rk_cru, rk_cru_driver, rk_cru_methods, sizeof(struct rk_cru_softc)); Index: head/sys/arm64/rockchip/clk/rk_cru.h =================================================================== --- head/sys/arm64/rockchip/clk/rk_cru.h (revision 352849) +++ head/sys/arm64/rockchip/clk/rk_cru.h (revision 352850) @@ -1,102 +1,97 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot * 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. * * $FreeBSD$ */ #ifndef __RK_CRU_H__ #define __RK_CRU_H__ #include #include #include #include #include -struct rk_cru_reset { - uint32_t offset; - uint32_t shift; -}; - struct rk_cru_gate { const char *name; const char *parent_name; uint32_t id; uint32_t offset; uint32_t shift; }; #define CRU_GATE(idx, clkname, pname, o, s) \ { \ .id = idx, \ .name = clkname, \ .parent_name = pname, \ .offset = o, \ .shift = s, \ }, enum rk_clk_type { RK_CLK_UNDEFINED = 0, RK3328_CLK_PLL, RK3399_CLK_PLL, RK_CLK_COMPOSITE, RK_CLK_MUX, RK_CLK_ARMCLK, }; struct rk_clk { enum rk_clk_type type; union { struct rk_clk_pll_def *pll; struct rk_clk_composite_def *composite; struct rk_clk_mux_def *mux; struct rk_clk_armclk_def *armclk; } clk; }; struct rk_cru_softc { device_t dev; struct resource *res; struct clkdom *clkdom; struct mtx mtx; int type; - struct rk_cru_reset *resets; - int nresets; + uint32_t reset_offset; + uint32_t reset_num; struct rk_cru_gate *gates; int ngates; struct rk_clk *clks; int nclks; struct rk_clk_armclk_def *armclk; struct rk_clk_armclk_rates *armclk_rates; int narmclk_rates; }; DECLARE_CLASS(rk_cru_driver); int rk_cru_attach(device_t dev); #endif /* __RK_CRU_H__ */