Index: sys/arm64/conf/GENERIC =================================================================== --- sys/arm64/conf/GENERIC +++ sys/arm64/conf/GENERIC @@ -106,6 +106,7 @@ options SOC_HISI_HI6220 options SOC_BRCM_BCM2837 options SOC_ROCKCHIP_RK3328 +options SOC_ROCKCHIP_RK3399 options SOC_XILINX_ZYNQ # Annapurna Alpine drivers Index: sys/arm64/rockchip/clk/rk3399_cru.c =================================================================== --- /dev/null +++ sys/arm64/rockchip/clk/rk3399_cru.c @@ -0,0 +1,1381 @@ +/*- + * 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_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 + +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_CON8 */ + CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1) + CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0) + + /* 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) +}; + + +/* + * 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, + .mode_reg = 0xc, + .mode_val = 1 << 8, + .flags = RK_CLK_PLL_HAVE_GATE, + .rates = rk3399_pll_rates, +}; + +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, + .mode_reg = 0x2c, + .mode_val = 1 << 8, + .flags = RK_CLK_PLL_HAVE_GATE, + .rates = rk3399_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 = 0x40, + .gate_offset = 0x300, + .gate_shift = 2, + .mode_reg = 0x4c, + .mode_val = 1 << 8, + .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, + .mode_reg = 0x6c, + .mode_val = 1 << 8, + .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, + .mode_reg = 0x8c, + .mode_val = 1 << 8, + .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, + .mode_reg = 0xac, + .mode_val = 1 << 8, + .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, + .mode_reg = 0, + .mode_val = 0, + .rates = rk3399_pll_rates, +}; + +/* + * misc + */ +#define PCLK_ALIVE 231 + +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, + + .flags = 0, +}; + +#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 = 2, + + .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), +}; + +static struct rk_clk rk3399_clks[] = { + { + .type = RK_CLK_PLL, + .clk.pll = &lpll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &bpll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &dpll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &cpll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &gpll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &npll + }, + { + .type = RK_CLK_PLL, + .clk.pll = &vpll + }, + + { + .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, + }, +}; + +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); + + 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: sys/arm64/rockchip/clk/rk3399_pmucru.c =================================================================== --- /dev/null +++ sys/arm64/rockchip/clk/rk3399_pmucru.c @@ -0,0 +1,875 @@ +/*- + * 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_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 8 + +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, + .gate_offset = 0x100, + .gate_shift = 0, + .mode_reg = 0xc, + .mode_val = 1 << 8, + .flags = RK_CLK_PLL_HAVE_GATE, + .rates = rk3399_pll_rates, +}; + +static const char *pmu_parents[] = {"ppll"}; + +#define PCLK_PMU_SRC 1000 + +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, + + .gate_offset = 0x100, + .gate_shift = 4, + + .flags = RK_CLK_COMPOSITE_HAVE_GATE, +}; + + +#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", + .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 i2c4 = { + .clkdef = { + .id = SCLK_I2C4_PMU, + .name = "clk_i2c4", + .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_composite_def i2c8 = { + .clkdef = { + .id = SCLK_I2C8_PMU, + .name = "clk_i2c8", + .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 rk3399_pmu_clks[] = { + { + .type = RK_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); + + 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: sys/arm64/rockchip/if_dwc_rk.c =================================================================== --- sys/arm64/rockchip/if_dwc_rk.c +++ sys/arm64/rockchip/if_dwc_rk.c @@ -84,13 +84,39 @@ /* SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON0, tx | rx | 0xFFFF0000); */ } +#define RK3399_GRF_SOC_CON6 0xc218 +#define RK3399_GRF_SOC_CON6_TX_MASK 0x7F +#define RK3399_GRF_SOC_CON6_TX_SHIFT 0 +#define RK3399_GRF_SOC_CON6_RX_MASK 0x7F +#define RK3399_GRF_SOC_CON6_RX_SHIFT 8 + +static void +rk3399_set_delays(struct syscon *grf, phandle_t node) +{ + uint32_t tx, rx; + + if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) + tx = 0x30; + if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) + rx = 0x10; + + tx = ((tx & RK3399_GRF_SOC_CON6_TX_MASK) << + RK3399_GRF_SOC_CON6_TX_SHIFT); + rx = ((rx & RK3399_GRF_SOC_CON6_TX_MASK) << + RK3399_GRF_SOC_CON6_RX_SHIFT); + + SYSCON_WRITE_4(grf, RK3399_GRF_SOC_CON6, tx | rx | 0x80808080); +} + + static int if_dwc_rk_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac")) + if (!(ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac") || + ofw_bus_is_compatible(dev, "rockchip,rk3399-gmac"))) return (ENXIO); device_set_desc(dev, "Rockchip Gigabit Ethernet Controller"); @@ -111,7 +137,10 @@ return (ENXIO); } - rk3328_set_delays(grf, node); + if (ofw_bus_is_compatible(dev, "rockchip,rk3399-gmac")) + rk3399_set_delays(grf, node); + else if (ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac")) + rk3328_set_delays(grf, node); /* Mode should be set according to dtb property */ Index: sys/arm64/rockchip/rk_grf.c =================================================================== --- sys/arm64/rockchip/rk_grf.c +++ sys/arm64/rockchip/rk_grf.c @@ -49,6 +49,10 @@ static struct ofw_compat_data compat_data[] = { #ifdef SOC_ROCKCHIP_RK3328 {"rockchip,rk3328-grf", 1}, +#endif +#ifdef SOC_ROCKCHIP_RK3399 + {"rockchip,rk3399-grf", 1}, + {"rockchip,rk3399-pmugrf", 1}, #endif {NULL, 0} }; Index: sys/arm64/rockchip/rk_i2c.c =================================================================== --- sys/arm64/rockchip/rk_i2c.c +++ sys/arm64/rockchip/rk_i2c.c @@ -145,6 +145,9 @@ static struct ofw_compat_data compat_data[] = { #ifdef SOC_ROCKCHIP_RK3328 {"rockchip,rk3328-i2c", 1}, +#endif +#ifdef SOC_ROCKCHIP_RK3399 + {"rockchip,rk3399-i2c", 1}, #endif {NULL, 0} }; Index: sys/arm64/rockchip/rk_pinctrl.c =================================================================== --- sys/arm64/rockchip/rk_pinctrl.c +++ sys/arm64/rockchip/rk_pinctrl.c @@ -78,6 +78,8 @@ uint32_t mask; }; +struct rk_pinctrl_softc; + struct rk_pinctrl_conf { struct rk_pinctrl_bank *iomux_conf; uint32_t iomux_nbanks; @@ -87,12 +89,14 @@ uint32_t npin_drive; uint32_t pd_offset; uint32_t drive_offset; + struct syscon *(*get_syscon)(struct rk_pinctrl_softc *, uint32_t); }; struct rk_pinctrl_softc { struct simplebus_softc simplebus_sc; device_t dev; struct syscon *grf; + struct syscon *pmu; struct rk_pinctrl_conf *conf; }; @@ -238,6 +242,11 @@ }, }; +static struct syscon *rk3328_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) +{ + return sc->grf; +} + struct rk_pinctrl_conf rk3328_conf = { .iomux_conf = rk3328_iomux_bank, .iomux_nbanks = nitems(rk3328_iomux_bank), @@ -247,11 +256,160 @@ .npin_drive = nitems(rk3328_pin_drive), .pd_offset = 0x100, .drive_offset = 0x200, + .get_syscon = rk3328_get_syscon, +}; + +static struct rk_pinctrl_bank rk3399_iomux_bank[] = { + { + .bank_num = 0, + .subbank_num = 0, + .offset = 0x00, + .nbits = 2, + }, + { + .bank_num = 0, + .subbank_num = 1, + .offset = 0x04, + .nbits = 2, + }, + { + .bank_num = 0, + .subbank_num = 2, + .offset = 0x08, + .nbits = 2, + }, + { + .bank_num = 0, + .subbank_num = 3, + .offset = 0x0c, + .nbits = 2, + }, + { + .bank_num = 1, + .subbank_num = 0, + .offset = 0x10, + .nbits = 2, + }, + { + .bank_num = 1, + .subbank_num = 1, + .offset = 0x14, + .nbits = 2, + }, + { + .bank_num = 1, + .subbank_num = 2, + .offset = 0x18, + .nbits = 2, + }, + { + .bank_num = 1, + .subbank_num = 3, + .offset = 0x1c, + .nbits = 2, + }, + { + .bank_num = 2, + .subbank_num = 0, + .offset = 0x20, + .nbits = 2, + }, + { + .bank_num = 2, + .subbank_num = 1, + .offset = 0x24, + .nbits = 2, + }, + { + .bank_num = 2, + .subbank_num = 2, + .offset = 0x28, + .nbits = 2, + }, + { + .bank_num = 2, + .subbank_num = 3, + .offset = 0x2c, + .nbits = 2, + }, + { + .bank_num = 3, + .subbank_num = 0, + .offset = 0x30, + .nbits = 2, + }, + { + .bank_num = 3, + .subbank_num = 1, + .offset = 0x34, + .nbits = 2, + }, + { + .bank_num = 3, + .subbank_num = 2, + .offset = 0x38, + .nbits = 2, + }, + { + .bank_num = 3, + .subbank_num = 3, + .offset = 0x3c, + .nbits = 2, + }, + { + .bank_num = 4, + .subbank_num = 0, + .offset = 0x40, + .nbits = 2, + }, + { + .bank_num = 4, + .subbank_num = 1, + .offset = 0x44, + .nbits = 2, + }, + { + .bank_num = 4, + .subbank_num = 2, + .offset = 0x48, + .nbits = 2, + }, + { + .bank_num = 4, + .subbank_num = 3, + .offset = 0x4c, + .nbits = 2, + }, +}; + +static struct rk_pinctrl_pin_fixup rk3399_pin_fixup[] = {}; + +static struct syscon *rk3399_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) +{ + if (bank < 2) + return sc->pmu; + return sc->grf; +} + +struct rk_pinctrl_conf rk3399_conf = { + .iomux_conf = rk3399_iomux_bank, + .iomux_nbanks = nitems(rk3399_iomux_bank), + .pin_fixup = rk3399_pin_fixup, + .npin_fixup = nitems(rk3399_pin_fixup), + // XXX: pin drive is not used + .pin_drive = rk3328_pin_drive, + .npin_drive = nitems(rk3328_pin_drive), + .pd_offset = 0x40, + .drive_offset = 0, + .get_syscon = rk3399_get_syscon, }; static struct ofw_compat_data compat_data[] = { #ifdef SOC_ROCKCHIP_RK3328 {"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf}, +#endif +#ifdef SOC_ROCKCHIP_RK3399 + {"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf}, #endif {NULL, 0} }; @@ -310,6 +468,7 @@ rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata) { phandle_t pin_conf; + struct syscon *syscon; uint32_t bank, subbank, pin, function, bias; uint32_t bit, mask, reg, drive; int i; @@ -331,6 +490,9 @@ return; } + /* Find syscon */ + syscon = sc->conf->get_syscon(sc, bank); + /* Parse pin function */ reg = sc->conf->iomux_conf[i].offset; switch (sc->conf->iomux_conf[i].nbits) { @@ -347,7 +509,7 @@ break; } rk_pinctrl_get_fixup(sc, bank, pin, ®, &mask, &bit); - SYSCON_WRITE_4(sc->grf, reg, function << bit | mask); + SYSCON_WRITE_4(syscon, reg, function << bit | mask); /* Pull-Up/Down */ bias = rk_pinctrl_parse_bias(pin_conf); @@ -357,7 +519,7 @@ reg += bank * 0x10 + ((pin / 8) * 0x4); bit = (pin % 8) * 2; mask = (0x3 << bit) << 16; - SYSCON_WRITE_4(sc->grf, reg, bias << bit | mask); + SYSCON_WRITE_4(syscon, reg, bias << bit | mask); } /* Drive Strength */ @@ -367,7 +529,7 @@ reg += bank * 0x10 + ((pin / 8) * 0x4); bit = (pin % 8) * 2; mask = (0x3 << bit) << 16; - SYSCON_WRITE_4(sc->grf, reg, bias << bit | mask); + SYSCON_WRITE_4(syscon, reg, bias << bit | mask); } } @@ -426,6 +588,16 @@ return (ENXIO); } + // RK3399 has banks in PMU. RK3328 does not have a PMU. + if (ofw_bus_node_is_compatible(node, "rockchip,rk3399-pinctrl")) { + if (OF_hasprop(node, "rockchip,pmu") && + syscon_get_by_ofw_property(dev, node, + "rockchip,pmu", &sc->pmu) != 0) { + device_printf(dev, "cannot get pmu driver handle\n"); + return (ENXIO); + } + } + sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; Index: sys/arm64/rockchip/rk_pmu.c =================================================================== --- sys/arm64/rockchip/rk_pmu.c +++ sys/arm64/rockchip/rk_pmu.c @@ -47,14 +47,14 @@ #include "opt_soc.h" static struct ofw_compat_data compat_data[] = { -#ifdef SOC_ROCKCHIP_RK3328 - {"rockchip,rk3328-grf", 1}, +#ifdef SOC_ROCKCHIP_RK3399 + {"rockchip,rk3399-pmu", 1}, #endif {NULL, 0} }; static int -rk_grf_probe(device_t dev) +rk_pmu_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) @@ -62,20 +62,20 @@ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); - device_set_desc(dev, "RockChip General Register Files"); + device_set_desc(dev, "Rockchip Power Management Unit"); return (BUS_PROBE_DEFAULT); } -static device_method_t rk_grf_methods[] = { - DEVMETHOD(device_probe, rk_grf_probe), +static device_method_t rk_pmu_methods[] = { + DEVMETHOD(device_probe, rk_pmu_probe), DEVMETHOD_END }; -DEFINE_CLASS_1(rk_grf, rk_grf_driver, rk_grf_methods, +DEFINE_CLASS_1(rk_pmu, rk_pmu_driver, rk_pmu_methods, sizeof(struct syscon_generic_softc), syscon_generic_driver); -static devclass_t rk_grf_devclass; -EARLY_DRIVER_MODULE(rk_grf, simplebus, rk_grf_driver, rk_grf_devclass, +static devclass_t rk_pmu_devclass; +EARLY_DRIVER_MODULE(rk_pmu, simplebus, rk_pmu_driver, rk_pmu_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); -MODULE_VERSION(rk_grf, 1); +MODULE_VERSION(rk_pmu, 1); Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -249,17 +249,20 @@ cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" -arm64/rockchip/rk_i2c.c optional rk_i2c fdt soc_rockchip_rk3328 -arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/rk_pinctrl.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/rk_gpio.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 +arm64/rockchip/rk_i2c.c optional rk_i2c fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/rk_pmu.c optional fdt soc_rockchip_rk3399 +arm64/rockchip/rk_pinctrl.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/rk_gpio.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 +arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 soc_rockchip_rk3399 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 -arm64/rockchip/if_dwc_rk.c optional dwc_rk 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 +arm64/rockchip/if_dwc_rk.c optional dwc_rk fdt soc_rockchip_rk3328 soc_rockchip_rk3399 dev/dwc/if_dwc.c optional dwc_rk dev/dwc/if_dwc_if.m optional dwc_rk Index: sys/conf/options.arm64 =================================================================== --- sys/conf/options.arm64 +++ sys/conf/options.arm64 @@ -20,4 +20,5 @@ SOC_CAVM_THUNDERX opt_soc.h SOC_HISI_HI6220 opt_soc.h SOC_ROCKCHIP_RK3328 opt_soc.h +SOC_ROCKCHIP_RK3399 opt_soc.h SOC_XILINX_ZYNQ opt_soc.h