Index: sys/arm64/conf/GENERIC =================================================================== --- sys/arm64/conf/GENERIC +++ sys/arm64/conf/GENERIC @@ -129,6 +129,7 @@ options SOC_MARVELL_8K options SOC_NVIDIA_TEGRA210 options SOC_NXP_LS +options SOC_ROCKCHIP_PX30 options SOC_ROCKCHIP_RK3328 options SOC_ROCKCHIP_RK3399 options SOC_XILINX_ZYNQ Index: sys/arm64/rockchip/clk/px30_cru.c =================================================================== --- /dev/null +++ sys/arm64/rockchip/clk/px30_cru.c @@ -0,0 +1,972 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Roger Pau Monné + * Copyright (c) 2018 Emmanuel Vadot + * + * 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 HCLK_SDMMC 247 +#define HCLK_USB 248 +#define HCLK_HOST 259 +#define PCLK_I2C0 334 +#define PCLK_I2C1 335 +#define PCLK_I2C2 336 +#define PCLK_I2C3 337 + +static struct rk_cru_gate gates[] = { + /* CRU_CLKGATE_CON0 */ + CRU_GATE(0, "apll_core", "apll", 0x200, 0) + CRU_GATE(0, "gpll_core", "gpll", 0x200, 0) + + /* CRU_CLKGATE_CON6 */ + CRU_GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0x218, 12) + + /* CRU_CLKGATE_CON7 */ + CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sdmmc_pre", 0x21c, 1) + CRU_GATE(HCLK_USB, "hclk_usb", "hclk_peri_pre", 0x21c, 2) + CRU_GATE(HCLK_HOST, "hclk_host", "hclk_usb", 0x21c, 6) + + /* CRU_CLKGATE_CON14 */ + CRU_GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_pre", 0x238, 10) + CRU_GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0x238, 11) + CRU_GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0x238, 12) + CRU_GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0x238, 13) +}; + +/* + * 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 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 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 = 0, + .mode_reg = 0xa0, + .mode_shift = 0, + .rates = pll_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, + .mode_reg = 0xa0, + .mode_shift = 4, +}; + +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 = 0xa0, + .mode_shift = 2, + .rates = 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 = 0x60, + .mode_reg = 0xa0, + .mode_shift = 6, + .rates = pll_rates, +}; + +#define ACLK_BUS_PRE 171 + +static const char *aclk_bus_pre_parents[] = {"gpll", "cpll"}; +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), + }, + /* CRU_CLKSEL_CON23 */ + .muxdiv_offset = 0x15c, + .mux_shift = 15, + .mux_width = 1, + + .div_shift = 8, + .div_width = 5, + + /* CRU_CLKGATE_CON8 */ + .gate_offset = 0x220, + .gate_shift = 7, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +#define PX30_FREQ(f) { .freq = f, .div = 1 } +static struct rk_clk_armclk_rates armclk_rates[] = { + PX30_FREQ(1608000000), + PX30_FREQ(1584000000), + PX30_FREQ(1560000000), + PX30_FREQ(1536000000), + PX30_FREQ(1512000000), + PX30_FREQ(1488000000), + PX30_FREQ(1464000000), + PX30_FREQ(1440000000), + PX30_FREQ(1416000000), + PX30_FREQ(1392000000), + PX30_FREQ(1368000000), + PX30_FREQ(1344000000), + PX30_FREQ(1320000000), + PX30_FREQ(1296000000), + PX30_FREQ(1272000000), + PX30_FREQ(1248000000), + PX30_FREQ(1224000000), + PX30_FREQ(1200000000), + PX30_FREQ(1104000000), + PX30_FREQ(1008000000), + PX30_FREQ(912000000), + PX30_FREQ(816000000), + PX30_FREQ(696000000), + PX30_FREQ(600000000), + PX30_FREQ(408000000), + PX30_FREQ(312000000), + PX30_FREQ(216000000), + PX30_FREQ(96000000), +}; + +#define ARMCLK 7 +static const char *armclk_parents[] = {"apll", "gpll"}; +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 = 7, + .mux_width = 1, + + .div_shift = 0, + .div_width = 4, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX, + .main_parent = 0, /* apll */ + .alt_parent = 1, /* gpll */ + + .rates = armclk_rates, + .nrates = nitems(armclk_rates), +}; + +/* CRU_CLKSEL_CON24 */ + +#define PCLK_BUS_PRE 320 +#define HCLK_BUS_PRE 240 + +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 = 0x160, + + .div_shift = 0, + .div_width = 5, + + .gate_offset = 0x220, + .gate_shift = 8, + + .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 = 0x160, + + .div_shift = 8, + .div_width = 2, + + .gate_offset = 0x220, + .gate_shift = 9, + + .flags = RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON54 */ + +#define SCLK_TSADC 44 + +static const char *clk_tsadc_parents[] = {"xin24m"}; +static struct rk_clk_composite_def clk_tsadc = { + .clkdef = { + .id = SCLK_TSADC, + .name = "clk_tsadc", + .parent_names = clk_tsadc_parents, + .parent_cnt = nitems(clk_tsadc_parents), + }, + .muxdiv_offset = 0x1d8, + + .div_shift = 0, + .div_width = 11, + + .gate_offset = 0x230, + .gate_shift = 9, + + .flags = RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON14 */ + +#define ACLK_PERI_PRE 176 +#define HCLK_PERI_PRE 245 + +static const char *aclk_peri_pre_parents[] = {"gpll", "cpll"}; +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 = 0x138, + + .div_shift = 0, + .div_width = 5, + + .gate_offset = 0x214, + .gate_shift = 8, + + .flags = RK_CLK_COMPOSITE_HAVE_GATE, +}; + +static const char *hclk_peri_pre_parents[] = {"aclk_peri_pre"}; +static struct rk_clk_composite_def hclk_peri_pre = { + .clkdef = { + .id = HCLK_PERI_PRE, + .name = "hclk_peri_pre", + .parent_names = hclk_peri_pre_parents, + .parent_cnt = nitems(hclk_peri_pre_parents), + }, + /* CRU_CLKSEL_CON14 */ + .muxdiv_offset = 0x160, + + .div_shift = 8, + .div_width = 5, +}; + +/* CRU_CLKSEL_CON16 */ + +#define SCLK_SDMMC 59 + +static const char *mmc_parents[] = {"gpll", "cpll", "npll", "xin24m"}; +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 = 0x140, + + .mux_shift = 14, + .mux_width = 2, + + .div_shift = 0, + .div_width = 8, + + /* CRU_CLKGATE_CON6 */ + .gate_offset = 0x218, + .gate_shift = 15, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON18 */ +#define SCLK_SDIO 56 + +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 = 0x148, + + .mux_shift = 14, + .mux_width = 2, + + .div_shift = 0, + .div_width = 8, + + /* CRU_CLKGATE_CON6 */ + .gate_offset = 0x218, + .gate_shift = 9, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON20 */ +#define SCLK_EMMC 57 + +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 = 0x150, + + .mux_shift = 14, + .mux_width = 2, + + .div_shift = 0, + .div_width = 8, + + /* CRU_CLKGATE_CON6 */ + .gate_offset = 0x218, + .gate_shift = 6, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON49 */ +#define SCLK_I2C0 29 +#define SCLK_I2C1 30 + +static const char *i2c_parents[] = {"gpll", "xin24m"}; + +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 = 0x1c4, + + .mux_shift = 7, + .mux_width = 1, + + .div_shift = 0, + .div_width = 7, + + /* CRU_CLKGATE_CON12 */ + .gate_offset = 0x230, + .gate_shift = 0, + + .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 = 0x1c4, + + .mux_shift = 15, + .mux_width = 1, + + .div_shift = 8, + .div_width = 7, + + /* CRU_CLKGATE_CON12 */ + .gate_offset = 0x230, + .gate_shift = 1, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +/* CRU_CLKSEL_CON50 */ +#define SCLK_I2C2 31 +#define SCLK_I2C3 32 + +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 = 7, + + /* CRU_CLKGATE_CON12 */ + .gate_offset = 0x230, + .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), + }, + .muxdiv_offset = 0x18c, + + .mux_shift = 15, + .mux_width = 1, + + .div_shift = 8, + .div_width = 7, + + /* CRU_CLKGATE_CON12 */ + .gate_offset = 0x230, + .gate_shift = 3, + + .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE, +}; + +static struct rk_clk 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 = &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 = &clk_tsadc, + }, + { + .type = RK_CLK_COMPOSITE, + .clk.composite = &aclk_peri_pre, + }, + { + .type = RK_CLK_COMPOSITE, + .clk.composite = &hclk_peri_pre, + }, + { + .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 + }, +}; + +extern bool pmucru_attached; +static int +probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + //printf("probe cru\n"); + if (ofw_bus_is_compatible(dev, "rockchip,px30-cru") && + /* XXX: CRU depends on the GPLL clock declared in PMUCRU. */ + pmucru_attached) { + device_set_desc(dev, "Rockchip PX30 Clock and Reset Unit"); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static int +attach(device_t dev) +{ + struct rk_cru_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + + sc->gates = gates; + sc->ngates = nitems(gates); + + sc->clks = clks; + sc->nclks = nitems(clks); + + sc->reset_offset = 0x300; + sc->reset_num = 184; + + return (rk_cru_attach(dev)); +} + +static device_method_t methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, probe), + DEVMETHOD(device_attach, attach), + + DEVMETHOD_END +}; + +static devclass_t devclass; + +DEFINE_CLASS_1(px30_cru, px30_cru_driver, methods, + sizeof(struct rk_cru_softc), rk_cru_driver); + +EARLY_DRIVER_MODULE(px30_cru, simplebus, px30_cru_driver, + devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); Index: sys/arm64/rockchip/clk/px30_pmucru.c =================================================================== --- /dev/null +++ sys/arm64/rockchip/clk/px30_pmucru.c @@ -0,0 +1,498 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Roger Pau Monné + * 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 + +/* + * PLLs + */ + +#define PLL_GPLL 4 + +static struct rk_clk_pll_rate 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 const char *pll_parents[] = {"xin24m"}; +static struct rk_clk_pll_def gpll = { + .clkdef = { + .id = PLL_GPLL, + .name = "gpll", + .parent_names = pll_parents, + .parent_cnt = nitems(pll_parents), + }, + .base_offset = 0, + .mode_reg = 0x20, + .mode_shift = 0, + .rates = pll_rates, +}; + + +#define SCLK_REF24M 9 + +static const char *ref24m_parents[] = { "gpll" }; + +static struct rk_clk_composite_def ref24m = { + .clkdef = { + .id = SCLK_REF24M, + .name = "clk_ref24m", + .parent_names = ref24m_parents, + .parent_cnt = nitems(ref24m_parents), + }, + .muxdiv_offset = 0x48, + + .div_shift = 0, + .div_width = 6, + + /* CRU_PMU_CLKGATE_CON1 */ + .gate_offset = 0x84, + .gate_shift = 8, + + .flags = RK_CLK_COMPOSITE_HAVE_GATE, +}; + +static struct rk_clk clks[] = { + { + .type = RK3328_CLK_PLL, + .clk.pll = &gpll + }, + { + .type = RK_CLK_COMPOSITE, + .clk.composite = &ref24m + }, +}; + + +static int +probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_is_compatible(dev, "rockchip,px30-pmucru")) { + device_set_desc(dev, "Rockchip PX30 PMU Clock and Reset Unit"); + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + + +bool pmucru_attached; + +static int +attach(device_t dev) +{ + struct rk_cru_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + + sc->clks = clks; + sc->nclks = nitems(clks); + + /* XXX: hack to notify CRU. */ + pmucru_attached = true; + return (rk_cru_attach(dev)); +} + +static device_method_t methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, probe), + DEVMETHOD(device_attach, attach), + + DEVMETHOD_END +}; + +static devclass_t devclass; + +DEFINE_CLASS_1(px30_pmucru, px30_pmucru_driver, methods, + sizeof(struct rk_cru_softc), rk_cru_driver); + +EARLY_DRIVER_MODULE(px30_pmucru, simplebus, px30_pmucru_driver, + devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -510,16 +510,16 @@ # RockChip Drivers arm64/rockchip/rk3399_emmcphy.c optional fdt rk_emmcphy soc_rockchip_rk3399 arm64/rockchip/rk_dwc3.c optional fdt rk_dwc3 soc_rockchip_rk3399 -arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399 -arm64/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 -arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399 -arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399 +arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_px30 | fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399 +arm64/rockchip/rk805.c optional fdt rk_i2c soc_rockchip_px30 | fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 +arm64/rockchip/rk_grf.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_px30 | fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399 +arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_px30 | fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399 arm64/rockchip/rk_iodomain.c optional fdt rk_iodomain arm64/rockchip/rk_spi.c optional fdt rk_spi -arm64/rockchip/rk_usb2phy.c optional fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399 +arm64/rockchip/rk_usb2phy.c optional fdt rk_usb2phy soc_rockchip_px30 | fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399 arm64/rockchip/rk_typec_phy.c optional fdt rk_typec_phy soc_rockchip_rk3399 -arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 +arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_px30 | fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 arm64/rockchip/rk_tsadc_if.m optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_tsadc.c optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_pwm.c optional fdt rk_pwm @@ -527,13 +527,15 @@ arm64/rockchip/rk_pcie_phy.c optional fdt pci soc_rockchip_rk3399 # RockChip Clock support -arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_fract.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 -arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_fract.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_px30 | fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 +arm64/rockchip/clk/px30_cru.c optional fdt soc_rockchip_px30 +arm64/rockchip/clk/px30_pmucru.c optional fdt soc_rockchip_px30 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk3399_cru.c optional fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3399_pmucru.c optional fdt soc_rockchip_rk3399 Index: sys/conf/options.arm64 =================================================================== --- sys/conf/options.arm64 +++ sys/conf/options.arm64 @@ -28,6 +28,7 @@ SOC_MARVELL_8K opt_soc.h SOC_NVIDIA_TEGRA210 opt_soc.h SOC_NXP_LS opt_soc.h +SOC_ROCKCHIP_PX30 opt_soc.h SOC_ROCKCHIP_RK3328 opt_soc.h SOC_ROCKCHIP_RK3399 opt_soc.h SOC_XILINX_ZYNQ opt_soc.h Index: sys/modules/dtb/rockchip/Makefile =================================================================== --- sys/modules/dtb/rockchip/Makefile +++ sys/modules/dtb/rockchip/Makefile @@ -14,6 +14,8 @@ rockchip/rk3328-rock64.dts \ rockchip/rk3399-firefly.dts \ rockchip/rk3399-rockpro64.dts +# https://github.com/davidchisnall/dtc/issues/64 +# rockchip/rk3326-odroid-go2.dts DTSO= rk3328-dwc3.dtso .endif