mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 13:13:57 +08:00
2c6fae2501
The emac needs constant and very specific rate but the possible PLL-sources are very limited, so we expect the PLL source to be set manually on per board and don't want it to get changed in an automatic way later. So add the necessary clock-id and disable reparenting on set_rate calls. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Heiko Stuebner <heiko@sntech.de> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: linux-clk@vger.kernel.org Signed-off-by: Caesar Wang <wxt@rock-chips.com> Signed-off-by: David S. Miller <davem@davemloft.net>
494 lines
20 KiB
C
494 lines
20 KiB
C
/*
|
|
* Copyright (c) 2014 MundoReader S.L.
|
|
* Author: Heiko Stuebner <heiko@sntech.de>
|
|
*
|
|
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
|
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/syscore_ops.h>
|
|
#include <dt-bindings/clock/rk3036-cru.h>
|
|
#include "clk.h"
|
|
|
|
#define RK3036_GRF_SOC_STATUS0 0x14c
|
|
|
|
enum rk3036_plls {
|
|
apll, dpll, gpll,
|
|
};
|
|
|
|
static struct rockchip_pll_rate_table rk3036_pll_rates[] = {
|
|
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
|
|
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
|
|
RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
|
|
RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
|
|
RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
|
|
RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
|
|
RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
|
|
RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
|
|
RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
|
|
{ /* sentinel */ },
|
|
};
|
|
|
|
#define RK3036_DIV_CPU_MASK 0x1f
|
|
#define RK3036_DIV_CPU_SHIFT 8
|
|
|
|
#define RK3036_DIV_PERI_MASK 0xf
|
|
#define RK3036_DIV_PERI_SHIFT 0
|
|
#define RK3036_DIV_ACLK_MASK 0x7
|
|
#define RK3036_DIV_ACLK_SHIFT 4
|
|
#define RK3036_DIV_HCLK_MASK 0x3
|
|
#define RK3036_DIV_HCLK_SHIFT 8
|
|
#define RK3036_DIV_PCLK_MASK 0x7
|
|
#define RK3036_DIV_PCLK_SHIFT 12
|
|
|
|
#define RK3036_CLKSEL1(_core_periph_div) \
|
|
{ \
|
|
.reg = RK2928_CLKSEL_CON(1), \
|
|
.val = HIWORD_UPDATE(_core_periph_div, RK3036_DIV_PERI_MASK, \
|
|
RK3036_DIV_PERI_SHIFT) \
|
|
}
|
|
|
|
#define RK3036_CPUCLK_RATE(_prate, _core_periph_div) \
|
|
{ \
|
|
.prate = _prate, \
|
|
.divs = { \
|
|
RK3036_CLKSEL1(_core_periph_div), \
|
|
}, \
|
|
}
|
|
|
|
static struct rockchip_cpuclk_rate_table rk3036_cpuclk_rates[] __initdata = {
|
|
RK3036_CPUCLK_RATE(816000000, 4),
|
|
RK3036_CPUCLK_RATE(600000000, 4),
|
|
RK3036_CPUCLK_RATE(312000000, 4),
|
|
};
|
|
|
|
static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
|
|
.core_reg = RK2928_CLKSEL_CON(0),
|
|
.div_core_shift = 0,
|
|
.div_core_mask = 0x1f,
|
|
.mux_core_shift = 7,
|
|
};
|
|
|
|
PNAME(mux_pll_p) = { "xin24m", "xin24m" };
|
|
|
|
PNAME(mux_armclk_p) = { "apll", "gpll_armclk" };
|
|
PNAME(mux_busclk_p) = { "apll", "dpll_cpu", "gpll_cpu" };
|
|
PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
|
|
PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" };
|
|
PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" };
|
|
|
|
PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll" "usb480m" };
|
|
|
|
PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" };
|
|
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
|
PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
|
|
PNAME(mux_spdif_p) = { "spdif_src", "spdif_frac", "xin12m" };
|
|
PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
|
|
PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
|
|
PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
|
|
PNAME(mux_mac_p) = { "mac_pll_src", "rmii_clkin" };
|
|
PNAME(mux_dclk_p) = { "dclk_lcdc", "dclk_cru" };
|
|
|
|
static struct rockchip_pll_clock rk3036_pll_clks[] __initdata = {
|
|
[apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
|
|
RK2928_MODE_CON, 0, 5, 0, rk3036_pll_rates),
|
|
[dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
|
|
RK2928_MODE_CON, 4, 4, 0, NULL),
|
|
[gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
|
|
RK2928_MODE_CON, 12, 6, ROCKCHIP_PLL_SYNC_RATE, rk3036_pll_rates),
|
|
};
|
|
|
|
#define MFLAGS CLK_MUX_HIWORD_MASK
|
|
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
|
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
|
|
|
static struct rockchip_clk_branch rk3036_uart0_fracmux __initdata =
|
|
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(13), 8, 2, MFLAGS);
|
|
|
|
static struct rockchip_clk_branch rk3036_uart1_fracmux __initdata =
|
|
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(14), 8, 2, MFLAGS);
|
|
|
|
static struct rockchip_clk_branch rk3036_uart2_fracmux __initdata =
|
|
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
|
|
|
|
static struct rockchip_clk_branch rk3036_i2s_fracmux __initdata =
|
|
MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(3), 8, 2, MFLAGS);
|
|
|
|
static struct rockchip_clk_branch rk3036_spdif_fracmux __initdata =
|
|
MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
|
|
RK2928_CLKSEL_CON(5), 8, 2, MFLAGS);
|
|
|
|
static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
|
|
/*
|
|
* Clock-Architecture Diagram 1
|
|
*/
|
|
|
|
GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKGATE_CON(0), 6, GFLAGS),
|
|
|
|
/*
|
|
* Clock-Architecture Diagram 2
|
|
*/
|
|
|
|
GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKGATE_CON(0), 2, GFLAGS),
|
|
GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKGATE_CON(0), 8, GFLAGS),
|
|
COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
|
|
|
COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
|
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
|
COMPOSITE_NOMUX(0, "aclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
|
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
|
|
|
GATE(0, "dpll_cpu", "dpll", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
|
|
GATE(0, "gpll_cpu", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS),
|
|
COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_busclk_p, 0,
|
|
RK2928_CLKSEL_CON(0), 14, 2, MFLAGS, 8, 5, DFLAGS),
|
|
GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKGATE_CON(0), 3, GFLAGS),
|
|
COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(1), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
|
RK2928_CLKGATE_CON(0), 5, GFLAGS),
|
|
COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
|
RK2928_CLKGATE_CON(0), 4, GFLAGS),
|
|
|
|
COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(2), 0, GFLAGS),
|
|
|
|
GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
|
|
RK2928_CLKGATE_CON(2), 1, GFLAGS),
|
|
DIV(0, "pclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
|
GATE(PCLK_PERI, "pclk_peri", "pclk_peri_src", 0,
|
|
RK2928_CLKGATE_CON(2), 3, GFLAGS),
|
|
DIV(0, "hclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
|
GATE(HCLK_PERI, "hclk_peri", "hclk_peri_src", 0,
|
|
RK2928_CLKGATE_CON(2), 2, GFLAGS),
|
|
|
|
COMPOSITE_NODIV(SCLK_TIMER0, "sclk_timer0", mux_timer_p, CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(2), 4, 1, MFLAGS,
|
|
RK2928_CLKGATE_CON(1), 0, GFLAGS),
|
|
COMPOSITE_NODIV(SCLK_TIMER1, "sclk_timer1", mux_timer_p, CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(2), 5, 1, MFLAGS,
|
|
RK2928_CLKGATE_CON(1), 1, GFLAGS),
|
|
COMPOSITE_NODIV(SCLK_TIMER2, "sclk_timer2", mux_timer_p, CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(2), 6, 1, MFLAGS,
|
|
RK2928_CLKGATE_CON(2), 4, GFLAGS),
|
|
COMPOSITE_NODIV(SCLK_TIMER3, "sclk_timer3", mux_timer_p, CLK_IGNORE_UNUSED,
|
|
RK2928_CLKSEL_CON(2), 7, 1, MFLAGS,
|
|
RK2928_CLKGATE_CON(2), 5, GFLAGS),
|
|
|
|
MUX(0, "uart_pll_clk", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
|
|
RK2928_CLKSEL_CON(13), 10, 2, MFLAGS),
|
|
COMPOSITE_NOMUX(0, "uart0_src", "uart_pll_clk", 0,
|
|
RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(1), 8, GFLAGS),
|
|
COMPOSITE_NOMUX(0, "uart1_src", "uart_pll_clk", 0,
|
|
RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(1), 10, GFLAGS),
|
|
COMPOSITE_NOMUX(0, "uart2_src", "uart_pll_clk", 0,
|
|
RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(1), 12, GFLAGS),
|
|
COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(17), 0,
|
|
RK2928_CLKGATE_CON(1), 9, GFLAGS,
|
|
&rk3036_uart0_fracmux),
|
|
COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(18), 0,
|
|
RK2928_CLKGATE_CON(1), 11, GFLAGS,
|
|
&rk3036_uart1_fracmux),
|
|
COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(19), 0,
|
|
RK2928_CLKGATE_CON(1), 13, GFLAGS,
|
|
&rk3036_uart2_fracmux),
|
|
|
|
COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(3), 11, GFLAGS),
|
|
|
|
COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(10), 6, GFLAGS),
|
|
|
|
COMPOSITE(0, "aclk_disp1_pre", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(1), 4, GFLAGS),
|
|
COMPOSITE(0, "hclk_disp_pre", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(0), 11, GFLAGS),
|
|
COMPOSITE(SCLK_LCDC, "dclk_lcdc", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
|
|
RK2928_CLKGATE_CON(3), 2, GFLAGS),
|
|
|
|
COMPOSITE_NODIV(0, "sclk_sdmmc_src", mux_mmc_src_p, 0,
|
|
RK2928_CLKSEL_CON(12), 8, 2, MFLAGS,
|
|
RK2928_CLKGATE_CON(2), 11, GFLAGS),
|
|
DIV(SCLK_SDMMC, "sclk_sdmmc", "sclk_sdmmc_src", 0,
|
|
RK2928_CLKSEL_CON(11), 0, 7, DFLAGS),
|
|
|
|
COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
|
|
RK2928_CLKSEL_CON(12), 10, 2, MFLAGS,
|
|
RK2928_CLKGATE_CON(2), 13, GFLAGS),
|
|
DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
|
|
RK2928_CLKSEL_CON(11), 8, 7, DFLAGS),
|
|
|
|
COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
|
|
RK2928_CLKSEL_CON(12), 12, 2, MFLAGS, 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(2), 14, GFLAGS),
|
|
|
|
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3036_SDMMC_CON0, 1),
|
|
MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3036_SDMMC_CON1, 0),
|
|
|
|
MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3036_SDIO_CON0, 1),
|
|
MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3036_SDIO_CON1, 0),
|
|
|
|
MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3036_EMMC_CON0, 1),
|
|
MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3036_EMMC_CON1, 0),
|
|
|
|
COMPOSITE(0, "i2s_src", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(0), 9, GFLAGS),
|
|
COMPOSITE_FRACMUX(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(7), 0,
|
|
RK2928_CLKGATE_CON(0), 10, GFLAGS,
|
|
&rk3036_i2s_fracmux),
|
|
COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_clkout", mux_i2s_clkout_p, 0,
|
|
RK2928_CLKSEL_CON(3), 12, 1, MFLAGS,
|
|
RK2928_CLKGATE_CON(0), 13, GFLAGS),
|
|
GATE(SCLK_I2S, "sclk_i2s", "i2s_pre", CLK_SET_RATE_PARENT,
|
|
RK2928_CLKGATE_CON(0), 14, GFLAGS),
|
|
|
|
COMPOSITE(0, "spdif_src", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(5), 10, 2, MFLAGS, 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(2), 10, GFLAGS),
|
|
COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_src", 0,
|
|
RK2928_CLKSEL_CON(9), 0,
|
|
RK2928_CLKGATE_CON(2), 12, GFLAGS,
|
|
&rk3036_spdif_fracmux),
|
|
|
|
GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin12m", CLK_IGNORE_UNUSED,
|
|
RK2928_CLKGATE_CON(1), 5, GFLAGS),
|
|
|
|
COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(34), 8, 2, MFLAGS, 0, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
|
|
|
COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS,
|
|
RK2928_CLKGATE_CON(2), 9, GFLAGS),
|
|
|
|
COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0,
|
|
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(10), 4, GFLAGS),
|
|
|
|
COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
|
|
RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(10), 5, GFLAGS),
|
|
|
|
COMPOSITE_NOGATE(SCLK_MACPLL, "mac_pll_src", mux_pll_src_3plls_p, CLK_SET_RATE_NO_REPARENT,
|
|
RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 9, 5, DFLAGS),
|
|
MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
|
|
RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
|
|
|
|
COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0,
|
|
RK2928_CLKSEL_CON(21), 4, 5, DFLAGS,
|
|
RK2928_CLKGATE_CON(2), 6, GFLAGS),
|
|
|
|
MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0,
|
|
RK2928_CLKSEL_CON(31), 0, 1, MFLAGS),
|
|
|
|
/*
|
|
* Clock-Architecture Diagram 3
|
|
*/
|
|
|
|
/* aclk_cpu gates */
|
|
GATE(0, "sclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
|
|
GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
|
|
|
|
/* hclk_cpu gates */
|
|
GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
|
|
|
|
/* pclk_cpu gates */
|
|
GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
|
|
GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
|
|
GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
|
|
GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
|
|
|
|
/* aclk_vio gates */
|
|
GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS),
|
|
GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
|
|
|
|
GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS),
|
|
GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS),
|
|
|
|
/* hclk_video gates */
|
|
GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS),
|
|
|
|
/* xin24m gates */
|
|
GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS),
|
|
GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK2928_CLKGATE_CON(10), 1, GFLAGS),
|
|
|
|
/* aclk_peri gates */
|
|
GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
|
|
GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
|
|
GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
|
|
GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
|
|
|
|
/* hclk_peri gates */
|
|
GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
|
|
GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS),
|
|
GATE(0, "hclk_peri_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS),
|
|
GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
|
|
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
|
|
GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
|
|
GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
|
|
GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
|
|
GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
|
|
GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
|
|
GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
|
|
GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
|
|
|
|
/* pclk_peri gates */
|
|
GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
|
|
GATE(0, "pclk_efuse", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 2, GFLAGS),
|
|
GATE(PCLK_TIMER, "pclk_timer", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS),
|
|
GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS),
|
|
GATE(PCLK_SPI, "pclk_spi", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
|
|
GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
|
|
GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
|
|
GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
|
|
GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
|
|
GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
|
|
GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
|
|
GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
|
|
GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
|
GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
|
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
|
|
};
|
|
|
|
static const char *const rk3036_critical_clocks[] __initconst = {
|
|
"aclk_cpu",
|
|
"aclk_peri",
|
|
"hclk_peri",
|
|
"pclk_peri",
|
|
};
|
|
|
|
static void __init rk3036_clk_init(struct device_node *np)
|
|
{
|
|
void __iomem *reg_base;
|
|
struct clk *clk;
|
|
|
|
reg_base = of_iomap(np, 0);
|
|
if (!reg_base) {
|
|
pr_err("%s: could not map cru region\n", __func__);
|
|
return;
|
|
}
|
|
|
|
rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
|
|
|
|
/* xin12m is created by an cru-internal divider */
|
|
clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
|
|
if (IS_ERR(clk))
|
|
pr_warn("%s: could not register clock xin12m: %ld\n",
|
|
__func__, PTR_ERR(clk));
|
|
|
|
clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
|
|
if (IS_ERR(clk))
|
|
pr_warn("%s: could not register clock usb480m: %ld\n",
|
|
__func__, PTR_ERR(clk));
|
|
|
|
clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2);
|
|
if (IS_ERR(clk))
|
|
pr_warn("%s: could not register clock ddrphy: %ld\n",
|
|
__func__, PTR_ERR(clk));
|
|
|
|
clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre",
|
|
"aclk_vcodec", 0, 1, 4);
|
|
if (IS_ERR(clk))
|
|
pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
|
|
__func__, PTR_ERR(clk));
|
|
|
|
clk = clk_register_fixed_factor(NULL, "sclk_macref_out",
|
|
"hclk_peri_src", 0, 1, 2);
|
|
if (IS_ERR(clk))
|
|
pr_warn("%s: could not register clock sclk_macref_out: %ld\n",
|
|
__func__, PTR_ERR(clk));
|
|
|
|
rockchip_clk_register_plls(rk3036_pll_clks,
|
|
ARRAY_SIZE(rk3036_pll_clks),
|
|
RK3036_GRF_SOC_STATUS0);
|
|
rockchip_clk_register_branches(rk3036_clk_branches,
|
|
ARRAY_SIZE(rk3036_clk_branches));
|
|
rockchip_clk_protect_critical(rk3036_critical_clocks,
|
|
ARRAY_SIZE(rk3036_critical_clocks));
|
|
|
|
rockchip_clk_register_armclk(ARMCLK, "armclk",
|
|
mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
|
|
&rk3036_cpuclk_data, rk3036_cpuclk_rates,
|
|
ARRAY_SIZE(rk3036_cpuclk_rates));
|
|
|
|
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
|
|
|
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
|
|
}
|
|
CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
|