Re: [PATCH 19/19] clk: tegra210: add support for Tegra210 clocks
From: Peter De Schrijver
Date: Mon Apr 27 2015 - 10:47:56 EST
On Fri, Apr 24, 2015 at 12:47:59PM -0400, Rhyland Klein wrote:
> Implement clock support for Tegra210.
>
> Signed-off-by: Rhyland Klein <rklein@xxxxxxxxxx>
> ---
> .../bindings/clock/nvidia,tegra210-car.txt | 56 +
> drivers/clk/tegra/Makefile | 1 +
> drivers/clk/tegra/clk-id.h | 4 +
> drivers/clk/tegra/clk-tegra210.c | 2704 ++++++++++++++++++++
> include/dt-bindings/clock/tegra210-car.h | 401 +++
> 5 files changed, 3166 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt
> create mode 100644 drivers/clk/tegra/clk-tegra210.c
> create mode 100644 include/dt-bindings/clock/tegra210-car.h
>
> diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt
> new file mode 100644
> index 000000000000..26f237f641b7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt
> @@ -0,0 +1,56 @@
> +NVIDIA Tegra210 Clock And Reset Controller
> +
> +This binding uses the common clock binding:
> +Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
> +for muxing and gating Tegra's clocks, and setting their rates.
> +
> +Required properties :
> +- compatible : Should be "nvidia,tegra210-car"
> +- reg : Should contain CAR registers location and length
> +- clocks : Should contain phandle and clock specifiers for two clocks:
> + the 32 KHz "32k_in".
> +- #clock-cells : Should be 1.
> + In clock consumers, this cell represents the clock ID exposed by the
> + CAR. The assignments may be found in header file
> + <dt-bindings/clock/tegra210-car.h>.
> +- #reset-cells : Should be 1.
> + In clock consumers, this cell represents the bit number in the CAR's
> + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
> +
> +Example SoC include file:
> +
> +/ {
> + tegra_car: clock {
> + compatible = "nvidia,tegra210-car";
> + reg = <0x60006000 0x1000>;
> + #clock-cells = <1>;
> + #reset-cells = <1>;
> + };
> +
> + usb@c5004000 {
> + clocks = <&tegra_car TEGRA210_CLK_USB2>;
> + };
> +};
> +
> +Example board file:
> +
> +/ {
> + clocks {
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + clk_32k: clock@1 {
> + compatible = "fixed-clock";
> + reg = <1>;
> + #clock-cells = <0>;
> + clock-frequency = <32768>;
> + };
> + };
> +
> + &tegra_car {
> + clocks = <&clk_32k>;
> + };
> +};
> diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
> index 0ba495b852e6..2dd683b6b63c 100644
> --- a/drivers/clk/tegra/Makefile
> +++ b/drivers/clk/tegra/Makefile
> @@ -17,4 +17,5 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
> obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
> obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
> obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
> +obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
> obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o
> diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
> index ac6eaba5cc6e..6f3b1715bd24 100644
> --- a/drivers/clk/tegra/clk-id.h
> +++ b/drivers/clk/tegra/clk-id.h
> @@ -151,6 +151,10 @@ enum clk_id {
> tegra_clk_pll_c2,
> tegra_clk_pll_c3,
> tegra_clk_pll_c4,
> + tegra_clk_pll_c4_out0,
> + tegra_clk_pll_c4_out1,
> + tegra_clk_pll_c4_out2,
> + tegra_clk_pll_c4_out3,
> tegra_clk_pll_c_out1,
> tegra_clk_pll_d,
> tegra_clk_pll_d2,
> diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
> new file mode 100644
> index 000000000000..8bdb31b0bbd8
> --- /dev/null
> +++ b/drivers/clk/tegra/clk-tegra210.c
> @@ -0,0 +1,2704 @@
> +/*
> + * Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/delay.h>
> +#include <linux/export.h>
> +#include <linux/clk/tegra.h>
> +#include <dt-bindings/clock/tegra210-car.h>
> +
> +#include "clk.h"
> +#include "clk-id.h"
> +
> +/*
> + * TEGRA210_CAR_BANK_COUNT: the number of peripheral clock register
> + * banks present in the Tegra210 CAR IP block. The banks are
> + * identified by single letters, e.g.: L, H, U, V, W, X, Y. See
> + * periph_regs[] in drivers/clk/tegra/clk.c
> + */
> +#define TEGRA210_CAR_BANK_COUNT 7
> +
> +#define CLK_SOURCE_CSITE 0x1d4
> +#define CLK_SOURCE_EMC 0x19c
> +
> +#define PLLC_BASE 0x80
> +#define PLLC_OUT 0x84
> +#define PLLC_MISC0 0x88
> +#define PLLC_MISC1 0x8c
> +#define PLLC_MISC2 0x5d0
> +#define PLLC_MISC3 0x5d4
> +
> +#define PLLC2_BASE 0x4e8
> +#define PLLC2_MISC0 0x4ec
> +#define PLLC2_MISC1 0x4f0
> +#define PLLC2_MISC2 0x4f4
> +#define PLLC2_MISC3 0x4f8
> +
> +#define PLLC3_BASE 0x4fc
> +#define PLLC3_MISC0 0x500
> +#define PLLC3_MISC1 0x504
> +#define PLLC3_MISC2 0x508
> +#define PLLC3_MISC3 0x50c
> +
> +#define PLLM_BASE 0x90
> +#define PLLM_MISC0 0x9c
> +#define PLLM_MISC1 0x98
> +#define PLLP_BASE 0xa0
> +#define PLLP_MISC0 0xac
> +#define PLLP_MISC1 0x680
> +#define PLLA_BASE 0xb0
> +#define PLLA_MISC0 0xbc
> +#define PLLA_MISC1 0xb8
> +#define PLLA_MISC2 0x5d8
> +#define PLLD_BASE 0xd0
> +#define PLLD_MISC0 0xdc
> +#define PLLD_MISC1 0xd8
> +#define PLLU_BASE 0xc0
> +#define PLLU_MISC0 0xcc
> +#define PLLU_MISC1 0xc8
> +#define PLLX_BASE 0xe0
> +#define PLLX_MISC0 0xe4
> +#define PLLX_MISC1 0x510
> +#define PLLX_MISC2 0x514
> +#define PLLX_MISC3 0x518
> +#define PLLX_MISC4 0x5f0
> +#define PLLX_MISC5 0x5f4
> +#define PLLE_BASE 0xe8
> +#define PLLE_MISC0 0xec
> +#define PLLD2_BASE 0x4b8
> +#define PLLD2_MISC0 0x4bc
> +#define PLLD2_MISC1 0x570
> +#define PLLD2_MISC2 0x574
> +#define PLLD2_MISC3 0x578
> +#define PLLE_AUX 0x48c
> +#define PLLRE_BASE 0x4c4
> +#define PLLRE_MISC0 0x4c8
> +#define PLLDP_BASE 0x590
> +#define PLLDP_MISC 0x594
> +
> +#define PLLC4_BASE 0x5a4
> +#define PLLC4_MISC0 0x5a8
> +#define PLLC4_OUT 0x5e4
> +#define PLLMB_BASE 0x5e8
> +#define PLLMB_MISC0 0x5ec
> +#define PLLA1_BASE 0x6a4
> +#define PLLA1_MISC0 0x6a8
> +#define PLLA1_MISC1 0x6ac
> +#define PLLA1_MISC2 0x6b0
> +#define PLLA1_MISC3 0x6b4
> +
> +#define PLLU_IDDQ_BIT 31
> +#define PLLCX_IDDQ_BIT 27
> +#define PLLRE_IDDQ_BIT 24
> +#define PLLA_IDDQ_BIT 25
> +#define PLLD_IDDQ_BIT 20
> +#define PLLSS_IDDQ_BIT 18
> +#define PLLM_IDDQ_BIT 5
> +#define PLLMB_IDDQ_BIT 17
> +#define PLLXP_IDDQ_BIT 3
> +
> +#define PLLCX_RESET_BIT 30
> +
> +#define PLL_BASE_LOCK BIT(27)
> +#define PLLCX_BASE_LOCK BIT(26)
> +#define PLLE_MISC_LOCK BIT(11)
> +#define PLLRE_MISC_LOCK BIT(27)
> +
> +#define PLL_MISC_LOCK_ENABLE 18
> +#define PLLC_MISC_LOCK_ENABLE 24
> +#define PLLDU_MISC_LOCK_ENABLE 22
> +#define PLLU_MISC_LOCK_ENABLE 29
> +#define PLLE_MISC_LOCK_ENABLE 9
> +#define PLLRE_MISC_LOCK_ENABLE 30
> +#define PLLSS_MISC_LOCK_ENABLE 30
> +#define PLLP_MISC_LOCK_ENABLE 18
> +#define PLLM_MISC_LOCK_ENABLE 4
> +#define PLLMB_MISC_LOCK_ENABLE 16
> +#define PLLA_MISC_LOCK_ENABLE 28
> +#define PLLU_MISC_LOCK_ENABLE 29
> +#define PLLD_MISC_LOCK_ENABLE 18
> +
> +#define PLLA_SDM_DIN_MASK 0xffff
> +#define PLLA_SDM_EN_MASK BIT(26)
> +
> +#define PLLD_SDM_EN_MASK BIT(16)
> +
> +#define PLLD2_SDM_EN_MASK BIT(31)
> +#define PLLD2_SSC_EN_MASK BIT(30)
> +
> +#define PLLDP_SS_CFG 0x598
> +#define PLLDP_SDM_EN_MASK BIT(31)
> +#define PLLDP_SSC_EN_MASK BIT(30)
> +#define PLLDP_SS_CTRL1 0x59c
> +#define PLLDP_SS_CTRL2 0x5a0
> +
> +#define PMC_PLLM_WB0_OVERRIDE 0x1dc
> +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
> +
> +#define UTMIP_PLL_CFG2 0x488
> +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6)
> +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
> +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0)
> +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2)
> +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4)
> +
> +#define UTMIP_PLL_CFG1 0x484
> +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6)
> +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
> +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17)
> +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16)
> +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15)
> +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
> +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
> +
> +#define UTMIPLL_HW_PWRDN_CFG0 0x52c
> +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25)
> +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24)
> +#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6)
> +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5)
> +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4)
> +#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2)
> +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1)
> +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0)
> +
> +#define SPARE_REG0 0x55c
> +#define CLK_M_DIVISOR_SHIFT 2
> +#define CLK_M_DIVISOR_MASK 0x3
> +
> +/*
> + * SDM fractional divisor is 16-bit 2's complement signed number within
> + * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned
> + * 16-bit value, with "0" divisor mapped to 0xFFFF. Data "0" is used to
> + * indicate that SDM is disabled.
> + *
> + * Effective ndiv value when SDM is enabled: ndiv + 1/2 + sdm_din/2^13
> + */
> +#define PLL_SDM_COEFF BIT(13)
> +#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU))
> +#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat)
> +
> +/* Tegra CPU clock and reset control regs */
> +#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
> +
> +#ifdef CONFIG_PM_SLEEP
> +static struct cpu_clk_suspend_context {
> + u32 clk_csite_src;
> +} tegra210_cpu_clk_sctx;
> +#endif
> +
> +static void __iomem *clk_base;
> +static void __iomem *pmc_base;
> +
> +static unsigned long osc_freq;
> +static unsigned long pll_ref_freq;
> +
> +static DEFINE_SPINLOCK(pll_d_lock);
> +static DEFINE_SPINLOCK(pll_e_lock);
> +static DEFINE_SPINLOCK(pll_re_lock);
> +static DEFINE_SPINLOCK(pll_u_lock);
> +static DEFINE_SPINLOCK(emc_lock);
> +
> +/* possible OSC frequencies in Hz */
> +static unsigned long tegra210_input_freq[] = {
> + [5] = 38400000,
> + [8] = 12000000,
> +};
> +
> +static const char *mux_pllmcp_clkm[] = {
> + "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3",
> +};
> +#define mux_pllmcp_clkm_idx NULL
> +
> +#define PLL_ENABLE (1 << 30)
> +
> +#define PLLCX_MISC1_IDDQ (1 << 27)
> +#define PLLCX_MISC0_RESET (1 << 30)
> +
> +#define PLLCX_MISC0_DEFAULT_VALUE 0x40080000
> +#define PLLCX_MISC0_WRITE_MASK 0x400ffffb
> +#define PLLCX_MISC1_DEFAULT_VALUE 0x08000000
> +#define PLLCX_MISC1_WRITE_MASK 0x08003cff
> +#define PLLCX_MISC2_DEFAULT_VALUE 0x1f720f05
> +#define PLLCX_MISC2_WRITE_MASK 0xffffff17
> +#define PLLCX_MISC3_DEFAULT_VALUE 0x000000c4
> +#define PLLCX_MISC3_WRITE_MASK 0x00ffffff
> +
> +/* PLLA */
> +#define PLLA_BASE_IDDQ (1 << 25)
> +#define PLLA_BASE_LOCK (1 << 27)
> +
> +#define PLLA_MISC0_LOCK_ENABLE (1 << 28)
> +#define PLLA_MISC0_LOCK_OVERRIDE (1 << 27)
> +
> +#define PLLA_MISC2_EN_SDM (1 << 26)
> +#define PLLA_MISC2_EN_DYNRAMP (1 << 25)
> +
> +#define PLLA_MISC0_DEFAULT_VALUE 0x12000020
> +#define PLLA_MISC0_WRITE_MASK 0x7fffffff
> +#define PLLA_MISC2_DEFAULT_VALUE 0x0
> +#define PLLA_MISC2_WRITE_MASK 0x06ffffff
> +
> +/* PLLD */
> +#define PLLD_MISC0_EN_SDM (1 << 16)
> +#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
> +#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
> +#define PLLD_MISC0_IDDQ (1 << 20)
> +#define PLLD_MISC0_DSI_CLKENABLE (1 << 21)
> +
> +#define PLLD_MISC0_DEFAULT_VALUE 0x00140000
> +#define PLLD_MISC0_WRITE_MASK 0x3ff7ffff
> +#define PLLD_MISC1_DEFAULT_VALUE 0x20
> +#define PLLD_MISC1_WRITE_MASK 0x00ffffff
> +
> +/* PLLD2 and PLLDP and PLLC4 */
> +#define PLLDSS_BASE_LOCK (1 << 27)
> +#define PLLDSS_BASE_LOCK_OVERRIDE (1 << 24)
> +#define PLLDSS_BASE_IDDQ (1 << 18)
> +#define PLLDSS_BASE_REF_SEL_SHIFT 25
> +#define PLLDSS_BASE_REF_SEL_MASK (0x3 << PLLDSS_BASE_REF_SEL_SHIFT)
> +
> +#define PLLDSS_MISC0_LOCK_ENABLE (1 << 30)
> +
> +#define PLLDSS_MISC1_CFG_EN_SDM (1 << 31)
> +#define PLLDSS_MISC1_CFG_EN_SSC (1 << 30)
> +
> +#define PLLD2_MISC0_DEFAULT_VALUE 0x40000020
> +#define PLLD2_MISC1_CFG_DEFAULT_VALUE 0x10000000
> +#define PLLD2_MISC2_CTRL1_DEFAULT_VALUE 0x0
> +#define PLLD2_MISC3_CTRL2_DEFAULT_VALUE 0x0
> +
> +#define PLLDP_MISC0_DEFAULT_VALUE 0x40000020
> +#define PLLDP_MISC1_CFG_DEFAULT_VALUE 0xc0000000
> +#define PLLDP_MISC2_CTRL1_DEFAULT_VALUE 0xf400f0da
> +#define PLLDP_MISC3_CTRL2_DEFAULT_VALUE 0x2004f400
> +
> +#define PLLDSS_MISC0_WRITE_MASK 0x47ffffff
> +#define PLLDSS_MISC1_CFG_WRITE_MASK 0xf8000000
> +#define PLLDSS_MISC2_CTRL1_WRITE_MASK 0xffffffff
> +#define PLLDSS_MISC3_CTRL2_WRITE_MASK 0xffffffff
> +
> +#define PLLC4_MISC0_DEFAULT_VALUE 0x40000000
> +
> +/* PLLRE */
> +#define PLLRE_MISC0_LOCK_ENABLE (1 << 30)
> +#define PLLRE_MISC0_LOCK_OVERRIDE (1 << 29)
> +#define PLLRE_MISC0_LOCK (1 << 27)
> +#define PLLRE_MISC0_IDDQ (1 << 24)
> +
> +#define PLLRE_BASE_DEFAULT_VALUE 0x0
> +#define PLLRE_MISC0_DEFAULT_VALUE 0x41000000
> +
> +#define PLLRE_BASE_DEFAULT_MASK 0x1c000000
> +#define PLLRE_MISC0_WRITE_MASK 0x67ffffff
> +
> +/* PLLX */
> +#define PLLX_USE_DYN_RAMP 1
> +#define PLLX_BASE_LOCK (1 << 27)
> +
> +#define PLLX_MISC0_FO_G_DISABLE (0x1 << 28)
> +#define PLLX_MISC0_LOCK_ENABLE (0x1 << 18)
> +
> +#define PLLX_MISC2_DYNRAMP_STEPB_SHIFT 24
> +#define PLLX_MISC2_DYNRAMP_STEPB_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPB_SHIFT)
> +#define PLLX_MISC2_DYNRAMP_STEPA_SHIFT 16
> +#define PLLX_MISC2_DYNRAMP_STEPA_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPA_SHIFT)
> +#define PLLX_MISC2_NDIV_NEW_SHIFT 8
> +#define PLLX_MISC2_NDIV_NEW_MASK (0xFF << PLLX_MISC2_NDIV_NEW_SHIFT)
> +#define PLLX_MISC2_LOCK_OVERRIDE (0x1 << 4)
> +#define PLLX_MISC2_DYNRAMP_DONE (0x1 << 2)
> +#define PLLX_MISC2_EN_DYNRAMP (0x1 << 0)
> +
> +#define PLLX_MISC3_IDDQ (0x1 << 3)
> +
> +#define PLLX_MISC0_DEFAULT_VALUE PLLX_MISC0_LOCK_ENABLE
> +#define PLLX_MISC0_WRITE_MASK 0x10c40000
> +#define PLLX_MISC1_DEFAULT_VALUE 0x20
> +#define PLLX_MISC1_WRITE_MASK 0x00ffffff
> +#define PLLX_MISC2_DEFAULT_VALUE 0x0
> +#define PLLX_MISC2_WRITE_MASK 0xffffff11
> +#define PLLX_MISC3_DEFAULT_VALUE PLLX_MISC3_IDDQ
> +#define PLLX_MISC3_WRITE_MASK 0x01ff0f0f
> +#define PLLX_MISC4_DEFAULT_VALUE 0x0
> +#define PLLX_MISC4_WRITE_MASK 0x8000ffff
> +#define PLLX_MISC5_DEFAULT_VALUE 0x0
> +#define PLLX_MISC5_WRITE_MASK 0x0000ffff
> +
> +#define PLLX_HW_CTRL_CFG 0x548
> +#define PLLX_HW_CTRL_CFG_SWCTRL (0x1 << 0)
> +
> +/* PLLMB */
> +#define PLLMB_BASE_LOCK (1 << 27)
> +
> +#define PLLMB_MISC0_LOCK_OVERRIDE (1 << 18)
> +#define PLLMB_MISC0_IDDQ (1 << 17)
> +#define PLLMB_MISC0_LOCK_ENABLE (1 << 16)
> +
> +#define PLLMB_MISC0_DEFAULT_VALUE 0x00030000
> +#define PLLMB_MISC0_WRITE_MASK 0x0007ffff
> +
> +/* PLLP */
> +#define PLLP_BASE_OVERRIDE (1 << 28)
> +#define PLLP_BASE_LOCK (1 << 27)
> +
> +#define PLLP_MISC0_LOCK_ENABLE (1 << 18)
> +#define PLLP_MISC0_LOCK_OVERRIDE (1 << 17)
> +#define PLLP_MISC0_IDDQ (1 << 3)
> +
> +#define PLLP_MISC1_HSIO_EN_SHIFT 29
> +#define PLLP_MISC1_HSIO_EN (1 << PLLP_MISC1_HSIO_EN_SHIFT)
> +#define PLLP_MISC1_XUSB_EN_SHIFT 28
> +#define PLLP_MISC1_XUSB_EN (1 << PLLP_MISC1_XUSB_EN_SHIFT)
> +
> +#define PLLP_MISC0_DEFAULT_VALUE 0x00040008
> +#define PLLP_MISC1_DEFAULT_VALUE 0x0
> +
> +#define PLLP_MISC0_WRITE_MASK 0xdc6000f
> +#define PLLP_MISC1_WRITE_MASK 0x70ffffff
> +
> +/* PLLU */
> +#define PLLU_BASE_LOCK (1 << 27)
> +#define PLLU_BASE_OVERRIDE (1 << 24)
> +#define PLLU_BASE_CLKENABLE_USB (1 << 21)
> +
> +#define PLLU_MISC0_IDDQ (1 << 31)
> +#define PLLU_MISC0_LOCK_ENABLE (1 << 29)
> +#define PLLU_MISC1_LOCK_OVERRIDE (1 << 0)
> +
> +#define PLLU_MISC0_DEFAULT_VALUE 0xa0000000
> +#define PLLU_MISC1_DEFAULT_VALUE 0x0
> +
> +#define PLLU_MISC0_WRITE_MASK 0xbfffffff
> +#define PLLU_MISC1_WRITE_MASK 0x00000007
> +
> +/*
> + * PLLCX: PLLC, PLLC2, PLLC3, PLLA1
> + * Hybrid PLLs with dynamic ramp. Dynamic ramp is allowed for any transition
> + * that changes NDIV only, while PLL is already locked.
> + */
> +static void pllcx_check_defaults(struct tegra_clk_pll_params *params)
> +{
> + u32 default_val;
> +
> + default_val = PLLCX_MISC0_DEFAULT_VALUE & (~PLLCX_MISC0_RESET);
> + PLL_MISC_CHK_DEFAULT(clk_base, params, 0, default_val,
> + PLLCX_MISC0_WRITE_MASK);
> +
> + default_val = PLLCX_MISC1_DEFAULT_VALUE & (~PLLCX_MISC1_IDDQ);
> + PLL_MISC_CHK_DEFAULT(clk_base, params, 1, default_val,
> + PLLCX_MISC1_WRITE_MASK);
> +
> + default_val = PLLCX_MISC2_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, params, 2, default_val,
> + PLLCX_MISC2_WRITE_MASK);
> +
> + default_val = PLLCX_MISC3_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, params, 3, default_val,
> + PLLCX_MISC3_WRITE_MASK);
> +}
> +
> +void tegra210_pllcx_set_defaults(struct tegra_clk_pll *pllcx)
> +{
> + pllcx->params->defaults_set = true;
> +
> + if (readl_relaxed(clk_base + pllcx->params->base_reg) &
> + PLL_ENABLE) {
> + /* PLL is ON: only check if defaults already set */
> + pllcx_check_defaults(pllcx->params);
> + return;
> + }
> +
> + /* Defaults assert PLL reset, and set IDDQ */
> + writel_relaxed(PLLCX_MISC0_DEFAULT_VALUE,
> + clk_base + pllcx->params->ext_misc_reg[0]);
> + writel_relaxed(PLLCX_MISC1_DEFAULT_VALUE,
> + clk_base + pllcx->params->ext_misc_reg[1]);
> + writel_relaxed(PLLCX_MISC2_DEFAULT_VALUE,
> + clk_base + pllcx->params->ext_misc_reg[2]);
> + writel_relaxed(PLLCX_MISC3_DEFAULT_VALUE,
> + clk_base + pllcx->params->ext_misc_reg[3]);
> + udelay(1);
> +}
> +
> +/*
> + * PLLA
> + * PLL with dynamic ramp and fractional SDM. Dynamic ramp is not used.
> + * Fractional SDM is allowed to provide exact audio rates.
> + */
> +void tegra210_plla_set_defaults(struct tegra_clk_pll *plla)
> +{
> + u32 mask;
> + u32 val = readl_relaxed(clk_base + plla->params->base_reg);
> +
> + plla->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + if (val & PLLA_BASE_IDDQ) {
> + pr_warn("PLL_A boot enabled with IDDQ set\n");
> + plla->params->defaults_set = false;
> + }
> +
> + val = PLLA_MISC0_DEFAULT_VALUE; /* ignore lock enable */
> + mask = PLLA_MISC0_LOCK_ENABLE | PLLA_MISC0_LOCK_OVERRIDE;
> + PLL_MISC_CHK_DEFAULT(clk_base, plla->params, 0, val,
> + ~mask & PLLA_MISC0_WRITE_MASK);
> +
> + val = PLLA_MISC2_DEFAULT_VALUE; /* ignore all but control bit */
> + PLL_MISC_CHK_DEFAULT(clk_base, plla->params, 2, val,
> + PLLA_MISC2_EN_DYNRAMP);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + plla->params->ext_misc_reg[0]);
> + val &= ~mask;
> + val |= PLLA_MISC0_DEFAULT_VALUE & mask;
> + writel_relaxed(val, clk_base + plla->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect, disable dynamic ramp and SDM */
> + val |= PLLA_BASE_IDDQ;
> + writel_relaxed(val, clk_base + plla->params->base_reg);
> + writel_relaxed(PLLA_MISC0_DEFAULT_VALUE,
> + clk_base + plla->params->ext_misc_reg[0]);
> + writel_relaxed(PLLA_MISC2_DEFAULT_VALUE,
> + clk_base + plla->params->ext_misc_reg[2]);
> + udelay(1);
> +}
> +
> +/*
> + * PLLD
> + * PLL with fractional SDM.
> + */
> +void tegra210_plld_set_defaults(struct tegra_clk_pll *plld)
> +{
> + u32 mask = 0xffff;
> +
> + plld->params->defaults_set = true;
> +
> + if (readl_relaxed(clk_base + plld->params->base_reg) &
> + PLL_ENABLE) {
> + u32 val;
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + val = PLLD_MISC1_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, plld->params, 1,
> + val, PLLD_MISC1_WRITE_MASK);
> +
> + /* ignore lock, DSI and SDM controls, make sure IDDQ not set */
> + val = PLLD_MISC0_DEFAULT_VALUE & (~PLLD_MISC0_IDDQ);
> + mask |= PLLD_MISC0_DSI_CLKENABLE | PLLD_MISC0_LOCK_ENABLE |
> + PLLD_MISC0_LOCK_OVERRIDE | PLLD_MISC0_EN_SDM;
> + PLL_MISC_CHK_DEFAULT(clk_base, plld->params, 0, val,
> + ~mask & PLLD_MISC0_WRITE_MASK);
> +
> + /* Enable lock detect */
> + mask = PLLD_MISC0_LOCK_ENABLE | PLLD_MISC0_LOCK_OVERRIDE;
> + val = readl_relaxed(clk_base + plld->params->ext_misc_reg[0]);
> + val &= ~mask;
> + val |= PLLD_MISC0_DEFAULT_VALUE & mask;
> + writel_relaxed(val, clk_base + plld->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect, disable SDM */
> + writel_relaxed(PLLD_MISC0_DEFAULT_VALUE, clk_base +
> + plld->params->ext_misc_reg[0]);
> + writel_relaxed(PLLD_MISC1_DEFAULT_VALUE, clk_base +
> + plld->params->ext_misc_reg[1]);
> + udelay(1);
> +}
> +
> +/*
> + * PLLD2, PLLDP
> + * PLL with fractional SDM and Spread Spectrum (SDM is a must if SSC is used).
> + */
> +static void plldss_defaults(struct tegra_clk_pll *plldss,
> + u32 misc0_val, u32 misc1_val, u32 misc2_val, u32 misc3_val)
> +{
> + u32 default_val;
> + u32 val = readl_relaxed(clk_base + plldss->params->base_reg);
> +
> + plldss->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + if (val & PLLDSS_BASE_IDDQ) {
> + pr_warn("plldss boot enabled with IDDQ set\n");
> + plldss->params->defaults_set = false;
> + }
> +
> + /* ignore lock enable */
> + default_val = misc0_val;
> + PLL_MISC_CHK_DEFAULT(clk_base, plldss->params, 0, default_val,
> + PLLDSS_MISC0_WRITE_MASK &
> + (~PLLDSS_MISC0_LOCK_ENABLE));
> +
> + /*
> + * If SSC is used, check all settings, otherwise just confirm
> + * that SSC is not used on boot as well. Do nothing when using
> + * this function for PLLC4 that has only MISC0.
> + */
> + if (plldss->params->ssc_ctrl_en_mask) {
> + default_val = misc1_val;
> + PLL_MISC_CHK_DEFAULT(clk_base, plldss->params, 1,
> + default_val, PLLDSS_MISC1_CFG_WRITE_MASK);
> + default_val = misc2_val;
> + PLL_MISC_CHK_DEFAULT(clk_base, plldss->params, 2,
> + default_val, PLLDSS_MISC2_CTRL1_WRITE_MASK);
> + default_val = misc3_val;
> + PLL_MISC_CHK_DEFAULT(clk_base, plldss->params, 3,
> + default_val, PLLDSS_MISC3_CTRL2_WRITE_MASK);
> + } else if (plldss->params->ext_misc_reg[1]) {
> + default_val = misc1_val;
> + PLL_MISC_CHK_DEFAULT(clk_base, plldss->params, 1,
> + default_val, PLLDSS_MISC1_CFG_WRITE_MASK &
> + (~PLLDSS_MISC1_CFG_EN_SDM));
> + }
> +
> + /* Enable lock detect */
> + if (val & PLLDSS_BASE_LOCK_OVERRIDE) {
> + val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
> + writel_relaxed(val, clk_base +
> + plldss->params->base_reg);
> + }
> +
> + val = readl_relaxed(clk_base + plldss->params->ext_misc_reg[0]);
> + val &= ~PLLDSS_MISC0_LOCK_ENABLE;
> + val |= misc0_val & PLLDSS_MISC0_LOCK_ENABLE;
> + writel_relaxed(val, clk_base + plldss->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect, configure SDM/SSC */
> + val |= PLLDSS_BASE_IDDQ;
> + val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
> + writel_relaxed(val, clk_base + plldss->params->base_reg);
> +
> + /* When using this function for PLLC4 exit here */
> + if (!plldss->params->ext_misc_reg[1]) {
> + writel_relaxed(misc0_val, clk_base +
> + plldss->params->ext_misc_reg[0]);
> + udelay(1);
> + return;
> + }
> +
> + writel_relaxed(misc0_val, clk_base +
> + plldss->params->ext_misc_reg[0]);
> + /* if SSC used set by 1st enable */
> + writel_relaxed(misc1_val & (~PLLDSS_MISC1_CFG_EN_SSC),
> + clk_base + plldss->params->ext_misc_reg[1]);
> + writel_relaxed(misc2_val, clk_base + plldss->params->ext_misc_reg[2]);
> + writel_relaxed(misc3_val, clk_base + plldss->params->ext_misc_reg[3]);
> + udelay(1);
> +}
> +
> +void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2)
> +{
> + plldss_defaults(plld2, PLLD2_MISC0_DEFAULT_VALUE,
> + PLLD2_MISC1_CFG_DEFAULT_VALUE,
> + PLLD2_MISC2_CTRL1_DEFAULT_VALUE,
> + PLLD2_MISC3_CTRL2_DEFAULT_VALUE);
> +}
> +
> +void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp)
> +{
> + plldss_defaults(plldp, PLLDP_MISC0_DEFAULT_VALUE,
> + PLLDP_MISC1_CFG_DEFAULT_VALUE,
> + PLLDP_MISC2_CTRL1_DEFAULT_VALUE,
> + PLLDP_MISC3_CTRL2_DEFAULT_VALUE);
> +}
> +
> +/*
> + * PLLC4
> + * Base and misc0 layout is the same as PLLD2/PLLDP, but no SDM/SSC support.
> + * VCO is exposed to the clock tree via fixed 1/3 and 1/5 dividers.
> + */
> +void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4)
> +{
> + plldss_defaults(pllc4, PLLC4_MISC0_DEFAULT_VALUE, 0, 0, 0);
> +}
> +
> +/*
> + * PLLRE
> + * VCO is exposed to the clock tree directly along with post-divider output
> + */
> +void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre)
> +{
> + u32 mask;
> + u32 val = readl_relaxed(clk_base + pllre->params->base_reg);
> +
> + pllre->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + val &= PLLRE_BASE_DEFAULT_MASK;
> + if (val != PLLRE_BASE_DEFAULT_VALUE) {
> + pr_warn("pllre boot base 0x%x : expected 0x%x\n",
> + val, PLLRE_BASE_DEFAULT_VALUE);
> + pr_warn("(comparison mask = 0x%x)\n",
> + PLLRE_BASE_DEFAULT_MASK);
> + pllre->params->defaults_set = false;
> + }
> +
> + /* Ignore lock enable */
> + val = PLLRE_MISC0_DEFAULT_VALUE & (~PLLRE_MISC0_IDDQ);
> + mask = PLLRE_MISC0_LOCK_ENABLE | PLLRE_MISC0_LOCK_OVERRIDE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pllre->params, 0, val,
> + ~mask & PLLRE_MISC0_WRITE_MASK);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]);
> + val &= ~mask;
> + val |= PLLRE_MISC0_DEFAULT_VALUE & mask;
> + writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect */
> + val &= ~PLLRE_BASE_DEFAULT_MASK;
> + val |= PLLRE_BASE_DEFAULT_VALUE & PLLRE_BASE_DEFAULT_MASK;
> + writel_relaxed(val, clk_base + pllre->params->base_reg);
> + writel_relaxed(PLLRE_MISC0_DEFAULT_VALUE,
> + clk_base + pllre->params->ext_misc_reg[0]);
> + udelay(1);
> +}
> +
> +static void pllx_get_dyn_steps(struct clk_hw *hw, u32 *step_a, u32 *step_b)
> +{
> + unsigned long input_rate;
> +
> + if (!IS_ERR_OR_NULL(hw->clk)) {
> + input_rate = __clk_get_rate(__clk_get_parent(hw->clk));
> + /* cf rate */
> + input_rate /= tegra_pll_get_fixed_mdiv(hw, input_rate);
> + } else {
> + input_rate = 38400000;
> + }
> +
> + switch (input_rate) {
> + case 12000000:
> + case 12800000:
> + case 13000000:
> + *step_a = 0x2B;
> + *step_b = 0x0B;
> + return;
> + case 19200000:
> + *step_a = 0x12;
> + *step_b = 0x08;
> + return;
> + case 38400000:
> + *step_a = 0x04;
> + *step_b = 0x05;
> + return;
> + default:
> + pr_err("%s: Unexpected reference rate %lu\n",
> + __func__, input_rate);
> + BUG();
> + }
> +}
> +
> +static void pllx_check_defaults(struct tegra_clk_pll *pll)
> +{
> + u32 default_val;
> +
> + default_val = PLLX_MISC0_DEFAULT_VALUE;
> + /* ignore lock enable */
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 0, default_val,
> + PLLX_MISC0_WRITE_MASK & (~PLLX_MISC0_LOCK_ENABLE));
> +
> + default_val = PLLX_MISC1_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 1, default_val,
> + PLLX_MISC1_WRITE_MASK);
> +
> + /* ignore all but control bit */
> + default_val = PLLX_MISC2_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 2,
> + default_val, PLLX_MISC2_EN_DYNRAMP);
> +
> + default_val = PLLX_MISC3_DEFAULT_VALUE & (~PLLX_MISC3_IDDQ);
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 3, default_val,
> + PLLX_MISC3_WRITE_MASK);
> +
> + default_val = PLLX_MISC4_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 4, default_val,
> + PLLX_MISC4_WRITE_MASK);
> +
> + default_val = PLLX_MISC5_DEFAULT_VALUE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 5, default_val,
> + PLLX_MISC5_WRITE_MASK);
> +}
> +
> +void tegra210_pllx_set_defaults(struct tegra_clk_pll *pllx)
> +{
> + u32 val;
> + u32 step_a, step_b;
> +
> + pllx->params->defaults_set = true;
> +
> + /* Get ready dyn ramp state machine settings */
> + pllx_get_dyn_steps(&pllx->hw, &step_a, &step_b);
> + val = PLLX_MISC2_DEFAULT_VALUE & (~PLLX_MISC2_DYNRAMP_STEPA_MASK) &
> + (~PLLX_MISC2_DYNRAMP_STEPB_MASK);
> + val |= step_a << PLLX_MISC2_DYNRAMP_STEPA_SHIFT;
> + val |= step_b << PLLX_MISC2_DYNRAMP_STEPB_SHIFT;
> +
> + if (readl_relaxed(clk_base + pllx->params->base_reg) & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + pllx_check_defaults(pllx);
> +
> + /* Configure dyn ramp, disable lock override */
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[0]);
> + val &= ~PLLX_MISC0_LOCK_ENABLE;
> + val |= PLLX_MISC0_DEFAULT_VALUE & PLLX_MISC0_LOCK_ENABLE;
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* Enable lock detect and CPU output */
> + writel_relaxed(PLLX_MISC0_DEFAULT_VALUE, clk_base +
> + pllx->params->ext_misc_reg[0]);
> +
> + /* Setup */
> + writel_relaxed(PLLX_MISC1_DEFAULT_VALUE, clk_base +
> + pllx->params->ext_misc_reg[1]);
> +
> + /* Configure dyn ramp state machine, disable lock override */
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]);
> +
> + /* Set IDDQ */
> + writel_relaxed(PLLX_MISC3_DEFAULT_VALUE, clk_base +
> + pllx->params->ext_misc_reg[3]);
> +
> + /* Disable SDM */
> + writel_relaxed(PLLX_MISC4_DEFAULT_VALUE, clk_base +
> + pllx->params->ext_misc_reg[4]);
> + writel_relaxed(PLLX_MISC5_DEFAULT_VALUE, clk_base +
> + pllx->params->ext_misc_reg[5]);
> + udelay(1);
> +}
> +
> +/* PLLMB */
> +void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb)
> +{
> + u32 mask, val = readl_relaxed(clk_base + pllmb->params->base_reg);
> +
> + pllmb->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + val = PLLMB_MISC0_DEFAULT_VALUE & (~PLLMB_MISC0_IDDQ);
> + mask = PLLMB_MISC0_LOCK_ENABLE | PLLMB_MISC0_LOCK_OVERRIDE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pllmb->params, 0, val,
> + ~mask & PLLMB_MISC0_WRITE_MASK);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + pllmb->params->ext_misc_reg[0]);
> + val &= ~mask;
> + val |= PLLMB_MISC0_DEFAULT_VALUE & mask;
> + writel_relaxed(val, clk_base + pllmb->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect */
> + writel_relaxed(PLLMB_MISC0_DEFAULT_VALUE,
> + clk_base + pllmb->params->ext_misc_reg[0]);
> + udelay(1);
> +}
> +
> +/*
> + * PLLP
> + * VCO is exposed to the clock tree directly along with post-divider output.
> + * Both VCO and post-divider output rates are fixed at 408MHz and 204MHz,
> + * respectively.
> + */
> +static void pllp_check_defaults(struct tegra_clk_pll *pll, bool enabled)
> +{
> + u32 val, mask;
> +
> + /* Ignore lock enable (will be set), make sure not in IDDQ if enabled */
> + val = PLLP_MISC0_DEFAULT_VALUE & (~PLLP_MISC0_IDDQ);
> + mask = PLLP_MISC0_LOCK_ENABLE | PLLP_MISC0_LOCK_OVERRIDE;
> + if (!enabled)
> + mask |= PLLP_MISC0_IDDQ;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 0, val,
> + ~mask & PLLP_MISC0_WRITE_MASK);
> +
> + /* Ignore branch controls */
> + val = PLLP_MISC1_DEFAULT_VALUE;
> + mask = PLLP_MISC1_HSIO_EN | PLLP_MISC1_XUSB_EN;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 1, val,
> + ~mask & PLLP_MISC1_WRITE_MASK);
> +}
> +
> +void tegra210_pllp_set_defaults(struct tegra_clk_pll *pllp)
> +{
> + u32 mask;
> + u32 val = readl_relaxed(clk_base + pllp->params->base_reg);
> +
> + pllp->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + pllp_check_defaults(pllp, true);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + pllp->params->ext_misc_reg[0]);
> + mask = PLLP_MISC0_LOCK_ENABLE | PLLP_MISC0_LOCK_OVERRIDE;
> + val &= ~mask;
> + val |= PLLP_MISC0_DEFAULT_VALUE & mask;
> + writel_relaxed(val, clk_base + pllp->params->ext_misc_reg[0]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect */
> + writel_relaxed(PLLP_MISC0_DEFAULT_VALUE,
> + clk_base + pllp->params->ext_misc_reg[0]);
> +
> + /* Preserve branch control */
> + val = readl_relaxed(clk_base + pllp->params->ext_misc_reg[1]);
> + mask = PLLP_MISC1_HSIO_EN | PLLP_MISC1_XUSB_EN;
> + val &= mask;
> + val |= ~mask & PLLP_MISC1_DEFAULT_VALUE;
> + writel_relaxed(val, clk_base + pllp->params->ext_misc_reg[1]);
> + udelay(1);
> +}
> +
> +/*
> + * PLLU
> + * VCO is exposed to the clock tree directly along with post-divider output.
> + * Both VCO and post-divider output rates are fixed at 480MHz and 240MHz,
> + * respectively.
> + */
> +static void pllu_check_defaults(struct tegra_clk_pll *pll, bool hw_control)
> +{
> + u32 val, mask;
> +
> + /* Ignore lock enable (will be set) and IDDQ if under h/w control */
> + val = PLLU_MISC0_DEFAULT_VALUE & (~PLLU_MISC0_IDDQ);
> + mask = PLLU_MISC0_LOCK_ENABLE | (hw_control ? PLLU_MISC0_IDDQ : 0);
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 0, val,
> + ~mask & PLLU_MISC0_WRITE_MASK);
> +
> + val = PLLU_MISC1_DEFAULT_VALUE;
> + mask = PLLU_MISC1_LOCK_OVERRIDE;
> + PLL_MISC_CHK_DEFAULT(clk_base, pll->params, 1, val,
> + ~mask & PLLU_MISC1_WRITE_MASK);
> +}
> +
> +void tegra210_pllu_set_defaults(struct tegra_clk_pll *pllu)
> +{
> + u32 val = readl_relaxed(clk_base + pllu->params->base_reg);
> +
> + pllu->params->defaults_set = true;
> +
> + if (val & PLL_ENABLE) {
> + /*
> + * PLL is ON: check if defaults already set, then set those
> + * that can be updated in flight.
> + */
> + pllu_check_defaults(pllu, false);
> +
> + /* Enable lock detect */
> + val = readl_relaxed(clk_base + pllu->params->ext_misc_reg[0]);
> + val &= ~PLLU_MISC0_LOCK_ENABLE;
> + val |= PLLU_MISC0_DEFAULT_VALUE & PLLU_MISC0_LOCK_ENABLE;
> + writel_relaxed(val, clk_base + pllu->params->ext_misc_reg[0]);
> +
> + val = readl_relaxed(clk_base + pllu->params->ext_misc_reg[1]);
> + val &= ~PLLU_MISC1_LOCK_OVERRIDE;
> + val |= PLLU_MISC1_DEFAULT_VALUE & PLLU_MISC1_LOCK_OVERRIDE;
> + writel_relaxed(val, clk_base + pllu->params->ext_misc_reg[1]);
> + udelay(1);
> +
> + return;
> + }
> +
> + /* set IDDQ, enable lock detect */
> + writel_relaxed(PLLU_MISC0_DEFAULT_VALUE,
> + clk_base + pllu->params->ext_misc_reg[0]);
> + writel_relaxed(PLLU_MISC1_DEFAULT_VALUE,
> + clk_base + pllu->params->ext_misc_reg[1]);
> + udelay(1);
> +}
> +
> +#define mask(w) ((1 << (w)) - 1)
> +#define divm_mask(p) mask(p->params->div_nmp->divm_width)
> +#define divn_mask(p) mask(p->params->div_nmp->divn_width)
> +#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\
> + mask(p->params->div_nmp->divp_width))
> +
> +#define PLL_LOCKDET_DELAY 2 /* Lock detection safety delays */
> +static int tegra210_wait_for_mask(struct tegra_clk_pll *pll,
> + u32 reg, u32 mask)
> +{
> + int i;
> + u32 val = 0;
> +
> + for (i = 0; i < pll->params->lock_delay / PLL_LOCKDET_DELAY + 1; i++) {
> + udelay(PLL_LOCKDET_DELAY);
> + val = readl_relaxed(clk_base + reg);
> + if ((val & mask) == mask) {
> + udelay(PLL_LOCKDET_DELAY);
> + return 0;
> + }
> + }
> + return -ETIMEDOUT;
> +}
> +
> +static int tegra210_pllx_dyn_ramp(struct tegra_clk_pll *pllx,
> + struct tegra_clk_pll_freq_table *cfg)
> +{
> + u32 val, base, ndiv_new_mask;
> +
> + ndiv_new_mask = (divn_mask(pllx) >> pllx->params->div_nmp->divn_shift)
> + << PLLX_MISC2_NDIV_NEW_SHIFT;
> +
> + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[2]);
> + val &= (~ndiv_new_mask);
> + val |= cfg->n << PLLX_MISC2_NDIV_NEW_SHIFT;
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]);
> + udelay(1);
> +
> + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[2]);
> + val |= PLLX_MISC2_EN_DYNRAMP;
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]);
> + udelay(1);
> +
> + tegra210_wait_for_mask(pllx, pllx->params->ext_misc_reg[2],
> + PLLX_MISC2_DYNRAMP_DONE);
> +
> + base = readl_relaxed(clk_base + pllx->params->base_reg) &
> + (~divn_mask(pllx));
> + base |= cfg->n << pllx->params->div_nmp->divn_shift;
> + writel_relaxed(base, clk_base + pllx->params->base_reg);
> + udelay(1);
> +
> + val &= ~PLLX_MISC2_EN_DYNRAMP;
> + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]);
> + udelay(1);
> +
> + pr_debug("%s: dynamic ramp to m = %u n = %u p = %u, Fout = %lu kHz\n",
> + __clk_get_name(pllx->hw.clk), cfg->m, cfg->n, cfg->p,
> + cfg->input_rate / cfg->m * cfg->n / cfg->p / 1000);
> +
> + return 0;
> +}
> +
> +static int _p_div_to_hw(struct clk_hw *hw, u8 p_div)
> +{
> + struct tegra_clk_pll *pll = to_clk_pll(hw);
> + struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
> +
> + if (p_tohw) {
> + while (p_tohw->pdiv) {
> + if (p_div <= p_tohw->pdiv)
> + return p_tohw->hw_val;
> + p_tohw++;
> + }
> + return -EINVAL;
> + }
> + return -EINVAL;
> +}
> +
> +/*
> + * Common configuration for PLLs with fixed input divider policy:
> + * - always set fixed M-value based on the reference rate
> + * - always set P-value value 1:1 for output rates above VCO minimum, and
> + * choose minimum necessary P-value for output rates below VCO maximum
> + * - calculate N-value based on selected M and P
> + * - calculate SDM_DIN fractional part
> + */
> +static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw,
> + struct tegra_clk_pll_freq_table *cfg,
> + unsigned long rate, unsigned long input_rate)
> +{
> + struct tegra_clk_pll *pll = to_clk_pll(hw);
> + struct tegra_clk_pll_params *params = pll->params;
> + int p;
> + unsigned long cf, p_rate;
> + u32 pdiv;
> +
> + if (!rate)
> + return -EINVAL;
> +
> + if (!params->vco_out) {
> + p = DIV_ROUND_UP(params->vco_min, rate);
> + p = params->round_p_to_pdiv(p, &pdiv);
> + } else {
> + p = rate >= params->vco_min ? 1 : -EINVAL;
> + }
> +
> + if (IS_ERR_VALUE(p))
> + return -EINVAL;
> +
> + cfg->m = tegra_pll_get_fixed_mdiv(hw, input_rate);
> + cfg->p = p;
> +
> + /* Store P as HW value, as that is what is expected */
> + cfg->p = _p_div_to_hw(hw, cfg->p);
> +
> + p_rate = rate * p;
> + if (p_rate > params->vco_max)
> + p_rate = params->vco_max;
> + cf = input_rate / cfg->m;
> + cfg->n = p_rate / cf;
> +
> + cfg->sdm_data = 0;
> + if (params->sdm_ctrl_reg) {
> + unsigned long rem = p_rate - cf * cfg->n;
> + /* If ssc is enabled SDM enabled as well, even for integer n */
> + if (rem || params->ssc_ctrl_reg) {
> + u64 s = rem * PLL_SDM_COEFF;
> +
> + do_div(s, cf);
> + s -= PLL_SDM_COEFF / 2;
> + cfg->sdm_data = sdin_din_to_data(s);
> + }
> + }
> +
> + cfg->input_rate = input_rate;
> + cfg->output_rate = rate;
> +
> + return 0;
> +}
> +
> +/*
> + * clk_pll_set_gain - set gain to m, n to calculate correct VCO rate
> + *
> + * @cfg: struct tegra_clk_pll_freq_table * cfg
> + *
> + * For Normal mode:
> + * Fvco = Fref * NDIV / MDIV
> + *
> + * For fractional mode:
> + * Fvco = Fref * (NDIV + 0.5 + SDM_DIN / PLL_SDM_COEFF) / MDIV
> + */
> +static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg)
> +{
> + cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 +
> + sdin_data_to_din(cfg->sdm_data);
> + cfg->m *= PLL_SDM_COEFF;
> +}
> +
> +unsigned long tegra210_clk_adjust_vco_min(struct tegra_clk_pll_params *params,
> + unsigned long parent_rate)
> +{
> + unsigned long vco_min = params->vco_min;
> +
> + params->vco_min += DIV_ROUND_UP(parent_rate, PLL_SDM_COEFF);
> + vco_min = min(vco_min, params->vco_min);
> +
> + return vco_min;
> +}
> +
> +static struct div_nmp pllx_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> +};
> +/*
> + * PLL post divider maps - two types: quasi-linear and exponential
> + * post divider.
> + */
> +#define PLL_QLIN_PDIV_MAX 16
> +static struct pdiv_map pll_qlin_pdiv_to_hw[] = {
> + { .pdiv = 1, .hw_val = 0 },
> + { .pdiv = 2, .hw_val = 1 },
> + { .pdiv = 3, .hw_val = 2 },
> + { .pdiv = 4, .hw_val = 3 },
> + { .pdiv = 5, .hw_val = 4 },
> + { .pdiv = 6, .hw_val = 5 },
> + { .pdiv = 8, .hw_val = 6 },
> + { .pdiv = 9, .hw_val = 7 },
> + { .pdiv = 10, .hw_val = 8 },
> + { .pdiv = 12, .hw_val = 9 },
> + { .pdiv = 15, .hw_val = 10 },
> + { .pdiv = 16, .hw_val = 11 },
> + { .pdiv = 18, .hw_val = 12 },
> + { .pdiv = 20, .hw_val = 13 },
> + { .pdiv = 24, .hw_val = 14 },
> + { .pdiv = 30, .hw_val = 15 },
> + { .pdiv = 32, .hw_val = 16, },
> +};
> +
> +static u32 pll_qlin_p_to_pdiv(u32 p, u32 *pdiv)
> +{
> + int i;
> +
> + if (p) {
> + for (i = 0; i <= PLL_QLIN_PDIV_MAX; i++) {
> + if (p <= pll_qlin_pdiv_to_hw[i].pdiv) {
> + if (pdiv)
> + *pdiv = i;
> + return pll_qlin_pdiv_to_hw[i].pdiv;
> + }
> + }
> + }
> +
> + return -EINVAL;
> +}
> +
> +#define PLL_EXPO_PDIV_MAX 7
> +static struct pdiv_map pll_expo_pdiv_to_hw[] = {
> + { .pdiv = 1, .hw_val = 0, },
> + { .pdiv = 2, .hw_val = 1, },
> + { .pdiv = 4, .hw_val = 2, },
> + { .pdiv = 8, .hw_val = 3, },
> + { .pdiv = 16, .hw_val = 4, },
> + { .pdiv = 32, .hw_val = 5, },
> + { .pdiv = 64, .hw_val = 6, },
> + { .pdiv = 128, .hw_val = 7, },
> +};
> +
> +static u32 pll_expo_p_to_pdiv(u32 p, u32 *pdiv)
> +{
> + if (p) {
> + u32 i = fls(p);
> +
> + if (i == ffs(p))
> + i--;
> +
> + if (i <= PLL_EXPO_PDIV_MAX) {
> + if (pdiv)
> + *pdiv = i;
> + return 1 << i;
> + }
> + }
> + return -EINVAL;
> +}
> +
> +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
> + /* 1 GHz */
> + { 12000000, 1000000000, 166, 1, 1}, /* actual: 996.0 MHz */
> + { 13000000, 1000000000, 153, 1, 1}, /* actual: 994.0 MHz */
> + { 38400000, 1000000000, 156, 3, 1}, /* actual: 998.4 MHz */
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_x_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 38400000,
> + .vco_min = 1350000000,
> + .vco_max = 3000000000UL,
> + .base_reg = PLLX_BASE,
> + .misc_reg = PLLX_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .ext_misc_reg[0] = PLLX_MISC0,
> + .ext_misc_reg[1] = PLLX_MISC1,
> + .ext_misc_reg[2] = PLLX_MISC2,
> + .ext_misc_reg[3] = PLLX_MISC3,
> + .ext_misc_reg[4] = PLLX_MISC4,
> + .ext_misc_reg[5] = PLLX_MISC5,
> + .iddq_reg = PLLX_MISC3,
> + .iddq_bit_idx = PLLXP_IDDQ_BIT,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .mdiv_default = 2,
> + .dyn_ramp_reg = PLLX_MISC2,
> + .stepa_shift = 16,
> + .stepb_shift = 24,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllx_nmp,
> + .freq_table = pll_x_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .dyn_ramp = tegra210_pllx_dyn_ramp,
> + .set_defaults = tegra210_pllx_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct div_nmp pllc_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 10,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = {
> + { 12000000, 510000000, 85, 1, 1},
> + { 13000000, 510000000, 78, 1, 1}, /* actual: 507.0 MHz */
> + { 38400000, 510000000, 79, 3, 1}, /* actual: 505.6 MHz */
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_c_params = {
> + .input_min = 12000000,
> + .input_max = 700000000,
> + .cf_min = 12000000,
> + .cf_max = 50000000, /* s/w policy, h/w capability 50 MHz */
This is 50Mhz, so the comment isn't required?
> + .vco_min = 600000000,
> + .vco_max = 1200000000,
> + .base_reg = PLLC_BASE,
> + .misc_reg = PLLC_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_delay = 300,
> + .iddq_reg = PLLC_MISC1,
> + .iddq_bit_idx = PLLCX_IDDQ_BIT,
> + .reset_reg = PLLC_MISC0,
> + .reset_bit_idx = PLLCX_RESET_BIT,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLC_MISC0,
> + .ext_misc_reg[1] = PLLC_MISC1,
> + .ext_misc_reg[2] = PLLC_MISC2,
> + .ext_misc_reg[3] = PLLC_MISC3,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .mdiv_default = 3,
> + .div_nmp = &pllc_nmp,
> + .freq_table = pll_cx_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_pllcx_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct div_nmp pllcx_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 10,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_params pll_c2_params = {
> + .input_min = 12000000,
> + .input_max = 700000000,
> + .cf_min = 12000000,
> + .cf_max = 50000000,
> + .vco_min = 600000000,
> + .vco_max = 1200000000,
> + .base_reg = PLLC2_BASE,
> + .misc_reg = PLLC2_MISC0,
> + .iddq_reg = PLLC2_MISC1,
> + .iddq_bit_idx = PLLCX_IDDQ_BIT,
> + .reset_reg = PLLC2_MISC0,
> + .reset_bit_idx = PLLCX_RESET_BIT,
> + .lock_mask = PLLCX_BASE_LOCK,
> + .lock_delay = 300,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .mdiv_default = 3,
> + .div_nmp = &pllcx_nmp,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLC2_MISC0,
> + .ext_misc_reg[1] = PLLC2_MISC1,
> + .ext_misc_reg[2] = PLLC2_MISC2,
> + .ext_misc_reg[3] = PLLC2_MISC3,
> + .freq_table = pll_cx_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_pllcx_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct tegra_clk_pll_params pll_c3_params = {
> + .input_min = 12000000,
> + .input_max = 700000000,
> + .cf_min = 12000000,
> + .cf_max = 50000000,
> + .vco_min = 600000000,
> + .vco_max = 1200000000,
> + .base_reg = PLLC3_BASE,
> + .misc_reg = PLLC3_MISC0,
> + .lock_mask = PLLCX_BASE_LOCK,
> + .lock_delay = 300,
> + .iddq_reg = PLLC3_MISC1,
> + .iddq_bit_idx = PLLCX_IDDQ_BIT,
> + .reset_reg = PLLC3_MISC0,
> + .reset_bit_idx = PLLCX_RESET_BIT,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .mdiv_default = 3,
> + .div_nmp = &pllcx_nmp,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLC3_MISC0,
> + .ext_misc_reg[1] = PLLC3_MISC1,
> + .ext_misc_reg[2] = PLLC3_MISC2,
> + .ext_misc_reg[3] = PLLC3_MISC3,
> + .freq_table = pll_cx_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_pllcx_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct div_nmp pllss_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 19,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = {
> + { 12000000, 600000000, 50, 1, 0},
> + { 13000000, 600000000, 46, 1, 0}, /* actual: 598.0 MHz */
> + { 38400000, 600000000, 62, 4, 0}, /* actual: 595.2 MHz */
> + { 0, 0, 0, 0, 0, 0 },
> +};
> +
> +static const struct clk_div_table pll_re_c4_div_table[] = {
> + { .val = 0, .div = 1 },
> + { .val = 1, .div = 2 },
> + { .val = 2, .div = 3 },
> + { .val = 3, .div = 4 },
> + { .val = 4, .div = 5 },
> + { .val = 5, .div = 6 },
> + { .val = 6, .div = 8 },
> + { .val = 7, .div = 10 },
> + { .val = 8, .div = 12 },
> + { .val = 9, .div = 16 },
> + { .val = 10, .div = 12 },
> + { .val = 11, .div = 16 },
> + { .val = 12, .div = 20 },
> + { .val = 13, .div = 24 },
> + { .val = 14, .div = 32 },
> + { .val = 0, .div = 0 },
> +};
> +
> +static struct tegra_clk_pll_params pll_c4_vco_params = {
> + .input_min = 9600000,
> + .input_max = 800000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 500000000,
> + .vco_max = 1080000000,
> + .base_reg = PLLC4_BASE,
> + .misc_reg = PLLC4_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLC4_MISC0,
> + .iddq_reg = PLLC4_BASE,
> + .iddq_bit_idx = PLLSS_IDDQ_BIT,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .mdiv_default = 3,
> + .div_nmp = &pllss_nmp,
> + .freq_table = pll_c4_vco_freq_table,
> + .vco_out = true,
> + .set_defaults = tegra210_pllc4_set_defaults,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
> + { 12000000, 800000000, 66, 1, 0}, /* actual: 792.0 MHz */
> + { 13000000, 800000000, 61, 1, 0}, /* actual: 793.0 MHz */
> + { 38400000, 297600000, 93, 4, 2},
> + { 38400000, 400000000, 125, 4, 2},
> + { 38400000, 532800000, 111, 4, 1},
> + { 38400000, 665600000, 104, 3, 1},
> + { 38400000, 800000000, 125, 3, 1},
> + { 38400000, 931200000, 97, 4, 0},
> + { 38400000, 1065600000, 111, 4, 0},
> + { 38400000, 1200000000, 125, 4, 0},
> + { 38400000, 1331200000, 104, 3, 0},
> + { 38400000, 1459200000, 76, 2, 0},
> + { 38400000, 1600000000, 125, 3, 0},
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct div_nmp pllm_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .override_divm_shift = 0,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .override_divn_shift = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> + .override_divp_shift = 27,
> +};
> +
> +static struct tegra_clk_pll_params pll_m_params = {
> + .input_min = 9600000,
> + .input_max = 500000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 800000000,
> + .vco_max = 1866000000,
> + .base_reg = PLLM_BASE,
> + .misc_reg = PLLM_MISC1,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLM_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .iddq_reg = PLLM_MISC0,
> + .iddq_bit_idx = PLLM_IDDQ_BIT,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLM_MISC0,
> + .ext_misc_reg[0] = PLLM_MISC1,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllm_nmp,
> + .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
> + .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
> + .freq_table = pll_m_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct tegra_clk_pll_params pll_mb_params = {
> + .input_min = 9600000,
> + .input_max = 500000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 800000000,
> + .vco_max = 1866000000,
> + .base_reg = PLLMB_BASE,
> + .misc_reg = PLLMB_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLMB_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .iddq_reg = PLLMB_MISC0,
> + .iddq_bit_idx = PLLMB_IDDQ_BIT,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLMB_MISC0,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllm_nmp,
> + .freq_table = pll_m_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_pllmb_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +
> +static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
> + /* PLLE special case: use cpcon field to store cml divider value */
> + { 672000000, 100000000, 125, 42, 13,},
> + { 624000000, 100000000, 125, 39, 13,},
> + { 336000000, 100000000, 125, 21, 13,},
> + { 312000000, 100000000, 200, 26, 14,},
> + { 38400000, 100000000, 125, 2, 14,},
> + { 13000000, 100000000, 184, 1, 14,}, /* actual: 99.6MHz (FPGA) */
I don't think we're still running on FPGA? :)
> + { 12000000, 100000000, 200, 1, 14,},
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct div_nmp plle_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 24,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_params pll_e_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 38400000,
> + .vco_min = 1600000000,
> + .vco_max = 2500000000U,
> + .base_reg = PLLE_BASE,
> + .misc_reg = PLLE_MISC0,
> + .aux_reg = PLLE_AUX,
> + .lock_mask = PLLE_MISC_LOCK,
> + .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .div_nmp = &plle_nmp,
> + .freq_table = pll_e_freq_table,
> + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_LOCK_MISC | TEGRA_PLL_USE_LOCK |
> + TEGRA_PLL_HAS_LOCK_ENABLE,
> + .fixed_rate = 100000000,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_re_vco_freq_table[] = {
> + { 12000000, 672000000, 56, 1, 0},
> + { 13000000, 672000000, 51, 1, 0}, /* actual: 663.0 MHz */
> + { 38400000, 672000000, 70, 4, 0},
> + { 0, 0, 0, 0, 0, 0 },
> +};
> +
> +static struct div_nmp pllre_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 16,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_params pll_re_vco_params = {
> + .input_min = 9600000,
> + .input_max = 800000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 350000000,
> + .vco_max = 700000000,
> + .base_reg = PLLRE_BASE,
> + .misc_reg = PLLRE_MISC0,
> + .lock_mask = PLLRE_MISC_LOCK,
> + .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .ext_misc_reg[0] = PLLRE_MISC0,
> + .iddq_reg = PLLRE_MISC0,
> + .iddq_bit_idx = PLLRE_IDDQ_BIT,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllre_nmp,
> + .freq_table = pll_re_vco_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_LOCK_MISC |
> + TEGRA_PLL_HAS_LOCK_ENABLE,
> + .vco_out = true,
> + .set_defaults = tegra210_pllre_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct div_nmp pllp_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 10,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
> + { 12000000, 408000000, 34, 1, 0},
> + { 13000000, 408000000, 408, 13, 0}, /* cf = 1MHz - only on FPGA */
same here :)
> + { 38400000, 408000000, 85, 8, 0}, /* cf = 4.8MHz, allowed exception */
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_p_params = {
> + .input_min = 9600000,
> + .input_max = 800000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 350000000,
> + .vco_max = 700000000,
> + .base_reg = PLLP_BASE,
> + .misc_reg = PLLP_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLP_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .iddq_reg = PLLP_MISC0,
> + .iddq_bit_idx = PLLXP_IDDQ_BIT,
> + .ext_misc_reg[0] = PLLP_MISC0,
> + .ext_misc_reg[1] = PLLP_MISC1,
> + .div_nmp = &pllp_nmp,
> + .freq_table = pll_p_freq_table,
> + .fixed_rate = 408000000,
> + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK |
> + TEGRA_PLL_HAS_LOCK_ENABLE,
> + .vco_out = true,
> + .set_defaults = tegra210_pllp_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct tegra_clk_pll_params pll_a1_params = {
> + .input_min = 12000000,
> + .input_max = 700000000,
> + .cf_min = 12000000,
> + .cf_max = 50000000,
> + .vco_min = 600000000,
> + .vco_max = 1200000000,
> + .base_reg = PLLA1_BASE,
> + .misc_reg = PLLA1_MISC0,
> + .lock_mask = PLLCX_BASE_LOCK,
> + .lock_delay = 300,
> + .iddq_reg = PLLA1_MISC0,
> + .iddq_bit_idx = PLLCX_IDDQ_BIT,
> + .reset_reg = PLLA1_MISC0,
> + .reset_bit_idx = PLLCX_RESET_BIT,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllc_nmp,
> + .ext_misc_reg[0] = PLLA1_MISC0,
> + .ext_misc_reg[1] = PLLA1_MISC1,
> + .ext_misc_reg[2] = PLLA1_MISC2,
> + .ext_misc_reg[3] = PLLA1_MISC3,
> + .freq_table = pll_cx_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_pllcx_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +static struct div_nmp plla_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
> + { 12000000, 282240000, 47, 1, 1, 1, 0xf148}, /* actual: 282240234 */
> + { 12000000, 368640000, 61, 1, 1, 1, 0xfe15}, /* actual: 368640381 */
> + { 12000000, 240000000, 60, 1, 2, 1, },
> +
> + { 13000000, 282240000, 43, 1, 1, 1, 0xfd7d}, /* actual: 282239807 */
> + { 13000000, 368640000, 56, 1, 1, 1, 0x06d8}, /* actual: 368640137 */
> + { 13000000, 240000000, 55, 1, 2, 1, }, /* actual: 238.3 MHz */
> +
> + { 38400000, 282240000, 44, 3, 1, 1, 0xf333}, /* actual: 282239844 */
> + { 38400000, 368640000, 57, 3, 1, 1, 0x0333}, /* actual: 368639844 */
> + { 38400000, 240000000, 75, 3, 3, 1,},
> + {0, 0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_a_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 19200000,
> + .vco_min = 500000000,
> + .vco_max = 1000000000,
> + .base_reg = PLLA_BASE,
> + .misc_reg = PLLA_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLA_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .iddq_reg = PLLA_BASE,
> + .iddq_bit_idx = PLLA_IDDQ_BIT,
> + .div_nmp = &plla_nmp,
> + .sdm_din_reg = PLLA_MISC0,
> + .sdm_din_mask = PLLA_SDM_DIN_MASK,
> + .sdm_ctrl_reg = PLLA_MISC2,
> + .sdm_ctrl_en_mask = PLLA_SDM_EN_MASK,
> + .ext_misc_reg[0] = PLLA_MISC0,
> + .ext_misc_reg[1] = PLLA_MISC1,
> + .ext_misc_reg[2] = PLLA_MISC2,
> + .freq_table = pll_a_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_MDIV_NEW |
> + TEGRA_PLL_HAS_LOCK_ENABLE,
> + .set_defaults = tegra210_plla_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> + .set_gain = tegra210_clk_pll_set_gain,
> + .adjust_vco = tegra210_clk_adjust_vco_min,
> +};
> +
> +static struct div_nmp plld_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 11,
> + .divn_width = 8,
> + .divp_shift = 20,
> + .divp_width = 3,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
> + { 12000000, 594000000, 99, 1, 1},
> + { 13000000, 594000000, 91, 1, 1, 0, 0xfc4f}, /* actual: 594000183 */
> + { 38400000, 594000000, 30, 1, 1, 0, 0x0e00},
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_d_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 38400000,
> + .vco_min = 750000000,
> + .vco_max = 1500000000,
> + .base_reg = PLLD_BASE,
> + .misc_reg = PLLD_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLD_MISC_LOCK_ENABLE,
> + .lock_delay = 1000,
> + .iddq_reg = PLLD_MISC0,
> + .iddq_bit_idx = PLLD_IDDQ_BIT,
> + .round_p_to_pdiv = pll_expo_p_to_pdiv,
> + .pdiv_tohw = pll_expo_pdiv_to_hw,
> + .div_nmp = &plld_nmp,
> + .sdm_din_reg = PLLD_MISC0,
> + .sdm_din_mask = PLLA_SDM_DIN_MASK,
> + .sdm_ctrl_reg = PLLD_MISC0,
> + .sdm_ctrl_en_mask = PLLD_SDM_EN_MASK,
> + .ext_misc_reg[0] = PLLD_MISC0,
> + .ext_misc_reg[1] = PLLD_MISC1,
> + .freq_table = pll_d_freq_table,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .mdiv_default = 1,
> + .set_defaults = tegra210_plld_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> + .set_gain = tegra210_clk_pll_set_gain,
> + .adjust_vco = tegra210_clk_adjust_vco_min,
> +};
> +
> +static struct tegra_clk_pll_freq_table tegra210_pll_d2_freq_table[] = {
> + { 12000000, 594000000, 99, 1, 1, 0, 0xf000},
> + { 13000000, 594000000, 91, 1, 1, 0, 0xfc4f}, /* actual: 594000183 */
> + { 38400000, 594000000, 30, 1, 1, 0, 0x0e00},
> + { 0, 0, 0, 0, 0, 0 },
> +};
> +
> +/* s/w policy, always tegra_pll_ref */
> +static struct tegra_clk_pll_params pll_d2_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 38400000,
> + .vco_min = 750000000,
> + .vco_max = 1500000000,
> + .base_reg = PLLD2_BASE,
> + .misc_reg = PLLD2_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .iddq_reg = PLLD2_BASE,
> + .iddq_bit_idx = PLLSS_IDDQ_BIT,
> + .sdm_din_reg = PLLD2_MISC3,
> + .sdm_din_mask = PLLA_SDM_DIN_MASK,
> + .sdm_ctrl_reg = PLLD2_MISC1,
> + .sdm_ctrl_en_mask = PLLD2_SDM_EN_MASK,
> + .ssc_ctrl_reg = PLLD2_MISC1,
> + .ssc_ctrl_en_mask = PLLD2_SSC_EN_MASK,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllss_nmp,
> + .ext_misc_reg[0] = PLLD2_MISC0,
> + .ext_misc_reg[1] = PLLD2_MISC1,
> + .ext_misc_reg[2] = PLLD2_MISC2,
> + .ext_misc_reg[3] = PLLD2_MISC3,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .mdiv_default = 1,
> + .freq_table = tegra210_pll_d2_freq_table,
> + .set_defaults = tegra210_plld2_set_defaults,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> + .set_gain = tegra210_clk_pll_set_gain,
> + .adjust_vco = tegra210_clk_adjust_vco_min,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = {
> + { 12000000, 270000000, 90, 1, 3, 0, 0xf000},
> + { 13000000, 270000000, 83, 1, 3, 0, 0xf000}, /* actual: 269.8 MHz */
> + { 38400000, 270000000, 28, 1, 3, 0, 0xf400},
> + { 0, 0, 0, 0, 0, 0 },
> +};
> +
> +static struct tegra_clk_pll_params pll_dp_params = {
> + .input_min = 12000000,
> + .input_max = 800000000,
> + .cf_min = 12000000,
> + .cf_max = 38400000,
> + .vco_min = 750000000,
> + .vco_max = 1500000000,
> + .base_reg = PLLDP_BASE,
> + .misc_reg = PLLDP_MISC,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE,
> + .lock_delay = 300,
> + .iddq_reg = PLLDP_BASE,
> + .iddq_bit_idx = PLLSS_IDDQ_BIT,
> + .sdm_din_reg = PLLDP_SS_CTRL2,
> + .sdm_din_mask = PLLA_SDM_DIN_MASK,
> + .sdm_ctrl_reg = PLLDP_SS_CFG,
> + .sdm_ctrl_en_mask = PLLDP_SDM_EN_MASK,
> + .ssc_ctrl_reg = PLLDP_SS_CFG,
> + .ssc_ctrl_en_mask = PLLDP_SSC_EN_MASK,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllss_nmp,
> + .ext_misc_reg[0] = PLLDP_MISC,
> + .ext_misc_reg[1] = PLLDP_SS_CFG,
> + .ext_misc_reg[2] = PLLDP_SS_CTRL1,
> + .ext_misc_reg[3] = PLLDP_SS_CTRL2,
> + .max_p = PLL_QLIN_PDIV_MAX,
> + .mdiv_default = 1,
> + .freq_table = pll_dp_freq_table,
> + .set_defaults = tegra210_plldp_set_defaults,
> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> + .set_gain = tegra210_clk_pll_set_gain,
> + .adjust_vco = tegra210_clk_adjust_vco_min,
> +};
> +
> +static struct div_nmp pllu_nmp = {
> + .divm_shift = 0,
> + .divm_width = 8,
> + .divn_shift = 8,
> + .divn_width = 8,
> + .divp_shift = 16,
> + .divp_width = 5,
> +};
> +
> +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
> + { 12000000, 480000000, 40, 1, 0},
> + { 13000000, 480000000, 36, 1, 0}, /* actual: 468.0 MHz */
> + { 38400000, 480000000, 25, 2, 0},
> + {0, 0, 0, 0, 0, 0},
> +};
> +
> +static struct tegra_clk_pll_params pll_u_params = {
> + .input_min = 9600000,
> + .input_max = 800000000,
> + .cf_min = 9600000,
> + .cf_max = 19200000,
> + .vco_min = 350000000,
> + .vco_max = 700000000,
> + .base_reg = PLLU_BASE,
> + .misc_reg = PLLU_MISC0,
> + .lock_mask = PLL_BASE_LOCK,
> + .lock_enable_bit_idx = PLLU_MISC_LOCK_ENABLE,
> + .lock_delay = 1000,
> + .iddq_reg = PLLU_MISC0,
> + .iddq_bit_idx = PLLU_IDDQ_BIT,
> + .ext_misc_reg[0] = PLLU_MISC0,
> + .ext_misc_reg[1] = PLLU_MISC1,
> + .round_p_to_pdiv = pll_qlin_p_to_pdiv,
> + .pdiv_tohw = pll_qlin_pdiv_to_hw,
> + .div_nmp = &pllu_nmp,
> + .freq_table = pll_u_freq_table,
> + .flags = TEGRA_PLLU | TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
> + .vco_out = true,
> + .set_defaults = tegra210_pllu_set_defaults,
> + .calc_rate = tegra210_pll_fixed_mdiv_cfg,
> +};
> +
> +struct utmi_clk_param {
> + /* Oscillator Frequency in KHz */
> + u32 osc_frequency;
> + /* UTMIP PLL Enable Delay Count */
> + u8 enable_delay_count;
> + /* UTMIP PLL Stable count */
> + u16 stable_count;
> + /* UTMIP PLL Active delay count */
> + u8 active_delay_count;
> + /* UTMIP PLL Xtal frequency count */
> + u16 xtal_freq_count;
> +};
> +
> +static const struct utmi_clk_param utmi_parameters[] = {
> + {.osc_frequency = 38400000, .enable_delay_count = 0x05,
> + .stable_count = 0x96, .active_delay_count = 0x18,
> + .xtal_freq_count = 0x177},
> + {.osc_frequency = 13000000, .enable_delay_count = 0x02,
> + .stable_count = 0x33, .active_delay_count = 0x05,
> + .xtal_freq_count = 0x7F},
> + {.osc_frequency = 19200000, .enable_delay_count = 0x03,
> + .stable_count = 0x4B, .active_delay_count = 0x06,
> + .xtal_freq_count = 0xBB},
> + {.osc_frequency = 12000000, .enable_delay_count = 0x02,
> + .stable_count = 0x2F, .active_delay_count = 0x08,
> + .xtal_freq_count = 0x76},
> + {.osc_frequency = 26000000, .enable_delay_count = 0x04,
> + .stable_count = 0x66, .active_delay_count = 0x09,
> + .xtal_freq_count = 0xFE},
> + {.osc_frequency = 16800000, .enable_delay_count = 0x03,
> + .stable_count = 0x41, .active_delay_count = 0x0A,
> + .xtal_freq_count = 0xA4},
> +};
> +
> +static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
> + [tegra_clk_ispb] = { .dt_id = TEGRA210_CLK_ISPB, .present = true },
> + [tegra_clk_rtc] = { .dt_id = TEGRA210_CLK_RTC, .present = true },
> + [tegra_clk_timer] = { .dt_id = TEGRA210_CLK_TIMER, .present = true },
> + [tegra_clk_uarta_8] = { .dt_id = TEGRA210_CLK_UARTA, .present = true },
> + [tegra_clk_sdmmc2_9] = { .dt_id = TEGRA210_CLK_SDMMC2, .present = true },
> + [tegra_clk_i2s1] = { .dt_id = TEGRA210_CLK_I2S1, .present = true },
> + [tegra_clk_i2c1] = { .dt_id = TEGRA210_CLK_I2C1, .present = true },
> + [tegra_clk_sdmmc1_9] = { .dt_id = TEGRA210_CLK_SDMMC1, .present = true },
> + [tegra_clk_sdmmc4_9] = { .dt_id = TEGRA210_CLK_SDMMC4, .present = true },
> + [tegra_clk_pwm] = { .dt_id = TEGRA210_CLK_PWM, .present = true },
> + [tegra_clk_i2s2] = { .dt_id = TEGRA210_CLK_I2S2, .present = true },
> + [tegra_clk_usbd] = { .dt_id = TEGRA210_CLK_USBD, .present = true },
> + [tegra_clk_isp_9] = { .dt_id = TEGRA210_CLK_ISP, .present = true },
> + [tegra_clk_disp2_8] = { .dt_id = TEGRA210_CLK_DISP2, .present = true },
> + [tegra_clk_disp1_8] = { .dt_id = TEGRA210_CLK_DISP1, .present = true },
> + [tegra_clk_host1x_9] = { .dt_id = TEGRA210_CLK_HOST1X, .present = true },
> + [tegra_clk_i2s0] = { .dt_id = TEGRA210_CLK_I2S0, .present = true },
> + [tegra_clk_apbdma] = { .dt_id = TEGRA210_CLK_APBDMA, .present = true },
> + [tegra_clk_kfuse] = { .dt_id = TEGRA210_CLK_KFUSE, .present = true },
> + [tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .present = true },
> + [tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .present = true },
> + [tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .present = true },
> + [tegra_clk_i2c5] = { .dt_id = TEGRA210_CLK_I2C5, .present = true },
> + [tegra_clk_csi] = { .dt_id = TEGRA210_CLK_CSI, .present = true },
> + [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
> + [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true },
> + [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true },
> + [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true },
> + [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true },
> + [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
> + [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
> + [tegra_clk_i2c3] = { .dt_id = TEGRA210_CLK_I2C3, .present = true },
> + [tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .present = true },
> + [tegra_clk_sdmmc3_9] = { .dt_id = TEGRA210_CLK_SDMMC3, .present = true },
> + [tegra_clk_pcie] = { .dt_id = TEGRA210_CLK_PCIE, .present = true },
> + [tegra_clk_owr_8] = { .dt_id = TEGRA210_CLK_OWR, .present = true },
> + [tegra_clk_afi] = { .dt_id = TEGRA210_CLK_AFI, .present = true },
> + [tegra_clk_csite_8] = { .dt_id = TEGRA210_CLK_CSITE, .present = true },
> + [tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .present = true },
> + [tegra_clk_dtv] = { .dt_id = TEGRA210_CLK_DTV, .present = true },
> + [tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .present = true },
> + [tegra_clk_tsec_8] = { .dt_id = TEGRA210_CLK_TSEC, .present = true },
> + [tegra_clk_xusb_host] = { .dt_id = TEGRA210_CLK_XUSB_HOST, .present = true },
> + [tegra_clk_csus] = { .dt_id = TEGRA210_CLK_CSUS, .present = true },
> + [tegra_clk_mselect] = { .dt_id = TEGRA210_CLK_MSELECT, .present = true },
> + [tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .present = true },
> + [tegra_clk_i2s3] = { .dt_id = TEGRA210_CLK_I2S3, .present = true },
> + [tegra_clk_i2s4] = { .dt_id = TEGRA210_CLK_I2S4, .present = true },
> + [tegra_clk_i2c4] = { .dt_id = TEGRA210_CLK_I2C4, .present = true },
> + [tegra_clk_d_audio] = { .dt_id = TEGRA210_CLK_D_AUDIO, .present = true },
> + [tegra_clk_hda2codec_2x_8] = { .dt_id = TEGRA210_CLK_HDA2CODEC_2X, .present = true },
> + [tegra_clk_spdif_2x] = { .dt_id = TEGRA210_CLK_SPDIF_2X, .present = true },
> + [tegra_clk_actmon] = { .dt_id = TEGRA210_CLK_ACTMON, .present = true },
> + [tegra_clk_extern1] = { .dt_id = TEGRA210_CLK_EXTERN1, .present = true },
> + [tegra_clk_extern2] = { .dt_id = TEGRA210_CLK_EXTERN2, .present = true },
> + [tegra_clk_extern3] = { .dt_id = TEGRA210_CLK_EXTERN3, .present = true },
> + [tegra_clk_sata_oob_8] = { .dt_id = TEGRA210_CLK_SATA_OOB, .present = true },
> + [tegra_clk_sata_8] = { .dt_id = TEGRA210_CLK_SATA, .present = true },
> + [tegra_clk_hda_8] = { .dt_id = TEGRA210_CLK_HDA, .present = true },
> + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA210_CLK_HDA2HDMI, .present = true },
> + [tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .present = true },
> + [tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .present = true },
> + [tegra_clk_cile] = { .dt_id = TEGRA210_CLK_CILE, .present = true },
> + [tegra_clk_dsialp] = { .dt_id = TEGRA210_CLK_DSIALP, .present = true },
> + [tegra_clk_dsiblp] = { .dt_id = TEGRA210_CLK_DSIBLP, .present = true },
> + [tegra_clk_entropy_8] = { .dt_id = TEGRA210_CLK_ENTROPY, .present = true },
> + [tegra_clk_xusb_ss] = { .dt_id = TEGRA210_CLK_XUSB_SS, .present = true },
> + [tegra_clk_i2c6] = { .dt_id = TEGRA210_CLK_I2C6, .present = true },
> + [tegra_clk_vim2_clk] = { .dt_id = TEGRA210_CLK_VIM2_CLK, .present = true },
> + [tegra_clk_clk72Mhz] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true },
> + [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true },
> + [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true },
> + [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true },
> + [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true },
> + [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
> + [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, },
> + [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true },
> + [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true },
> + [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true },
> + [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true },
> + [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true },
> + [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR, .present = true },
> + [tegra_clk_fuse] = { .dt_id = TEGRA210_CLK_FUSE, .present = true },
> + [tegra_clk_fuse_burn] = { .dt_id = TEGRA210_CLK_FUSE_BURN, .present = true },
> + [tegra_clk_clk_32k] = { .dt_id = TEGRA210_CLK_CLK_32K, .present = true },
> + [tegra_clk_clk_m] = { .dt_id = TEGRA210_CLK_CLK_M, .present = true },
> + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA210_CLK_CLK_M_DIV2, .present = true },
> + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA210_CLK_CLK_M_DIV4, .present = true },
> + [tegra_clk_pll_ref] = { .dt_id = TEGRA210_CLK_PLL_REF, .present = true },
> + [tegra_clk_pll_c] = { .dt_id = TEGRA210_CLK_PLL_C, .present = true },
> + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA210_CLK_PLL_C_OUT1, .present = true },
> + [tegra_clk_pll_c2] = { .dt_id = TEGRA210_CLK_PLL_C2, .present = true },
> + [tegra_clk_pll_c3] = { .dt_id = TEGRA210_CLK_PLL_C3, .present = true },
> + [tegra_clk_pll_m] = { .dt_id = TEGRA210_CLK_PLL_M, .present = true },
> + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA210_CLK_PLL_M_OUT1, .present = true },
> + [tegra_clk_pll_p] = { .dt_id = TEGRA210_CLK_PLL_P, .present = true },
> + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA210_CLK_PLL_P_OUT1, .present = true },
> + [tegra_clk_pll_p_out2] = { .dt_id = TEGRA210_CLK_PLL_P_OUT2, .present = true },
> + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA210_CLK_PLL_P_OUT3, .present = true },
> + [tegra_clk_pll_p_out4] = { .dt_id = TEGRA210_CLK_PLL_P_OUT4, .present = true },
> + [tegra_clk_pll_a] = { .dt_id = TEGRA210_CLK_PLL_A, .present = true },
> + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA210_CLK_PLL_A_OUT0, .present = true },
> + [tegra_clk_pll_d] = { .dt_id = TEGRA210_CLK_PLL_D, .present = true },
> + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA210_CLK_PLL_D_OUT0, .present = true },
> + [tegra_clk_pll_d2] = { .dt_id = TEGRA210_CLK_PLL_D2, .present = true },
> + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA210_CLK_PLL_D2_OUT0, .present = true },
> + [tegra_clk_pll_u] = { .dt_id = TEGRA210_CLK_PLL_U, .present = true },
> + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA210_CLK_PLL_U_480M, .present = true },
> + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA210_CLK_PLL_U_60M, .present = true },
> + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA210_CLK_PLL_U_48M, .present = true },
> + [tegra_clk_pll_u_12m] = { .dt_id = TEGRA210_CLK_PLL_U_12M, .present = true },
> + [tegra_clk_pll_x] = { .dt_id = TEGRA210_CLK_PLL_X, .present = true },
> + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA210_CLK_PLL_X_OUT0, .present = true },
> + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA210_CLK_PLL_RE_VCO, .present = true },
> + [tegra_clk_pll_re_out] = { .dt_id = TEGRA210_CLK_PLL_RE_OUT, .present = true },
> + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC, .present = true },
> + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA210_CLK_I2S0_SYNC, .present = true },
> + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA210_CLK_I2S1_SYNC, .present = true },
> + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA210_CLK_I2S2_SYNC, .present = true },
> + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA210_CLK_I2S3_SYNC, .present = true },
> + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA210_CLK_I2S4_SYNC, .present = true },
> + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA210_CLK_VIMCLK_SYNC, .present = true },
> + [tegra_clk_audio0] = { .dt_id = TEGRA210_CLK_AUDIO0, .present = true },
> + [tegra_clk_audio1] = { .dt_id = TEGRA210_CLK_AUDIO1, .present = true },
> + [tegra_clk_audio2] = { .dt_id = TEGRA210_CLK_AUDIO2, .present = true },
> + [tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true },
> + [tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true },
> + [tegra_clk_spdif] = { .dt_id = TEGRA210_CLK_SPDIF, .present = true },
> + [tegra_clk_clk_out_1] = { .dt_id = TEGRA210_CLK_CLK_OUT_1, .present = true },
> + [tegra_clk_clk_out_2] = { .dt_id = TEGRA210_CLK_CLK_OUT_2, .present = true },
> + [tegra_clk_clk_out_3] = { .dt_id = TEGRA210_CLK_CLK_OUT_3, .present = true },
> + [tegra_clk_blink] = { .dt_id = TEGRA210_CLK_BLINK, .present = true },
> + [tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true },
> + [tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true },
> + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA210_CLK_XUSB_FS_SRC, .present = true },
> + [tegra_clk_xusb_ss_src_8] = { .dt_id = TEGRA210_CLK_XUSB_SS_SRC, .present = true },
> + [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA210_CLK_XUSB_SS_DIV2, .present = true },
> + [tegra_clk_xusb_dev_src_8] = { .dt_id = TEGRA210_CLK_XUSB_DEV_SRC, .present = true },
> + [tegra_clk_xusb_dev] = { .dt_id = TEGRA210_CLK_XUSB_DEV, .present = true },
> + [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA210_CLK_XUSB_HS_SRC, .present = true },
> + [tegra_clk_sclk] = { .dt_id = TEGRA210_CLK_SCLK, .present = true },
> + [tegra_clk_sclk_mux] = { .dt_id = TEGRA210_CLK_SCLK_MUX, .present = true },
> + [tegra_clk_hclk] = { .dt_id = TEGRA210_CLK_HCLK, .present = true },
> + [tegra_clk_pclk] = { .dt_id = TEGRA210_CLK_PCLK, .present = true },
> + [tegra_clk_cclk_g] = { .dt_id = TEGRA210_CLK_CCLK_G, .present = true },
> + [tegra_clk_cclk_lp] = { .dt_id = TEGRA210_CLK_CCLK_LP, .present = true },
> + [tegra_clk_dfll_ref] = { .dt_id = TEGRA210_CLK_DFLL_REF, .present = true },
> + [tegra_clk_dfll_soc] = { .dt_id = TEGRA210_CLK_DFLL_SOC, .present = true },
> + [tegra_clk_vi_sensor2_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR2, .present = true },
> + [tegra_clk_pll_p_out5] = { .dt_id = TEGRA210_CLK_PLL_P_OUT5, .present = true },
> + [tegra_clk_pll_c4] = { .dt_id = TEGRA210_CLK_PLL_C4, .present = true },
> + [tegra_clk_pll_dp] = { .dt_id = TEGRA210_CLK_PLL_DP, .present = true },
> + [tegra_clk_audio0_mux] = { .dt_id = TEGRA210_CLK_AUDIO0_MUX, .present = true },
> + [tegra_clk_audio1_mux] = { .dt_id = TEGRA210_CLK_AUDIO1_MUX, .present = true },
> + [tegra_clk_audio2_mux] = { .dt_id = TEGRA210_CLK_AUDIO2_MUX, .present = true },
> + [tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true },
> + [tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true },
> + [tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true },
> + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_1_MUX, .present = true },
> + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_2_MUX, .present = true },
> + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_3_MUX, .present = true },
> + [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true },
> + [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true },
> + [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true },
> + [tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .present = true },
> + [tegra_clk_tsecb] = { .dt_id = TEGRA210_CLK_TSECB, .present = true },
> + [tegra_clk_uartape] = { .dt_id = TEGRA210_CLK_UARTAPE, .present = true },
> + [tegra_clk_vi_i2c] = { .dt_id = TEGRA210_CLK_VI_I2C, .present = true },
> + [tegra_clk_ape] = { .dt_id = TEGRA210_CLK_APE, .present = true },
> + [tegra_clk_dbgapb] = { .dt_id = TEGRA210_CLK_DBGAPB, .present = true },
> + [tegra_clk_nvdec] = { .dt_id = TEGRA210_CLK_NVDEC, .present = true },
> + [tegra_clk_nvenc] = { .dt_id = TEGRA210_CLK_NVENC, .present = true },
> + [tegra_clk_nvjpg] = { .dt_id = TEGRA210_CLK_NVJPG, .present = true },
> + [tegra_clk_pll_c4_out0] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT0, .present = true },
> + [tegra_clk_pll_c4_out1] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT1, .present = true },
> + [tegra_clk_pll_c4_out2] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT2, .present = true },
> + [tegra_clk_pll_c4_out3] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT3, .present = true },
> +};
> +
> +static struct tegra_devclk devclks[] __initdata = {
> + { .con_id = "clk_m", .dt_id = TEGRA210_CLK_CLK_M },
> + { .con_id = "pll_ref", .dt_id = TEGRA210_CLK_PLL_REF },
> + { .con_id = "clk_32k", .dt_id = TEGRA210_CLK_CLK_32K },
> + { .con_id = "clk_m_div2", .dt_id = TEGRA210_CLK_CLK_M_DIV2 },
> + { .con_id = "clk_m_div4", .dt_id = TEGRA210_CLK_CLK_M_DIV4 },
> + { .con_id = "pll_c", .dt_id = TEGRA210_CLK_PLL_C },
> + { .con_id = "pll_c_out1", .dt_id = TEGRA210_CLK_PLL_C_OUT1 },
> + { .con_id = "pll_c2", .dt_id = TEGRA210_CLK_PLL_C2 },
> + { .con_id = "pll_c3", .dt_id = TEGRA210_CLK_PLL_C3 },
> + { .con_id = "pll_p", .dt_id = TEGRA210_CLK_PLL_P },
> + { .con_id = "pll_p_out1", .dt_id = TEGRA210_CLK_PLL_P_OUT1 },
> + { .con_id = "pll_p_out2", .dt_id = TEGRA210_CLK_PLL_P_OUT2 },
> + { .con_id = "pll_p_out3", .dt_id = TEGRA210_CLK_PLL_P_OUT3 },
> + { .con_id = "pll_p_out4", .dt_id = TEGRA210_CLK_PLL_P_OUT4 },
> + { .con_id = "pll_m", .dt_id = TEGRA210_CLK_PLL_M },
> + { .con_id = "pll_m_out1", .dt_id = TEGRA210_CLK_PLL_M_OUT1 },
> + { .con_id = "pll_x", .dt_id = TEGRA210_CLK_PLL_X },
> + { .con_id = "pll_x_out0", .dt_id = TEGRA210_CLK_PLL_X_OUT0 },
> + { .con_id = "pll_u", .dt_id = TEGRA210_CLK_PLL_U },
> + { .con_id = "pll_u_480M", .dt_id = TEGRA210_CLK_PLL_U_480M },
> + { .con_id = "pll_u_60M", .dt_id = TEGRA210_CLK_PLL_U_60M },
> + { .con_id = "pll_u_48M", .dt_id = TEGRA210_CLK_PLL_U_48M },
> + { .con_id = "pll_u_12M", .dt_id = TEGRA210_CLK_PLL_U_12M },
> + { .con_id = "pll_d", .dt_id = TEGRA210_CLK_PLL_D },
> + { .con_id = "pll_d_out0", .dt_id = TEGRA210_CLK_PLL_D_OUT0 },
> + { .con_id = "pll_d2", .dt_id = TEGRA210_CLK_PLL_D2 },
> + { .con_id = "pll_d2_out0", .dt_id = TEGRA210_CLK_PLL_D2_OUT0 },
> + { .con_id = "pll_a", .dt_id = TEGRA210_CLK_PLL_A },
> + { .con_id = "pll_a_out0", .dt_id = TEGRA210_CLK_PLL_A_OUT0 },
> + { .con_id = "pll_re_vco", .dt_id = TEGRA210_CLK_PLL_RE_VCO },
> + { .con_id = "pll_re_out", .dt_id = TEGRA210_CLK_PLL_RE_OUT },
> + { .con_id = "spdif_in_sync", .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC },
> + { .con_id = "i2s0_sync", .dt_id = TEGRA210_CLK_I2S0_SYNC },
> + { .con_id = "i2s1_sync", .dt_id = TEGRA210_CLK_I2S1_SYNC },
> + { .con_id = "i2s2_sync", .dt_id = TEGRA210_CLK_I2S2_SYNC },
> + { .con_id = "i2s3_sync", .dt_id = TEGRA210_CLK_I2S3_SYNC },
> + { .con_id = "i2s4_sync", .dt_id = TEGRA210_CLK_I2S4_SYNC },
> + { .con_id = "vimclk_sync", .dt_id = TEGRA210_CLK_VIMCLK_SYNC },
> + { .con_id = "audio0", .dt_id = TEGRA210_CLK_AUDIO0 },
> + { .con_id = "audio1", .dt_id = TEGRA210_CLK_AUDIO1 },
> + { .con_id = "audio2", .dt_id = TEGRA210_CLK_AUDIO2 },
> + { .con_id = "audio3", .dt_id = TEGRA210_CLK_AUDIO3 },
> + { .con_id = "audio4", .dt_id = TEGRA210_CLK_AUDIO4 },
> + { .con_id = "spdif", .dt_id = TEGRA210_CLK_SPDIF },
> + { .con_id = "spdif_2x", .dt_id = TEGRA210_CLK_SPDIF_2X },
> + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA210_CLK_EXTERN1 },
> + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA210_CLK_EXTERN2 },
> + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA210_CLK_EXTERN3 },
> + { .con_id = "blink", .dt_id = TEGRA210_CLK_BLINK },
> + { .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G },
> + { .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP },
> + { .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK },
> + { .con_id = "hclk", .dt_id = TEGRA210_CLK_HCLK },
> + { .con_id = "pclk", .dt_id = TEGRA210_CLK_PCLK },
> + { .con_id = "fuse", .dt_id = TEGRA210_CLK_FUSE },
> + { .dev_id = "rtc-tegra", .dt_id = TEGRA210_CLK_RTC },
> + { .dev_id = "timer", .dt_id = TEGRA210_CLK_TIMER },
> + { .con_id = "pll_c4_out0", .dt_id = TEGRA210_CLK_PLL_C4_OUT0 },
> + { .con_id = "pll_c4_out1", .dt_id = TEGRA210_CLK_PLL_C4_OUT1 },
> + { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 },
> + { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 },
> + { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX },
> + { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 },
> +};
> +
> +static struct tegra_audio_clk_info tegra210_audio_plls[] = {
> + { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_ref" },
> + { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" },
> +};
> +
> +static struct clk **clks;
> +
> +static void tegra210_utmi_param_configure(void __iomem *clk_base)
> +{
> + u32 reg;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
> + if (osc_freq == utmi_parameters[i].osc_frequency)
> + break;
> + }
> +
> + if (i >= ARRAY_SIZE(utmi_parameters)) {
> + pr_err("%s: Unexpected oscillator freq %lu\n", __func__,
> + osc_freq);
> + return;
> + }
> +
> + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
> +
> + /* Program UTMIP PLL stable and active counts */
> + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
> + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
> + reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count);
> +
> + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
> +
> + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].
> + active_delay_count);
> +
> + /* Remove power downs from UTMIP PLL control bits */
> + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
> + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
> + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
> +
> + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
> +
> + /* Program UTMIP PLL delay and oscillator frequency counts */
> + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
> + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
> +
> + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].
> + enable_delay_count);
> +
> + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
> + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i].
> + xtal_freq_count);
> +
> + /* Remove power downs from UTMIP PLL control bits */
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP;
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
> + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
> +
> + /* Setup HW control of UTMIPLL */
> + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
> + reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET;
> + reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL;
> + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE;
> + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
> +
> + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
> + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
> + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
> +
> + udelay(1);
> +
> + /* Setup SW override of UTMIPLL assuming USB2.0
> + ports are assigned to USB2 */
> + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
> + reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL;
> + reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
> + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
> +
> + udelay(1);
> +
> + /* Enable HW control UTMIPLL */
> + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
> + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE;
> + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
> +}
> +
> +static __init void tegra210_periph_clk_init(void __iomem *clk_base,
> + void __iomem *pmc_base)
> +{
> + struct clk *clk;
> +
> + /* xusb_ss_div2 */
> + clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
> + 1, 2);
> + clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk;
> +
> + /* plld_dsi */
> + clk = clk_register_gate(NULL, "pll_d_dsi", "pll_d_out0", 0,
> + clk_base + PLLD_MISC0, 21, 0, &pll_d_lock);
> + clks[TEGRA210_CLK_PLLD_DSI] = clk;
> +
> + /* dsia */
> + clk = tegra_clk_register_periph_gate("dsia", "pll_d_dsi", 0, clk_base,
> + 0, 48, periph_clk_enb_refcnt);
> + clks[TEGRA210_CLK_DSIA] = clk;
> +
> + /* dsib */
> + clk = tegra_clk_register_periph_gate("dsib", "pll_d_dsi", 0, clk_base,
> + 0, 82, periph_clk_enb_refcnt);
> + clks[TEGRA210_CLK_DSIB] = clk;
> +
> + /* emc mux */
> + clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
> + ARRAY_SIZE(mux_pllmcp_clkm), 0,
> + clk_base + CLK_SOURCE_EMC,
> + 29, 3, 0, &emc_lock);
> +
> + clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
> + &emc_lock);
> + clks[TEGRA210_CLK_MC] = clk;
> +
> + /* cml0 */
> + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
> + 0, 0, &pll_e_lock);
> + clk_register_clkdev(clk, "cml0", NULL);
> + clks[TEGRA210_CLK_CML0] = clk;
> +
> + /* cml1 */
> + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX,
> + 1, 0, &pll_e_lock);
> + clk_register_clkdev(clk, "cml1", NULL);
> + clks[TEGRA210_CLK_CML1] = clk;
> +
> + tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
> +}
> +
> +static void __init tegra210_pll_init(void __iomem *clk_base,
> + void __iomem *pmc)
> +{
> + u32 val;
> + struct clk *clk;
> +
> + /* PLLC */
> + clk = tegra_clk_register_pllxc_tegra210("pll_c", "pll_ref", clk_base,
> + pmc, 0, &pll_c_params, NULL);
> + if (!WARN_ON(IS_ERR(clk)))
> + clk_register_clkdev(clk, "pll_c", NULL);
> + clks[TEGRA210_CLK_PLL_C] = clk;
> +
> + /* PLLC_OUT1 */
> + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
> + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
> + 8, 8, 1, NULL);
> + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
> + clk_base + PLLC_OUT, 1, 0,
> + CLK_SET_RATE_PARENT, 0, NULL);
> + clk_register_clkdev(clk, "pll_c_out1", NULL);
> + clks[TEGRA210_CLK_PLL_C_OUT1] = clk;
> +
> + /* PLLC_UD */
> + clk = clk_register_fixed_factor(NULL, "pll_c_ud", "pll_c",
> + CLK_SET_RATE_PARENT, 1, 1);
> + clk_register_clkdev(clk, "pll_c_ud", NULL);
> + clks[TEGRA210_CLK_PLL_C_UD] = clk;
> +
> + /* PLLC2 */
> + clk = tegra_clk_register_pllc_tegra210("pll_c2", "pll_ref", clk_base,
> + pmc, 0, &pll_c2_params, NULL);
> + clk_register_clkdev(clk, "pll_c2", NULL);
> + clks[TEGRA210_CLK_PLL_C2] = clk;
> +
> + /* PLLC3 */
> + clk = tegra_clk_register_pllc_tegra210("pll_c3", "pll_ref", clk_base,
> + pmc, 0, &pll_c3_params, NULL);
> + clk_register_clkdev(clk, "pll_c3", NULL);
> + clks[TEGRA210_CLK_PLL_C3] = clk;
> +
> + /* PLLM */
> + clk = tegra_clk_register_pllm("pll_m", "osc", clk_base, pmc,
> + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
> + &pll_m_params, NULL);
> + clk_register_clkdev(clk, "pll_m", NULL);
> + clks[TEGRA210_CLK_PLL_M] = clk;
> +
> + /* PLLMB */
> + clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base, pmc,
> + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
> + &pll_mb_params, NULL);
> + clk_register_clkdev(clk, "pll_mb", NULL);
> + clks[TEGRA210_CLK_PLL_MB] = clk;
> +
> + clk_register_clkdev(clk, "pll_m_out1", NULL);
> + clks[TEGRA210_CLK_PLL_M_OUT1] = clk;
> +
> + /* PLLM_UD */
> + clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m",
> + CLK_SET_RATE_PARENT, 1, 1);
> + clk_register_clkdev(clk, "pll_m_ud", NULL);
> + clks[TEGRA210_CLK_PLL_M_UD] = clk;
> +
> + /* PLLU */
> + val = readl(clk_base + pll_u_params.base_reg);
> + val &= ~BIT(24); /* disable PLLU_OVERRIDE */
> + writel(val, clk_base + pll_u_params.base_reg);
> +
> + clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0,
> + &pll_u_params, &pll_u_lock);
> + clk_register_clkdev(clk, "pll_u", NULL);
> + clks[TEGRA210_CLK_PLL_U] = clk;
> +
> + tegra210_utmi_param_configure(clk_base);
> +
> + /* PLLU_480M */
> + clk = clk_register_gate(NULL, "pll_u_480M", "pll_u",
> + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
> + 22, 0, &pll_u_lock);
> + clk_register_clkdev(clk, "pll_u_480M", NULL);
> + clks[TEGRA210_CLK_PLL_U_480M] = clk;
> +
> + /* PLLU_60M */
> + clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u",
> + CLK_SET_RATE_PARENT, 1, 8);
> + clk_register_clkdev(clk, "pll_u_60M", NULL);
> + clks[TEGRA210_CLK_PLL_U_60M] = clk;
> +
> + /* PLLU_48M */
> + clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u",
> + CLK_SET_RATE_PARENT, 1, 10);
> + clk_register_clkdev(clk, "pll_u_48M", NULL);
> + clks[TEGRA210_CLK_PLL_U_48M] = clk;
> +
> + /* PLLU_12M */
> + clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u",
> + CLK_SET_RATE_PARENT, 1, 40);
> + clk_register_clkdev(clk, "pll_u_12M", NULL);
> + clks[TEGRA210_CLK_PLL_U_12M] = clk;
> +
> + /* PLLD */
> + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
> + &pll_d_params, &pll_d_lock);
> + clk_register_clkdev(clk, "pll_d", NULL);
> + clks[TEGRA210_CLK_PLL_D] = clk;
> +
> + /* PLLD_OUT0 */
> + clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
> + CLK_SET_RATE_PARENT, 1, 2);
> + clk_register_clkdev(clk, "pll_d_out0", NULL);
> + clks[TEGRA210_CLK_PLL_D_OUT0] = clk;
> +
> + /* PLLRE */
> + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
> + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
> + clk_register_clkdev(clk, "pll_re_vco", NULL);
> + clks[TEGRA210_CLK_PLL_RE_VCO] = clk;
> +
> + clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0,
> + clk_base + PLLRE_BASE, 16, 5, 0,
> + pll_re_c4_div_table, &pll_re_lock);
> + clk_register_clkdev(clk, "pll_re_out", NULL);
> + clks[TEGRA210_CLK_PLL_RE_OUT] = clk;
> +
> + /* PLLE */
> + clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref",
> + clk_base, 0, &pll_e_params, NULL);
> + clk_register_clkdev(clk, "pll_e", NULL);
> + clks[TEGRA210_CLK_PLL_E] = clk;
> +
> + /* PLLC4 */
> + clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc,
> + 0, &pll_c4_vco_params, NULL, pll_ref_freq);
> + clk_register_clkdev(clk, "pll_c4_vco", NULL);
> + clks[TEGRA210_CLK_PLL_C4] = clk;
> +
> + /* PLLC4_OUT0 */
> + clk = clk_register_divider_table(NULL, "pll_c4_out0", "pll_c4_vco", 0,
> + clk_base + PLLC4_BASE, 19, 4, 0,
> + pll_re_c4_div_table, NULL);
> + clk_register_clkdev(clk, "pll_c4_out0", NULL);
> + clks[TEGRA210_CLK_PLL_C4_OUT0] = clk;
> +
> + /* PLLC4_OUT1 */
> + clk = clk_register_fixed_factor(NULL, "pll_c4_out1", "pll_c4_vco",
> + CLK_SET_RATE_PARENT, 1, 3);
> + clk_register_clkdev(clk, "pll_c4_out1", NULL);
> + clks[TEGRA210_CLK_PLL_C4_OUT1] = clk;
> +
> + /* PLLC4_OUT2 */
> + clk = clk_register_fixed_factor(NULL, "pll_c4_out2", "pll_c4_vco",
> + CLK_SET_RATE_PARENT, 1, 5);
> + clk_register_clkdev(clk, "pll_c4_out2", NULL);
> + clks[TEGRA210_CLK_PLL_C4_OUT2] = clk;
> +
> + /* PLLC4_OUT3 */
> + clk = tegra_clk_register_divider("pll_c4_out3_div", "pll_c4_out0",
> + clk_base + PLLC4_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
> + 8, 8, 1, NULL);
> + clk = tegra_clk_register_pll_out("pll_c4_out3", "pll_c4_out3_div",
> + clk_base + PLLC4_OUT, 1, 0,
> + CLK_SET_RATE_PARENT, 0, NULL);
> + clk_register_clkdev(clk, "pll_c4_out3", NULL);
> + clks[TEGRA210_CLK_PLL_C4_OUT3] = clk;
> +
> + /* PLLDP */
> + clk = tegra_clk_register_pllss_tegra210("pll_dp", "pll_ref", clk_base,
> + 0, &pll_dp_params, NULL);
> + clk_register_clkdev(clk, "pll_dp", NULL);
> + clks[TEGRA210_CLK_PLL_DP] = clk;
> +
> + /* PLLD2 */
> + clk = tegra_clk_register_pllss_tegra210("pll_d2", "pll_ref", clk_base,
> + 0, &pll_d2_params, NULL);
> + clk_register_clkdev(clk, "pll_d2", NULL);
> + clks[TEGRA210_CLK_PLL_D2] = clk;
> +
> + /* PLLD2_OUT0 */
> + clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2",
> + CLK_SET_RATE_PARENT, 1, 1);
> + clk_register_clkdev(clk, "pll_d2_out0", NULL);
> + clks[TEGRA210_CLK_PLL_D2_OUT0] = clk;
> +
> +}
> +
> +/* Tegra210 CPU clock and reset control functions */
> +static void tegra210_wait_cpu_in_reset(u32 cpu)
> +{
> + unsigned int reg;
> +
> + do {
> + reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
> + cpu_relax();
> + } while (!(reg & (1 << cpu))); /* check CPU been reset or not */
> +}
> +
> +static void tegra210_disable_cpu_clock(u32 cpu)
> +{
> + /* flow controller would take care in the power sequence. */
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static void tegra210_cpu_clock_suspend(void)
> +{
> + /* switch coresite to clk_m, save off original source */
> + tegra210_cpu_clk_sctx.clk_csite_src =
> + readl(clk_base + CLK_SOURCE_CSITE);
> + writel(3 << 30, clk_base + CLK_SOURCE_CSITE);
> +}
> +
> +static void tegra210_cpu_clock_resume(void)
> +{
> + writel(tegra210_cpu_clk_sctx.clk_csite_src,
> + clk_base + CLK_SOURCE_CSITE);
> +}
> +#endif
> +
> +static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
> + .wait_for_reset = tegra210_wait_cpu_in_reset,
> + .disable_clock = tegra210_disable_cpu_clock,
> +#ifdef CONFIG_PM_SLEEP
> + .suspend = tegra210_cpu_clock_suspend,
> + .resume = tegra210_cpu_clock_resume,
> +#endif
> +};
> +
> +static const struct of_device_id pmc_match[] __initconst = {
> + { .compatible = "nvidia,tegra210-pmc" },
> + {},
> +};
> +
> +static struct tegra_clk_init_table common_init_table[] __initdata = {
> + {TEGRA210_CLK_UARTA, TEGRA210_CLK_PLL_P, 408000000, 0},
> + {TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0},
> + {TEGRA210_CLK_UARTC, TEGRA210_CLK_PLL_P, 408000000, 0},
> + {TEGRA210_CLK_UARTD, TEGRA210_CLK_PLL_P, 408000000, 0},
> + {TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1},
> + {TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 1},
> + {TEGRA210_CLK_EXTERN1, TEGRA210_CLK_PLL_A_OUT0, 0, 1},
> + {TEGRA210_CLK_CLK_OUT_1_MUX, TEGRA210_CLK_EXTERN1, 0, 1},
> + {TEGRA210_CLK_CLK_OUT_1, TEGRA210_CLK_CLK_MAX, 0, 1},
> + {TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0},
> + {TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0},
> + {TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0},
> + {TEGRA210_CLK_I2S3, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0},
> + {TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0},
> + {TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1},
> + {TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1},
> + {TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1},
> + {TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1},
> + {TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1},
> + {TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1},
> + {TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 624000000, 0},
> + {TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0},
> + {TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0},
> + {TEGRA210_CLK_XUSB_HS_SRC, TEGRA210_CLK_PLL_U_60M, 60000000, 0},
> + {TEGRA210_CLK_XUSB_FALCON_SRC, TEGRA210_CLK_PLL_RE_OUT, 224000000, 0},
> + {TEGRA210_CLK_XUSB_HOST_SRC, TEGRA210_CLK_PLL_RE_OUT, 112000000, 0},
> + {TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0},
> + {TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0},
> + {TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1},
> + {TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1},
> + {TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1},
> + {TEGRA210_CLK_TSENSOR, TEGRA210_CLK_CLK_M, 400000, 0},
> + {TEGRA210_CLK_I2C1, TEGRA210_CLK_PLL_P, 0, 0},
> + {TEGRA210_CLK_I2C2, TEGRA210_CLK_PLL_P, 0, 0},
> + {TEGRA210_CLK_I2C3, TEGRA210_CLK_PLL_P, 0, 0},
> + {TEGRA210_CLK_I2C4, TEGRA210_CLK_PLL_P, 0, 0},
> + {TEGRA210_CLK_I2C5, TEGRA210_CLK_PLL_P, 0, 0},
> + {TEGRA210_CLK_I2C6, TEGRA210_CLK_PLL_P, 0, 0},
> + /* This MUST be the last entry. */
> + {TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0},
> +};
> +
> +static struct tegra_clk_init_table tegra210_init_table[] __initdata = {
> + {TEGRA210_CLK_SOC_THERM, TEGRA210_CLK_PLL_P, 51000000, 0},
> + {TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1},
> + /* This MUST be the last entry. */
> + {TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0},
> +};
> +
> +/**
> + * tegra210_clock_apply_init_table - initialize clocks on Tegra210 SoCs
> + *
> + * Program an initial clock rate and enable or disable clocks needed
> + * by the rest of the kernel, for Tegra210 SoCs. It is intended to be
> + * called by assigning a pointer to it to tegra_clk_apply_init_table -
> + * this will be called as an arch_initcall. No return value.
> + */
> +static void __init tegra210_clock_apply_init_table(void)
> +{
> + tegra_init_from_table(common_init_table, clks, TEGRA210_CLK_CLK_MAX);
> + tegra_init_from_table(tegra210_init_table, clks, TEGRA210_CLK_CLK_MAX);
> +}
> +
> +/**
> + * tegra210_clock_init - Tegra210-specific clock initialization
> + * @np: struct device_node * of the DT node for the SoC CAR IP block
> + *
> + * Register most SoC clocks for the Tegra210 system-on-chip. Intended
> + * to be called by the OF init code when a DT node with the
> + * "nvidia,tegra210-car" string is encountered, and declared with
> + * CLK_OF_DECLARE. No return value.
> + */
> +static void __init tegra210_clock_init(struct device_node *np)
> +{
> + struct device_node *node;
> + u32 value, clk_m_div;
> +
> + clk_base = of_iomap(np, 0);
> + if (!clk_base) {
> + pr_err("ioremap tegra210 CAR failed\n");
> + return;
> + }
> +
> + node = of_find_matching_node(NULL, pmc_match);
> + if (!node) {
> + pr_err("Failed to find pmc node\n");
> + WARN_ON(1);
> + return;
> + }
> +
> + pmc_base = of_iomap(node, 0);
> + if (!pmc_base) {
> + pr_err("Can't map pmc registers\n");
> + WARN_ON(1);
> + return;
> + }
> +
> + clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
> + TEGRA210_CAR_BANK_COUNT);
> + if (!clks)
> + return;
> +
> + value = clk_readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT;
> + clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1;
> +
> + if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq,
> + ARRAY_SIZE(tegra210_input_freq), clk_m_div,
> + &osc_freq, &pll_ref_freq) < 0)
> + return;
> +
> + tegra_fixed_clk_init(tegra210_clks);
> + tegra210_pll_init(clk_base, pmc_base);
> + tegra210_periph_clk_init(clk_base, pmc_base);
> + tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
> + tegra210_audio_plls, 2);
> + tegra_pmc_clk_init(pmc_base, tegra210_clks);
> +
> + /* For Tegra210, PLLD is the only source for DSIA & DSIB */
> + value = clk_readl(clk_base + PLLD_BASE);
> + value &= ~BIT(25);
> + clk_writel(value, clk_base + PLLD_BASE);
> +
> + tegra_clk_apply_init_table = tegra210_clock_apply_init_table;
> +
> + tegra_super_clk_gen5_init(clk_base, pmc_base, tegra210_clks,
> + &pll_x_params);
> + tegra_add_of_provider(np);
> + tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
> +
> + tegra_cpu_car_ops = &tegra210_cpu_car_ops;
> +}
> +CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
> diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
> new file mode 100644
> index 000000000000..53ad876d9fc3
> --- /dev/null
> +++ b/include/dt-bindings/clock/tegra210-car.h
> @@ -0,0 +1,401 @@
> +/*
> + * This header provides constants for binding nvidia,tegra210-car.
> + *
> + * The first 224 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
> + * registers. These IDs often match those in the CAR's RST_DEVICES registers,
> + * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
> + * this case, those clocks are assigned IDs above 224 in order to highlight
> + * this issue. Implementations that interpret these clock IDs as bit values
> + * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
> + * explicitly handle these special cases.
> + *
> + * The balance of the clocks controlled by the CAR are assigned IDs of 224 and
> + * above.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_TEGRA210_CAR_H
> +#define _DT_BINDINGS_CLOCK_TEGRA210_CAR_H
> +
> +/* 0 */
> +/* 1 */
> +/* 2 */
> +#define TEGRA210_CLK_ISPB 3
> +#define TEGRA210_CLK_RTC 4
> +#define TEGRA210_CLK_TIMER 5
> +#define TEGRA210_CLK_UARTA 6
> +/* 7 (register bit affects uartb and vfir) */
> +#define TEGRA210_CLK_GPIO 8
> +#define TEGRA210_CLK_SDMMC2 9
> +/* 10 (register bit affects spdif_in and spdif_out) */
> +#define TEGRA210_CLK_I2S1 11
> +#define TEGRA210_CLK_I2C1 12
> +/* 13 */
> +#define TEGRA210_CLK_SDMMC1 14
> +#define TEGRA210_CLK_SDMMC4 15
> +/* 16 */
> +#define TEGRA210_CLK_PWM 17
> +#define TEGRA210_CLK_I2S2 18
> +/* 19 */
> +/* 20 (register bit affects vi and vi_sensor) */
> +/* 21 */
> +#define TEGRA210_CLK_USBD 22
> +#define TEGRA210_CLK_ISP 23
> +/* 24 */
> +/* 25 */
> +#define TEGRA210_CLK_DISP2 26
> +#define TEGRA210_CLK_DISP1 27
> +#define TEGRA210_CLK_HOST1X 28
> +/* 29 */
> +#define TEGRA210_CLK_I2S0 30
> +/* 31 */
> +
> +#define TEGRA210_CLK_MC 32
> +#define TEGRA210_CLK_AHBDMA 33
> +#define TEGRA210_CLK_APBDMA 34
> +/* 35 */
> +/* 36 */
> +/* 37 */
> +#define TEGRA210_CLK_PMC 38
> +/* 39 (register bit affects fuse and fuse_burn) */
> +#define TEGRA210_CLK_KFUSE 40
> +#define TEGRA210_CLK_SBC1 41
> +/* 42 */
> +/* 43 */
> +#define TEGRA210_CLK_SBC2 44
> +/* 45 */
> +#define TEGRA210_CLK_SBC3 46
> +#define TEGRA210_CLK_I2C5 47
> +#define TEGRA210_CLK_DSIA 48
> +/* 49 */
> +/* 50 */
> +/* 51 */
> +#define TEGRA210_CLK_CSI 52
> +/* 53 */
> +#define TEGRA210_CLK_I2C2 54
> +#define TEGRA210_CLK_UARTC 55
> +#define TEGRA210_CLK_MIPI_CAL 56
> +#define TEGRA210_CLK_EMC 57
> +#define TEGRA210_CLK_USB2 58
> +/* 59 */
> +/* 60 */
> +/* 61 */
> +/* 62 */
> +#define TEGRA210_CLK_BSEV 63
> +
> +/* 64 */
> +#define TEGRA210_CLK_UARTD 65
> +/* 66 */
> +#define TEGRA210_CLK_I2C3 67
> +#define TEGRA210_CLK_SBC4 68
> +#define TEGRA210_CLK_SDMMC3 69
> +#define TEGRA210_CLK_PCIE 70
> +#define TEGRA210_CLK_OWR 71
> +#define TEGRA210_CLK_AFI 72
> +#define TEGRA210_CLK_CSITE 73
> +/* 74 */
> +/* 75 */
> +/* 76 */
> +/* 77 */
> +#define TEGRA210_CLK_SOC_THERM 78
> +#define TEGRA210_CLK_DTV 79
> +/* 80 */
> +#define TEGRA210_CLK_I2CSLOW 81
> +#define TEGRA210_CLK_DSIB 82
> +#define TEGRA210_CLK_TSEC 83
> +/* 84 */
> +/* 85 */
> +/* 86 */
> +/* 87 */
> +/* 88 */
> +#define TEGRA210_CLK_XUSB_HOST 89
> +/* 90 */
> +/* 91 */
> +#define TEGRA210_CLK_CSUS 92
> +/* 93 */
> +/* 94 */
> +/* 95 (bit affects xusb_dev and xusb_dev_src) */
> +
> +/* 96 */
> +/* 97 */
> +/* 98 */
> +#define TEGRA210_CLK_MSELECT 99
> +#define TEGRA210_CLK_TSENSOR 100
> +#define TEGRA210_CLK_I2S3 101
> +#define TEGRA210_CLK_I2S4 102
> +#define TEGRA210_CLK_I2C4 103
> +/* 104 */
> +/* 105 */
> +#define TEGRA210_CLK_D_AUDIO 106
> +/* 107 ( affects abp -> ape) */
> +/* 108 */
> +/* 109 */
> +/* 110 */
> +#define TEGRA210_CLK_HDA2CODEC_2X 111
> +/* 112 */
> +/* 113 */
> +/* 114 */
> +/* 115 */
> +/* 116 */
> +/* 117 */
> +#define TEGRA210_CLK_SPDIF_2X 118
> +#define TEGRA210_CLK_ACTMON 119
> +#define TEGRA210_CLK_EXTERN1 120
> +#define TEGRA210_CLK_EXTERN2 121
> +#define TEGRA210_CLK_EXTERN3 122
> +#define TEGRA210_CLK_SATA_OOB 123
> +#define TEGRA210_CLK_SATA 124
> +#define TEGRA210_CLK_HDA 125
> +/* 126 */
> +/* 127 */
> +
> +#define TEGRA210_CLK_HDA2HDMI 128
> +/* 129 */
> +/* 130 */
> +/* 131 */
> +/* 132 */
> +/* 133 */
> +/* 134 */
> +/* 135 */
> +/* 136 */
> +/* 137 */
> +/* 138 */
> +/* 139 */
> +/* 140 */
> +/* 141 */
> +/* 142 */
> +/* 143 (bit affects xusb_falcon_src, xusb_fs_src, */
> +/* xusb_host_src and xusb_ss_src) */
> +#define TEGRA210_CLK_CILAB 144
> +#define TEGRA210_CLK_CILCD 145
> +#define TEGRA210_CLK_CILE 146
> +#define TEGRA210_CLK_DSIALP 147
> +#define TEGRA210_CLK_DSIBLP 148
> +#define TEGRA210_CLK_ENTROPY 149
> +/* 150 */
> +/* 151 */
> +/* 152 */
> +/* 153 */
> +/* 154 */
> +/* 155 (bit affects dfll_ref and dfll_soc) */
> +#define TEGRA210_CLK_XUSB_SS 156
> +/* 157 */
> +/* 158 */
> +/* 159 */
> +
> +/* 160 */
> +#define TEGRA210_CLK_DMIC1 161
> +#define TEGRA210_CLK_DMIC2 162
> +/* 163 */
> +/* 164 */
> +/* 165 */
> +#define TEGRA210_CLK_I2C6 166
> +/* 167 */
> +/* 168 */
> +/* 169 */
> +/* 170 */
> +#define TEGRA210_CLK_VIM2_CLK 171
> +/* 172 */
> +#define TEGRA210_CLK_MIPIBIF 173
> +/* 174 */
> +/* 175 */
> +/* 176 */
> +#define TEGRA210_CLK_CLK72MHZ 177
> +#define TEGRA210_CLK_VIC03 178
> +/* 179 */
> +/* 180 */
> +#define TEGRA210_CLK_DPAUX 181
> +#define TEGRA210_CLK_SOR0 182
> +#define TEGRA210_CLK_SOR1 183
> +#define TEGRA210_CLK_GPU 184
> +#define TEGRA210_CLK_DBGAPB 185
> +/* 186 */
> +/* 187 */
> +/* 188 */
> +#define TEGRA210_CLK_PLL_G_REF 189
> +/* 190 */
> +/* 191 */
> +
> +/* 192 */
> +#define TEGRA210_CLK_SDMMC_LEGACY 193
> +#define TEGRA210_CLK_NVDEC 194
> +#define TEGRA210_CLK_NVJPG 195
> +/* 196 */
> +#define TEGRA210_CLK_DMIC3 197
> +#define TEGRA210_CLK_APE 198
> +/* 199 */
> +/* 200 */
> +/* 201 */
> +#define TEGRA210_CLK_MAUD 202
> +/* 203 */
> +/* 204 */
> +/* 205 */
> +#define TEGRA210_CLK_TSECB 206
> +#define TEGRA210_CLK_DPAUX1 207
> +#define TEGRA210_CLK_VI_I2C 208
> +/* 209 */
> +/* 210 */
> +#define TEGRA210_CLK_QSPI 211
> +#define TEGRA210_CLK_UARTAPE 212
> +/* 213 */
> +/* 214 */
> +/* 215 */
> +/* 216 */
> +/* 217 */
> +/* 218 */
> +#define TEGRA210_CLK_NVENC 219
> +/* 220 */
> +/* 221 */
> +#define TEGRA210_CLK_SOR_SAFE 222
> +/* 223 */
> +
> +
> +#define TEGRA210_CLK_UARTB 224
> +#define TEGRA210_CLK_VFIR 225
> +#define TEGRA210_CLK_SPDIF_IN 226
> +#define TEGRA210_CLK_SPDIF_OUT 227
> +#define TEGRA210_CLK_VI 228
> +#define TEGRA210_CLK_VI_SENSOR 229
> +#define TEGRA210_CLK_FUSE 230
> +#define TEGRA210_CLK_FUSE_BURN 231
> +#define TEGRA210_CLK_CLK_32K 232
> +#define TEGRA210_CLK_CLK_M 233
> +#define TEGRA210_CLK_CLK_M_DIV2 234
> +#define TEGRA210_CLK_CLK_M_DIV4 235
> +#define TEGRA210_CLK_PLL_REF 236
> +#define TEGRA210_CLK_PLL_C 237
> +#define TEGRA210_CLK_PLL_C_OUT1 238
> +#define TEGRA210_CLK_PLL_C2 239
> +#define TEGRA210_CLK_PLL_C3 240
> +#define TEGRA210_CLK_PLL_M 241
> +#define TEGRA210_CLK_PLL_M_OUT1 242
> +#define TEGRA210_CLK_PLL_P 243
> +#define TEGRA210_CLK_PLL_P_OUT1 244
> +#define TEGRA210_CLK_PLL_P_OUT2 245
> +#define TEGRA210_CLK_PLL_P_OUT3 246
> +#define TEGRA210_CLK_PLL_P_OUT4 247
> +#define TEGRA210_CLK_PLL_A 248
> +#define TEGRA210_CLK_PLL_A_OUT0 249
> +#define TEGRA210_CLK_PLL_D 250
> +#define TEGRA210_CLK_PLL_D_OUT0 251
> +#define TEGRA210_CLK_PLL_D2 252
> +#define TEGRA210_CLK_PLL_D2_OUT0 253
> +#define TEGRA210_CLK_PLL_U 254
> +#define TEGRA210_CLK_PLL_U_480M 255
> +
> +#define TEGRA210_CLK_PLL_U_60M 256
> +#define TEGRA210_CLK_PLL_U_48M 257
> +#define TEGRA210_CLK_PLL_U_12M 258
> +#define TEGRA210_CLK_PLL_X 259
> +#define TEGRA210_CLK_PLL_X_OUT0 260
> +#define TEGRA210_CLK_PLL_RE_VCO 261
> +#define TEGRA210_CLK_PLL_RE_OUT 262
> +#define TEGRA210_CLK_PLL_E 263
> +#define TEGRA210_CLK_SPDIF_IN_SYNC 264
> +#define TEGRA210_CLK_I2S0_SYNC 265
> +#define TEGRA210_CLK_I2S1_SYNC 266
> +#define TEGRA210_CLK_I2S2_SYNC 267
> +#define TEGRA210_CLK_I2S3_SYNC 268
> +#define TEGRA210_CLK_I2S4_SYNC 269
> +#define TEGRA210_CLK_VIMCLK_SYNC 270
> +#define TEGRA210_CLK_AUDIO0 271
> +#define TEGRA210_CLK_AUDIO1 272
> +#define TEGRA210_CLK_AUDIO2 273
> +#define TEGRA210_CLK_AUDIO3 274
> +#define TEGRA210_CLK_AUDIO4 275
> +#define TEGRA210_CLK_SPDIF 276
> +#define TEGRA210_CLK_CLK_OUT_1 277
> +#define TEGRA210_CLK_CLK_OUT_2 278
> +#define TEGRA210_CLK_CLK_OUT_3 279
> +#define TEGRA210_CLK_BLINK 280
> +/* 281 */
> +/* 282 */
> +/* 283 */
> +#define TEGRA210_CLK_XUSB_HOST_SRC 284
> +#define TEGRA210_CLK_XUSB_FALCON_SRC 285
> +#define TEGRA210_CLK_XUSB_FS_SRC 286
> +#define TEGRA210_CLK_XUSB_SS_SRC 287
> +
> +#define TEGRA210_CLK_XUSB_DEV_SRC 288
> +#define TEGRA210_CLK_XUSB_DEV 289
> +#define TEGRA210_CLK_XUSB_HS_SRC 290
> +#define TEGRA210_CLK_SCLK 291
> +#define TEGRA210_CLK_HCLK 292
> +#define TEGRA210_CLK_PCLK 293
> +#define TEGRA210_CLK_CCLK_G 294
> +#define TEGRA210_CLK_CCLK_LP 295
> +#define TEGRA210_CLK_DFLL_REF 296
> +#define TEGRA210_CLK_DFLL_SOC 297
> +#define TEGRA210_CLK_VI_SENSOR2 298
> +#define TEGRA210_CLK_PLL_P_OUT5 299
> +#define TEGRA210_CLK_CML0 300
> +#define TEGRA210_CLK_CML1 301
> +#define TEGRA210_CLK_PLL_C4 302
> +#define TEGRA210_CLK_PLL_DP 303
> +#define TEGRA210_CLK_PLL_E_MUX 304
> +#define TEGRA210_CLK_PLL_MB 305
> +#define TEGRA210_CLK_PLL_A1 306
> +#define TEGRA210_CLK_PLLD_DSI 307
> +#define TEGRA210_CLK_PLL_C4_OUT0 308
> +#define TEGRA210_CLK_PLL_C4_OUT1 309
> +#define TEGRA210_CLK_PLL_C4_OUT2 310
> +#define TEGRA210_CLK_PLL_C4_OUT3 311
> +/* 312 */
> +/* 313 */
> +/* 314 */
> +/* 315 */
> +/* 316 */
> +/* 317 */
> +/* 318 */
> +/* 319 */
> +/* 320 */
> +/* 321 */
> +/* 322 */
> +/* 323 */
> +/* 324 */
> +/* 325 */
> +/* 326 */
> +/* 327 */
> +/* 328 */
> +/* 329 */
> +/* 330 */
> +/* 331 */
> +/* 332 */
> +/* 333 */
> +/* 334 */
> +/* 335 */
> +/* 336 */
> +/* 337 */
> +/* 338 */
> +/* 339 */
> +/* 340 */
> +/* 341 */
> +/* 342 */
> +/* 343 */
> +/* 344 */
> +/* 345 */
> +/* 346 */
> +/* 347 */
> +/* 348 */
> +/* 349 */
> +
> +#define TEGRA210_CLK_AUDIO0_MUX 350
> +#define TEGRA210_CLK_AUDIO1_MUX 351
> +#define TEGRA210_CLK_AUDIO2_MUX 352
> +#define TEGRA210_CLK_AUDIO3_MUX 353
> +#define TEGRA210_CLK_AUDIO4_MUX 354
> +#define TEGRA210_CLK_SPDIF_MUX 355
> +#define TEGRA210_CLK_CLK_OUT_1_MUX 356
> +#define TEGRA210_CLK_CLK_OUT_2_MUX 357
> +#define TEGRA210_CLK_CLK_OUT_3_MUX 358
> +#define TEGRA210_CLK_DSIA_MUX 359
> +#define TEGRA210_CLK_DSIB_MUX 360
> +#define TEGRA210_CLK_SOR0_LVDS 361
> +#define TEGRA210_CLK_XUSB_SS_DIV2 362
> +
> +#define TEGRA210_CLK_PLL_M_UD 363
> +#define TEGRA210_CLK_PLL_C_UD 364
> +#define TEGRA210_CLK_SCLK_MUX 365
> +
> +#define TEGRA210_CLK_CLK_MAX 366
> +
> +#endif /* _DT_BINDINGS_CLOCK_TEGRA210_CAR_H */
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/