2013-01-11 11:46:25 +04:00
/*
* Copyright ( c ) 2012 , 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/delay.h>
# include <linux/clk-provider.h>
# include <linux/clkdev.h>
# include <linux/of.h>
# include <linux/of_address.h>
# include <linux/clk/tegra.h>
2014-07-17 15:17:24 +04:00
2014-07-11 15:19:06 +04:00
# include <soc/tegra/pmc.h>
2014-07-17 15:17:24 +04:00
2013-10-07 15:49:04 +04:00
# include <dt-bindings/clock/tegra30-car.h>
2014-07-17 15:17:24 +04:00
2013-01-11 11:46:25 +04:00
# include "clk.h"
2013-10-07 15:49:04 +04:00
# include "clk-id.h"
2013-01-11 11:46:25 +04:00
# define OSC_CTRL 0x50
# define OSC_CTRL_OSC_FREQ_MASK (0xF<<28)
# define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28)
# define OSC_CTRL_OSC_FREQ_19_2MHZ (0X4<<28)
# define OSC_CTRL_OSC_FREQ_12MHZ (0X8<<28)
# define OSC_CTRL_OSC_FREQ_26MHZ (0XC<<28)
# define OSC_CTRL_OSC_FREQ_16_8MHZ (0X1<<28)
# define OSC_CTRL_OSC_FREQ_38_4MHZ (0X5<<28)
# define OSC_CTRL_OSC_FREQ_48MHZ (0X9<<28)
# define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
# define OSC_CTRL_PLL_REF_DIV_MASK (3<<26)
# define OSC_CTRL_PLL_REF_DIV_1 (0<<26)
# define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
# define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
# define OSC_FREQ_DET 0x58
# define OSC_FREQ_DET_TRIG BIT(31)
# define OSC_FREQ_DET_STATUS 0x5c
# define OSC_FREQ_DET_BUSY BIT(31)
# define OSC_FREQ_DET_CNT_MASK 0xffff
# define CCLKG_BURST_POLICY 0x368
# define SUPER_CCLKG_DIVIDER 0x36c
# define CCLKLP_BURST_POLICY 0x370
# define SUPER_CCLKLP_DIVIDER 0x374
# define SCLK_BURST_POLICY 0x028
# define SUPER_SCLK_DIVIDER 0x02c
# define SYSTEM_CLK_RATE 0x030
2013-08-22 19:44:06 +04:00
# define TEGRA30_CLK_PERIPH_BANKS 5
2013-01-11 11:46:25 +04:00
# define PLLC_BASE 0x80
# define PLLC_MISC 0x8c
# define PLLM_BASE 0x90
# define PLLM_MISC 0x9c
# define PLLP_BASE 0xa0
# define PLLP_MISC 0xac
# define PLLX_BASE 0xe0
# define PLLX_MISC 0xe4
# define PLLD_BASE 0xd0
# define PLLD_MISC 0xdc
# define PLLD2_BASE 0x4b8
# define PLLD2_MISC 0x4bc
# define PLLE_BASE 0xe8
# define PLLE_MISC 0xec
# define PLLA_BASE 0xb0
# define PLLA_MISC 0xbc
# define PLLU_BASE 0xc0
# define PLLU_MISC 0xcc
# define PLL_MISC_LOCK_ENABLE 18
# define PLLDU_MISC_LOCK_ENABLE 22
# define PLLE_MISC_LOCK_ENABLE 9
2013-04-03 18:40:40 +04:00
# define PLL_BASE_LOCK BIT(27)
# define PLLE_MISC_LOCK BIT(11)
2013-01-11 11:46:25 +04:00
# define PLLE_AUX 0x48c
# define PLLC_OUT 0x84
# define PLLM_OUT 0x94
# define PLLP_OUTA 0xa4
# define PLLP_OUTB 0xa8
# define PLLA_OUT 0xb4
# define AUDIO_SYNC_CLK_I2S0 0x4a0
# define AUDIO_SYNC_CLK_I2S1 0x4a4
# define AUDIO_SYNC_CLK_I2S2 0x4a8
# define AUDIO_SYNC_CLK_I2S3 0x4ac
# define AUDIO_SYNC_CLK_I2S4 0x4b0
# define AUDIO_SYNC_CLK_SPDIF 0x4b4
# define CLK_SOURCE_SPDIF_OUT 0x108
2013-10-29 19:51:12 +04:00
# define CLK_SOURCE_PWM 0x110
2013-01-11 11:46:25 +04:00
# define CLK_SOURCE_D_AUDIO 0x3d0
# define CLK_SOURCE_DAM0 0x3d8
# define CLK_SOURCE_DAM1 0x3dc
# define CLK_SOURCE_DAM2 0x3e0
# define CLK_SOURCE_3D2 0x3b0
# define CLK_SOURCE_2D 0x15c
# define CLK_SOURCE_HDMI 0x18c
# define CLK_SOURCE_DSIB 0xd0
# define CLK_SOURCE_SE 0x42c
# define CLK_SOURCE_EMC 0x19c
# define AUDIO_SYNC_DOUBLER 0x49c
/* Tegra CPU clock and reset control regs */
# define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c
# define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
# define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344
# define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c
# define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
# define CPU_CLOCK(cpu) (0x1 << (8 + cpu))
# define CPU_RESET(cpu) (0x1111ul << (cpu))
# define CLK_RESET_CCLK_BURST 0x20
# define CLK_RESET_CCLK_DIVIDER 0x24
# define CLK_RESET_PLLX_BASE 0xe0
# define CLK_RESET_PLLX_MISC 0xe4
# define CLK_RESET_SOURCE_CSITE 0x1d4
# define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28
# define CLK_RESET_CCLK_RUN_POLICY_SHIFT 4
# define CLK_RESET_CCLK_IDLE_POLICY_SHIFT 0
# define CLK_RESET_CCLK_IDLE_POLICY 1
# define CLK_RESET_CCLK_RUN_POLICY 2
# define CLK_RESET_CCLK_BURST_POLICY_PLLX 8
2013-06-06 14:47:30 +04:00
/* PLLM override registers */
# define PMC_PLLM_WB0_OVERRIDE 0x1dc
2013-01-11 11:46:25 +04:00
# ifdef CONFIG_PM_SLEEP
static struct cpu_clk_suspend_context {
u32 pllx_misc ;
u32 pllx_base ;
u32 cpu_burst ;
u32 clk_csite_src ;
u32 cclk_divider ;
} tegra30_cpu_clk_sctx ;
# endif
static void __iomem * clk_base ;
static void __iomem * pmc_base ;
static unsigned long input_freq ;
static DEFINE_SPINLOCK ( cml_lock ) ;
static DEFINE_SPINLOCK ( pll_d_lock ) ;
2014-07-29 12:17:53 +04:00
static DEFINE_SPINLOCK ( emc_lock ) ;
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
# define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
2013-08-22 19:44:06 +04:00
_clk_num , _gate_flags , _clk_id ) \
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA ( _name , NULL , NULL , _parents , _offset , \
2013-08-22 19:44:06 +04:00
30 , 2 , 0 , 0 , 8 , 1 , TEGRA_DIVIDER_ROUND_UP , \
2013-09-02 16:22:02 +04:00
_clk_num , _gate_flags , _clk_id )
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
# define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \
2013-08-22 19:44:06 +04:00
_clk_num , _gate_flags , _clk_id ) \
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA ( _name , NULL , NULL , _parents , _offset , \
2013-08-22 19:44:06 +04:00
29 , 3 , 0 , 0 , 8 , 1 , TEGRA_DIVIDER_ROUND_UP , \
2013-09-02 16:22:02 +04:00
_clk_num , _gate_flags , _clk_id )
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
# define TEGRA_INIT_DATA_INT(_name, _parents, _offset, \
2013-08-22 19:44:06 +04:00
_clk_num , _gate_flags , _clk_id ) \
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA ( _name , NULL , NULL , _parents , _offset , \
2013-11-26 15:48:09 +04:00
30 , 2 , 0 , 0 , 8 , 1 , TEGRA_DIVIDER_INT | \
2013-08-22 19:44:06 +04:00
TEGRA_DIVIDER_ROUND_UP , _clk_num , \
2013-09-02 16:22:02 +04:00
_gate_flags , _clk_id )
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
# define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \
2013-08-22 19:44:06 +04:00
_mux_shift , _mux_width , _clk_num , \
2013-01-11 11:46:25 +04:00
_gate_flags , _clk_id ) \
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA ( _name , NULL , NULL , _parents , _offset , \
2013-08-22 19:44:06 +04:00
_mux_shift , _mux_width , 0 , 0 , 0 , 0 , 0 , \
2013-09-02 16:22:02 +04:00
_clk_num , _gate_flags , \
2013-01-11 11:46:25 +04:00
_clk_id )
2013-09-02 16:22:02 +04:00
static struct clk * * clks ;
2013-01-11 11:46:25 +04:00
static struct tegra_clk_pll_freq_table pll_c_freq_table [ ] = {
2015-06-19 00:28:34 +03:00
{ 12000000 , 1040000000 , 520 , 6 , 1 , 8 } ,
{ 13000000 , 1040000000 , 480 , 6 , 1 , 8 } ,
{ 16800000 , 1040000000 , 495 , 8 , 1 , 8 } , /* actual: 1039.5 MHz */
{ 19200000 , 1040000000 , 325 , 6 , 1 , 6 } ,
{ 26000000 , 1040000000 , 520 , 13 , 1 , 8 } ,
{ 12000000 , 832000000 , 416 , 6 , 1 , 8 } ,
{ 13000000 , 832000000 , 832 , 13 , 1 , 8 } ,
{ 16800000 , 832000000 , 396 , 8 , 1 , 8 } , /* actual: 831.6 MHz */
{ 19200000 , 832000000 , 260 , 6 , 1 , 8 } ,
{ 26000000 , 832000000 , 416 , 13 , 1 , 8 } ,
{ 12000000 , 624000000 , 624 , 12 , 1 , 8 } ,
{ 13000000 , 624000000 , 624 , 13 , 1 , 8 } ,
{ 16800000 , 600000000 , 520 , 14 , 1 , 8 } ,
{ 19200000 , 624000000 , 520 , 16 , 1 , 8 } ,
{ 26000000 , 624000000 , 624 , 26 , 1 , 8 } ,
{ 12000000 , 600000000 , 600 , 12 , 1 , 8 } ,
{ 13000000 , 600000000 , 600 , 13 , 1 , 8 } ,
{ 16800000 , 600000000 , 500 , 14 , 1 , 8 } ,
{ 19200000 , 600000000 , 375 , 12 , 1 , 6 } ,
{ 26000000 , 600000000 , 600 , 26 , 1 , 8 } ,
{ 12000000 , 520000000 , 520 , 12 , 1 , 8 } ,
{ 13000000 , 520000000 , 520 , 13 , 1 , 8 } ,
{ 16800000 , 520000000 , 495 , 16 , 1 , 8 } , /* actual: 519.75 MHz */
{ 19200000 , 520000000 , 325 , 12 , 1 , 6 } ,
{ 26000000 , 520000000 , 520 , 26 , 1 , 8 } ,
{ 12000000 , 416000000 , 416 , 12 , 1 , 8 } ,
{ 13000000 , 416000000 , 416 , 13 , 1 , 8 } ,
{ 16800000 , 416000000 , 396 , 16 , 1 , 8 } , /* actual: 415.8 MHz */
{ 19200000 , 416000000 , 260 , 12 , 1 , 6 } ,
{ 26000000 , 416000000 , 416 , 26 , 1 , 8 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_freq_table pll_m_freq_table [ ] = {
2015-06-19 00:28:34 +03:00
{ 12000000 , 666000000 , 666 , 12 , 1 , 8 } ,
{ 13000000 , 666000000 , 666 , 13 , 1 , 8 } ,
{ 16800000 , 666000000 , 555 , 14 , 1 , 8 } ,
{ 19200000 , 666000000 , 555 , 16 , 1 , 8 } ,
{ 26000000 , 666000000 , 666 , 26 , 1 , 8 } ,
{ 12000000 , 600000000 , 600 , 12 , 1 , 8 } ,
{ 13000000 , 600000000 , 600 , 13 , 1 , 8 } ,
{ 16800000 , 600000000 , 500 , 14 , 1 , 8 } ,
{ 19200000 , 600000000 , 375 , 12 , 1 , 6 } ,
{ 26000000 , 600000000 , 600 , 26 , 1 , 8 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_freq_table pll_p_freq_table [ ] = {
2015-06-19 00:28:34 +03:00
{ 12000000 , 216000000 , 432 , 12 , 2 , 8 } ,
{ 13000000 , 216000000 , 432 , 13 , 2 , 8 } ,
{ 16800000 , 216000000 , 360 , 14 , 2 , 8 } ,
{ 19200000 , 216000000 , 360 , 16 , 2 , 8 } ,
{ 26000000 , 216000000 , 432 , 26 , 2 , 8 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_freq_table pll_a_freq_table [ ] = {
2015-06-19 00:28:34 +03:00
{ 9600000 , 564480000 , 294 , 5 , 1 , 4 } ,
{ 9600000 , 552960000 , 288 , 5 , 1 , 4 } ,
{ 9600000 , 24000000 , 5 , 2 , 1 , 1 } ,
{ 28800000 , 56448000 , 49 , 25 , 1 , 1 } ,
{ 28800000 , 73728000 , 64 , 25 , 1 , 1 } ,
{ 28800000 , 24000000 , 5 , 6 , 1 , 1 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_freq_table pll_d_freq_table [ ] = {
2015-06-19 00:28:34 +03:00
{ 12000000 , 216000000 , 216 , 12 , 1 , 4 } ,
{ 13000000 , 216000000 , 216 , 13 , 1 , 4 } ,
{ 16800000 , 216000000 , 180 , 14 , 1 , 4 } ,
{ 19200000 , 216000000 , 180 , 16 , 1 , 4 } ,
{ 26000000 , 216000000 , 216 , 26 , 1 , 4 } ,
{ 12000000 , 594000000 , 594 , 12 , 1 , 8 } ,
{ 13000000 , 594000000 , 594 , 13 , 1 , 8 } ,
{ 16800000 , 594000000 , 495 , 14 , 1 , 8 } ,
{ 19200000 , 594000000 , 495 , 16 , 1 , 8 } ,
{ 26000000 , 594000000 , 594 , 26 , 1 , 8 } ,
{ 12000000 , 1000000000 , 1000 , 12 , 1 , 12 } ,
{ 13000000 , 1000000000 , 1000 , 13 , 1 , 12 } ,
{ 19200000 , 1000000000 , 625 , 12 , 1 , 8 } ,
{ 26000000 , 1000000000 , 1000 , 26 , 1 , 12 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
2015-11-19 18:34:06 +03:00
static const struct pdiv_map pllu_p [ ] = {
2013-04-03 18:40:39 +04:00
{ . pdiv = 1 , . hw_val = 1 } ,
{ . pdiv = 2 , . hw_val = 0 } ,
{ . pdiv = 0 , . hw_val = 0 } ,
} ;
2013-01-11 11:46:25 +04:00
static struct tegra_clk_pll_freq_table pll_u_freq_table [ ] = {
2016-02-29 23:46:07 +03:00
{ 12000000 , 480000000 , 960 , 12 , 2 , 12 } ,
{ 13000000 , 480000000 , 960 , 13 , 2 , 12 } ,
{ 16800000 , 480000000 , 400 , 7 , 2 , 5 } ,
{ 19200000 , 480000000 , 200 , 4 , 2 , 3 } ,
{ 26000000 , 480000000 , 960 , 26 , 2 , 12 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_freq_table pll_x_freq_table [ ] = {
/* 1.7 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1700000000 , 850 , 6 , 1 , 8 } ,
{ 13000000 , 1700000000 , 915 , 7 , 1 , 8 } , /* actual: 1699.2 MHz */
{ 16800000 , 1700000000 , 708 , 7 , 1 , 8 } , /* actual: 1699.2 MHz */
{ 19200000 , 1700000000 , 885 , 10 , 1 , 8 } , /* actual: 1699.2 MHz */
{ 26000000 , 1700000000 , 850 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.6 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1600000000 , 800 , 6 , 1 , 8 } ,
{ 13000000 , 1600000000 , 738 , 6 , 1 , 8 } , /* actual: 1599.0 MHz */
{ 16800000 , 1600000000 , 857 , 9 , 1 , 8 } , /* actual: 1599.7 MHz */
{ 19200000 , 1600000000 , 500 , 6 , 1 , 8 } ,
{ 26000000 , 1600000000 , 800 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.5 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1500000000 , 750 , 6 , 1 , 8 } ,
{ 13000000 , 1500000000 , 923 , 8 , 1 , 8 } , /* actual: 1499.8 MHz */
{ 16800000 , 1500000000 , 625 , 7 , 1 , 8 } ,
{ 19200000 , 1500000000 , 625 , 8 , 1 , 8 } ,
{ 26000000 , 1500000000 , 750 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.4 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1400000000 , 700 , 6 , 1 , 8 } ,
{ 13000000 , 1400000000 , 969 , 9 , 1 , 8 } , /* actual: 1399.7 MHz */
{ 16800000 , 1400000000 , 1000 , 12 , 1 , 8 } ,
{ 19200000 , 1400000000 , 875 , 12 , 1 , 8 } ,
{ 26000000 , 1400000000 , 700 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.3 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1300000000 , 975 , 9 , 1 , 8 } ,
{ 13000000 , 1300000000 , 1000 , 10 , 1 , 8 } ,
{ 16800000 , 1300000000 , 928 , 12 , 1 , 8 } , /* actual: 1299.2 MHz */
{ 19200000 , 1300000000 , 812 , 12 , 1 , 8 } , /* actual: 1299.2 MHz */
{ 26000000 , 1300000000 , 650 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.2 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1200000000 , 1000 , 10 , 1 , 8 } ,
{ 13000000 , 1200000000 , 923 , 10 , 1 , 8 } , /* actual: 1199.9 MHz */
{ 16800000 , 1200000000 , 1000 , 14 , 1 , 8 } ,
{ 19200000 , 1200000000 , 1000 , 16 , 1 , 8 } ,
{ 26000000 , 1200000000 , 600 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1.1 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1100000000 , 825 , 9 , 1 , 8 } ,
{ 13000000 , 1100000000 , 846 , 10 , 1 , 8 } , /* actual: 1099.8 MHz */
{ 16800000 , 1100000000 , 982 , 15 , 1 , 8 } , /* actual: 1099.8 MHz */
{ 19200000 , 1100000000 , 859 , 15 , 1 , 8 } , /* actual: 1099.5 MHz */
{ 26000000 , 1100000000 , 550 , 13 , 1 , 8 } ,
2013-01-11 11:46:25 +04:00
/* 1 GHz */
2015-06-19 00:28:34 +03:00
{ 12000000 , 1000000000 , 1000 , 12 , 1 , 8 } ,
{ 13000000 , 1000000000 , 1000 , 13 , 1 , 8 } ,
{ 16800000 , 1000000000 , 833 , 14 , 1 , 8 } , /* actual: 999.6 MHz */
{ 19200000 , 1000000000 , 625 , 12 , 1 , 8 } ,
{ 26000000 , 1000000000 , 1000 , 26 , 1 , 8 } ,
2015-11-18 16:10:02 +03:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
2015-06-19 00:28:34 +03:00
static const struct pdiv_map plle_p [ ] = {
{ . pdiv = 18 , . hw_val = 18 } ,
{ . pdiv = 24 , . hw_val = 24 } ,
{ . pdiv = 0 , . hw_val = 0 } ,
} ;
2013-01-11 11:46:25 +04:00
static struct tegra_clk_pll_freq_table pll_e_freq_table [ ] = {
/* PLLE special case: use cpcon field to store cml divider value */
2015-11-18 16:10:02 +03:00
{ 12000000 , 100000000 , 150 , 1 , 18 , 11 } ,
{ 216000000 , 100000000 , 200 , 18 , 24 , 13 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
/* PLL parameters */
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_c_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 31000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 20000000 ,
. vco_max = 1400000000 ,
. base_reg = PLLC_BASE ,
. misc_reg = PLLC_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_c_freq_table ,
2015-06-19 00:28:23 +03:00
. flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK |
TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2013-06-06 14:47:30 +04:00
static struct div_nmp pllm_nmp = {
. divn_shift = 8 ,
. divn_width = 10 ,
. override_divn_shift = 5 ,
. divm_shift = 0 ,
. divm_width = 5 ,
. override_divm_shift = 0 ,
. divp_shift = 20 ,
. divp_width = 3 ,
. override_divp_shift = 15 ,
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_m_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 31000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 20000000 ,
. vco_max = 1200000000 ,
. base_reg = PLLM_BASE ,
. misc_reg = PLLM_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2013-06-06 14:47:30 +04:00
. div_nmp = & pllm_nmp ,
. pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE ,
. pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_m_freq_table ,
. flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON |
2015-06-19 00:28:23 +03:00
TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK |
2015-06-19 00:28:27 +03:00
TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_FIXED ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_p_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 31000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 20000000 ,
. vco_max = 1400000000 ,
. base_reg = PLLP_BASE ,
. misc_reg = PLLP_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_p_freq_table ,
2015-06-19 00:28:23 +03:00
. flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK |
TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-10-04 18:28:34 +04:00
. fixed_rate = 408000000 ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_clk_pll_params pll_a_params = {
. input_min = 2000000 ,
. input_max = 31000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 20000000 ,
. vco_max = 1400000000 ,
. base_reg = PLLA_BASE ,
. misc_reg = PLLA_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_a_freq_table ,
2015-06-19 00:28:23 +03:00
. flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK |
TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_d_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 40000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 40000000 ,
. vco_max = 1000000000 ,
. base_reg = PLLD_BASE ,
. misc_reg = PLLD_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE ,
. lock_delay = 1000 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_d_freq_table ,
. flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
2015-06-19 00:28:23 +03:00
TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_d2_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 40000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 40000000 ,
. vco_max = 1000000000 ,
. base_reg = PLLD2_BASE ,
. misc_reg = PLLD2_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE ,
. lock_delay = 1000 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_d_freq_table ,
. flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
2015-06-19 00:28:23 +03:00
TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_u_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 40000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 48000000 ,
. vco_max = 960000000 ,
. base_reg = PLLU_BASE ,
. misc_reg = PLLU_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE ,
. lock_delay = 1000 ,
2013-04-03 18:40:39 +04:00
. pdiv_tohw = pllu_p ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_u_freq_table ,
2015-06-19 00:28:23 +03:00
. flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_x_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 2000000 ,
. input_max = 31000000 ,
. cf_min = 1000000 ,
. cf_max = 6000000 ,
. vco_min = 20000000 ,
. vco_max = 1700000000 ,
. base_reg = PLLX_BASE ,
. misc_reg = PLLX_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLL_BASE_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_x_freq_table ,
. flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON |
2015-06-19 00:28:23 +03:00
TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE ,
2013-01-11 11:46:25 +04:00
} ;
2017-10-02 23:12:08 +03:00
static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
2013-01-11 11:46:25 +04:00
. input_min = 12000000 ,
. input_max = 216000000 ,
. cf_min = 12000000 ,
. cf_max = 12000000 ,
. vco_min = 1200000000 ,
. vco_max = 2400000000U ,
. base_reg = PLLE_BASE ,
. misc_reg = PLLE_MISC ,
2013-04-03 18:40:40 +04:00
. lock_mask = PLLE_MISC_LOCK ,
2013-01-11 11:46:25 +04:00
. lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE ,
. lock_delay = 300 ,
2015-06-19 00:28:34 +03:00
. pdiv_tohw = plle_p ,
2013-10-04 18:28:34 +04:00
. freq_table = pll_e_freq_table ,
2015-06-19 00:28:23 +03:00
. flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED |
TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC ,
2013-10-04 18:28:34 +04:00
. fixed_rate = 100000000 ,
2013-01-11 11:46:25 +04:00
} ;
2013-10-07 15:49:04 +04:00
static unsigned long tegra30_input_freq [ ] = {
2015-11-18 16:10:02 +03:00
[ 0 ] = 13000000 ,
[ 1 ] = 16800000 ,
[ 4 ] = 19200000 ,
[ 5 ] = 38400000 ,
[ 8 ] = 12000000 ,
[ 9 ] = 48000000 ,
2015-11-18 15:23:46 +03:00
[ 12 ] = 26000000 ,
2013-10-07 15:49:04 +04:00
} ;
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
static struct tegra_devclk devclks [ ] __initdata = {
{ . con_id = " pll_c " , . dt_id = TEGRA30_CLK_PLL_C } ,
{ . con_id = " pll_c_out1 " , . dt_id = TEGRA30_CLK_PLL_C_OUT1 } ,
{ . con_id = " pll_p " , . dt_id = TEGRA30_CLK_PLL_P } ,
{ . con_id = " pll_p_out1 " , . dt_id = TEGRA30_CLK_PLL_P_OUT1 } ,
{ . con_id = " pll_p_out2 " , . dt_id = TEGRA30_CLK_PLL_P_OUT2 } ,
{ . con_id = " pll_p_out3 " , . dt_id = TEGRA30_CLK_PLL_P_OUT3 } ,
{ . con_id = " pll_p_out4 " , . dt_id = TEGRA30_CLK_PLL_P_OUT4 } ,
{ . con_id = " pll_m " , . dt_id = TEGRA30_CLK_PLL_M } ,
{ . con_id = " pll_m_out1 " , . dt_id = TEGRA30_CLK_PLL_M_OUT1 } ,
{ . con_id = " pll_x " , . dt_id = TEGRA30_CLK_PLL_X } ,
{ . con_id = " pll_x_out0 " , . dt_id = TEGRA30_CLK_PLL_X_OUT0 } ,
{ . con_id = " pll_u " , . dt_id = TEGRA30_CLK_PLL_U } ,
{ . con_id = " pll_d " , . dt_id = TEGRA30_CLK_PLL_D } ,
{ . con_id = " pll_d_out0 " , . dt_id = TEGRA30_CLK_PLL_D_OUT0 } ,
{ . con_id = " pll_d2 " , . dt_id = TEGRA30_CLK_PLL_D2 } ,
{ . con_id = " pll_d2_out0 " , . dt_id = TEGRA30_CLK_PLL_D2_OUT0 } ,
{ . con_id = " pll_a " , . dt_id = TEGRA30_CLK_PLL_A } ,
{ . con_id = " pll_a_out0 " , . dt_id = TEGRA30_CLK_PLL_A_OUT0 } ,
{ . con_id = " pll_e " , . dt_id = TEGRA30_CLK_PLL_E } ,
{ . con_id = " spdif_in_sync " , . dt_id = TEGRA30_CLK_SPDIF_IN_SYNC } ,
{ . con_id = " i2s0_sync " , . dt_id = TEGRA30_CLK_I2S0_SYNC } ,
{ . con_id = " i2s1_sync " , . dt_id = TEGRA30_CLK_I2S1_SYNC } ,
{ . con_id = " i2s2_sync " , . dt_id = TEGRA30_CLK_I2S2_SYNC } ,
{ . con_id = " i2s3_sync " , . dt_id = TEGRA30_CLK_I2S3_SYNC } ,
{ . con_id = " i2s4_sync " , . dt_id = TEGRA30_CLK_I2S4_SYNC } ,
{ . con_id = " vimclk_sync " , . dt_id = TEGRA30_CLK_VIMCLK_SYNC } ,
{ . con_id = " audio0 " , . dt_id = TEGRA30_CLK_AUDIO0 } ,
{ . con_id = " audio1 " , . dt_id = TEGRA30_CLK_AUDIO1 } ,
{ . con_id = " audio2 " , . dt_id = TEGRA30_CLK_AUDIO2 } ,
{ . con_id = " audio3 " , . dt_id = TEGRA30_CLK_AUDIO3 } ,
{ . con_id = " audio4 " , . dt_id = TEGRA30_CLK_AUDIO4 } ,
{ . con_id = " spdif " , . dt_id = TEGRA30_CLK_SPDIF } ,
{ . con_id = " audio0_2x " , . dt_id = TEGRA30_CLK_AUDIO0_2X } ,
{ . con_id = " audio1_2x " , . dt_id = TEGRA30_CLK_AUDIO1_2X } ,
{ . con_id = " audio2_2x " , . dt_id = TEGRA30_CLK_AUDIO2_2X } ,
{ . con_id = " audio3_2x " , . dt_id = TEGRA30_CLK_AUDIO3_2X } ,
{ . con_id = " audio4_2x " , . dt_id = TEGRA30_CLK_AUDIO4_2X } ,
{ . con_id = " spdif_2x " , . dt_id = TEGRA30_CLK_SPDIF_2X } ,
{ . con_id = " extern1 " , . dev_id = " clk_out_1 " , . dt_id = TEGRA30_CLK_EXTERN1 } ,
{ . con_id = " extern2 " , . dev_id = " clk_out_2 " , . dt_id = TEGRA30_CLK_EXTERN2 } ,
{ . con_id = " extern3 " , . dev_id = " clk_out_3 " , . dt_id = TEGRA30_CLK_EXTERN3 } ,
{ . con_id = " blink " , . dt_id = TEGRA30_CLK_BLINK } ,
{ . con_id = " cclk_g " , . dt_id = TEGRA30_CLK_CCLK_G } ,
{ . con_id = " cclk_lp " , . dt_id = TEGRA30_CLK_CCLK_LP } ,
{ . con_id = " sclk " , . dt_id = TEGRA30_CLK_SCLK } ,
{ . con_id = " hclk " , . dt_id = TEGRA30_CLK_HCLK } ,
{ . con_id = " pclk " , . dt_id = TEGRA30_CLK_PCLK } ,
{ . con_id = " twd " , . dt_id = TEGRA30_CLK_TWD } ,
{ . con_id = " emc " , . dt_id = TEGRA30_CLK_EMC } ,
{ . con_id = " clk_32k " , . dt_id = TEGRA30_CLK_CLK_32K } ,
{ . con_id = " clk_m_div2 " , . dt_id = TEGRA30_CLK_CLK_M_DIV2 } ,
{ . con_id = " clk_m_div4 " , . dt_id = TEGRA30_CLK_CLK_M_DIV4 } ,
{ . con_id = " cml0 " , . dt_id = TEGRA30_CLK_CML0 } ,
{ . con_id = " cml1 " , . dt_id = TEGRA30_CLK_CML1 } ,
{ . con_id = " clk_m " , . dt_id = TEGRA30_CLK_CLK_M } ,
{ . con_id = " pll_ref " , . dt_id = TEGRA30_CLK_PLL_REF } ,
{ . con_id = " csus " , . dev_id = " tengra_camera " , . dt_id = TEGRA30_CLK_CSUS } ,
{ . con_id = " vcp " , . dev_id = " tegra-avp " , . dt_id = TEGRA30_CLK_VCP } ,
{ . con_id = " bsea " , . dev_id = " tegra-avp " , . dt_id = TEGRA30_CLK_BSEA } ,
{ . con_id = " bsev " , . dev_id = " tegra-aes " , . dt_id = TEGRA30_CLK_BSEV } ,
{ . con_id = " dsia " , . dev_id = " tegradc.0 " , . dt_id = TEGRA30_CLK_DSIA } ,
{ . con_id = " csi " , . dev_id = " tegra_camera " , . dt_id = TEGRA30_CLK_CSI } ,
{ . con_id = " isp " , . dev_id = " tegra_camera " , . dt_id = TEGRA30_CLK_ISP } ,
{ . con_id = " pcie " , . dev_id = " tegra-pcie " , . dt_id = TEGRA30_CLK_PCIE } ,
{ . con_id = " afi " , . dev_id = " tegra-pcie " , . dt_id = TEGRA30_CLK_AFI } ,
2013-11-21 06:38:10 +04:00
{ . con_id = " fuse " , . dt_id = TEGRA30_CLK_FUSE } ,
2013-10-07 15:49:04 +04:00
{ . con_id = " fuse_burn " , . dev_id = " fuse-tegra " , . dt_id = TEGRA30_CLK_FUSE_BURN } ,
{ . con_id = " apbif " , . dev_id = " tegra30-ahub " , . dt_id = TEGRA30_CLK_APBIF } ,
{ . con_id = " hda2hdmi " , . dev_id = " tegra30-hda " , . dt_id = TEGRA30_CLK_HDA2HDMI } ,
2015-01-23 11:42:33 +03:00
{ . dev_id = " tegra-apbdma " , . dt_id = TEGRA30_CLK_APBDMA } ,
{ . dev_id = " rtc-tegra " , . dt_id = TEGRA30_CLK_RTC } ,
{ . dev_id = " timer " , . dt_id = TEGRA30_CLK_TIMER } ,
{ . dev_id = " tegra-kbc " , . dt_id = TEGRA30_CLK_KBC } ,
{ . dev_id = " fsl-tegra-udc " , . dt_id = TEGRA30_CLK_USBD } ,
{ . dev_id = " tegra-ehci.1 " , . dt_id = TEGRA30_CLK_USB2 } ,
{ . dev_id = " tegra-ehci.2 " , . dt_id = TEGRA30_CLK_USB2 } ,
{ . dev_id = " kfuse-tegra " , . dt_id = TEGRA30_CLK_KFUSE } ,
{ . dev_id = " tegra_sata_cold " , . dt_id = TEGRA30_CLK_SATA_COLD } ,
{ . dev_id = " dtv " , . dt_id = TEGRA30_CLK_DTV } ,
2013-10-07 15:49:04 +04:00
{ . dev_id = " tegra30-i2s.0 " , . dt_id = TEGRA30_CLK_I2S0 } ,
{ . dev_id = " tegra30-i2s.1 " , . dt_id = TEGRA30_CLK_I2S1 } ,
{ . dev_id = " tegra30-i2s.2 " , . dt_id = TEGRA30_CLK_I2S2 } ,
{ . dev_id = " tegra30-i2s.3 " , . dt_id = TEGRA30_CLK_I2S3 } ,
{ . dev_id = " tegra30-i2s.4 " , . dt_id = TEGRA30_CLK_I2S4 } ,
{ . con_id = " spdif_out " , . dev_id = " tegra30-spdif " , . dt_id = TEGRA30_CLK_SPDIF_OUT } ,
{ . con_id = " spdif_in " , . dev_id = " tegra30-spdif " , . dt_id = TEGRA30_CLK_SPDIF_IN } ,
{ . con_id = " d_audio " , . dev_id = " tegra30-ahub " , . dt_id = TEGRA30_CLK_D_AUDIO } ,
{ . dev_id = " tegra30-dam.0 " , . dt_id = TEGRA30_CLK_DAM0 } ,
{ . dev_id = " tegra30-dam.1 " , . dt_id = TEGRA30_CLK_DAM1 } ,
{ . dev_id = " tegra30-dam.2 " , . dt_id = TEGRA30_CLK_DAM2 } ,
{ . con_id = " hda " , . dev_id = " tegra30-hda " , . dt_id = TEGRA30_CLK_HDA } ,
2015-04-11 00:35:57 +03:00
{ . con_id = " hda2codec_2x " , . dev_id = " tegra30-hda " , . dt_id = TEGRA30_CLK_HDA2CODEC_2X } ,
2013-10-07 15:49:04 +04:00
{ . dev_id = " spi_tegra.0 " , . dt_id = TEGRA30_CLK_SBC1 } ,
{ . dev_id = " spi_tegra.1 " , . dt_id = TEGRA30_CLK_SBC2 } ,
{ . dev_id = " spi_tegra.2 " , . dt_id = TEGRA30_CLK_SBC3 } ,
{ . dev_id = " spi_tegra.3 " , . dt_id = TEGRA30_CLK_SBC4 } ,
{ . dev_id = " spi_tegra.4 " , . dt_id = TEGRA30_CLK_SBC5 } ,
{ . dev_id = " spi_tegra.5 " , . dt_id = TEGRA30_CLK_SBC6 } ,
{ . dev_id = " tegra_sata_oob " , . dt_id = TEGRA30_CLK_SATA_OOB } ,
{ . dev_id = " tegra_sata " , . dt_id = TEGRA30_CLK_SATA } ,
{ . dev_id = " tegra_nand " , . dt_id = TEGRA30_CLK_NDFLASH } ,
{ . dev_id = " tegra_nand_speed " , . dt_id = TEGRA30_CLK_NDSPEED } ,
{ . dev_id = " vfir " , . dt_id = TEGRA30_CLK_VFIR } ,
{ . dev_id = " csite " , . dt_id = TEGRA30_CLK_CSITE } ,
{ . dev_id = " la " , . dt_id = TEGRA30_CLK_LA } ,
{ . dev_id = " tegra_w1 " , . dt_id = TEGRA30_CLK_OWR } ,
{ . dev_id = " mipi " , . dt_id = TEGRA30_CLK_MIPI } ,
{ . dev_id = " tegra-tsensor " , . dt_id = TEGRA30_CLK_TSENSOR } ,
{ . dev_id = " i2cslow " , . dt_id = TEGRA30_CLK_I2CSLOW } ,
{ . dev_id = " vde " , . dt_id = TEGRA30_CLK_VDE } ,
{ . con_id = " vi " , . dev_id = " tegra_camera " , . dt_id = TEGRA30_CLK_VI } ,
{ . dev_id = " epp " , . dt_id = TEGRA30_CLK_EPP } ,
{ . dev_id = " mpe " , . dt_id = TEGRA30_CLK_MPE } ,
{ . dev_id = " host1x " , . dt_id = TEGRA30_CLK_HOST1X } ,
{ . dev_id = " 3d " , . dt_id = TEGRA30_CLK_GR3D } ,
{ . dev_id = " 3d2 " , . dt_id = TEGRA30_CLK_GR3D2 } ,
{ . dev_id = " 2d " , . dt_id = TEGRA30_CLK_GR2D } ,
{ . dev_id = " se " , . dt_id = TEGRA30_CLK_SE } ,
{ . dev_id = " mselect " , . dt_id = TEGRA30_CLK_MSELECT } ,
{ . dev_id = " tegra-nor " , . dt_id = TEGRA30_CLK_NOR } ,
{ . dev_id = " sdhci-tegra.0 " , . dt_id = TEGRA30_CLK_SDMMC1 } ,
{ . dev_id = " sdhci-tegra.1 " , . dt_id = TEGRA30_CLK_SDMMC2 } ,
{ . dev_id = " sdhci-tegra.2 " , . dt_id = TEGRA30_CLK_SDMMC3 } ,
{ . dev_id = " sdhci-tegra.3 " , . dt_id = TEGRA30_CLK_SDMMC4 } ,
{ . dev_id = " cve " , . dt_id = TEGRA30_CLK_CVE } ,
{ . dev_id = " tvo " , . dt_id = TEGRA30_CLK_TVO } ,
{ . dev_id = " tvdac " , . dt_id = TEGRA30_CLK_TVDAC } ,
{ . dev_id = " actmon " , . dt_id = TEGRA30_CLK_ACTMON } ,
{ . con_id = " vi_sensor " , . dev_id = " tegra_camera " , . dt_id = TEGRA30_CLK_VI_SENSOR } ,
{ . con_id = " div-clk " , . dev_id = " tegra-i2c.0 " , . dt_id = TEGRA30_CLK_I2C1 } ,
{ . con_id = " div-clk " , . dev_id = " tegra-i2c.1 " , . dt_id = TEGRA30_CLK_I2C2 } ,
{ . con_id = " div-clk " , . dev_id = " tegra-i2c.2 " , . dt_id = TEGRA30_CLK_I2C3 } ,
{ . con_id = " div-clk " , . dev_id = " tegra-i2c.3 " , . dt_id = TEGRA30_CLK_I2C4 } ,
{ . con_id = " div-clk " , . dev_id = " tegra-i2c.4 " , . dt_id = TEGRA30_CLK_I2C5 } ,
{ . dev_id = " tegra_uart.0 " , . dt_id = TEGRA30_CLK_UARTA } ,
{ . dev_id = " tegra_uart.1 " , . dt_id = TEGRA30_CLK_UARTB } ,
{ . dev_id = " tegra_uart.2 " , . dt_id = TEGRA30_CLK_UARTC } ,
{ . dev_id = " tegra_uart.3 " , . dt_id = TEGRA30_CLK_UARTD } ,
{ . dev_id = " tegra_uart.4 " , . dt_id = TEGRA30_CLK_UARTE } ,
{ . dev_id = " hdmi " , . dt_id = TEGRA30_CLK_HDMI } ,
{ . dev_id = " extern1 " , . dt_id = TEGRA30_CLK_EXTERN1 } ,
{ . dev_id = " extern2 " , . dt_id = TEGRA30_CLK_EXTERN2 } ,
{ . dev_id = " extern3 " , . dt_id = TEGRA30_CLK_EXTERN3 } ,
{ . dev_id = " pwm " , . dt_id = TEGRA30_CLK_PWM } ,
{ . dev_id = " tegradc.0 " , . dt_id = TEGRA30_CLK_DISP1 } ,
{ . dev_id = " tegradc.1 " , . dt_id = TEGRA30_CLK_DISP2 } ,
{ . dev_id = " tegradc.1 " , . dt_id = TEGRA30_CLK_DSIB } ,
} ;
static struct tegra_clk tegra30_clks [ tegra_clk_max ] __initdata = {
[ tegra_clk_clk_32k ] = { . dt_id = TEGRA30_CLK_CLK_32K , . present = true } ,
[ tegra_clk_clk_m ] = { . dt_id = TEGRA30_CLK_CLK_M , . present = true } ,
[ tegra_clk_clk_m_div2 ] = { . dt_id = TEGRA30_CLK_CLK_M_DIV2 , . present = true } ,
[ tegra_clk_clk_m_div4 ] = { . dt_id = TEGRA30_CLK_CLK_M_DIV4 , . present = true } ,
[ tegra_clk_pll_ref ] = { . dt_id = TEGRA30_CLK_PLL_REF , . present = true } ,
[ tegra_clk_spdif_in_sync ] = { . dt_id = TEGRA30_CLK_SPDIF_IN_SYNC , . present = true } ,
[ tegra_clk_i2s0_sync ] = { . dt_id = TEGRA30_CLK_I2S0_SYNC , . present = true } ,
[ tegra_clk_i2s1_sync ] = { . dt_id = TEGRA30_CLK_I2S1_SYNC , . present = true } ,
[ tegra_clk_i2s2_sync ] = { . dt_id = TEGRA30_CLK_I2S2_SYNC , . present = true } ,
[ tegra_clk_i2s3_sync ] = { . dt_id = TEGRA30_CLK_I2S3_SYNC , . present = true } ,
[ tegra_clk_i2s4_sync ] = { . dt_id = TEGRA30_CLK_I2S4_SYNC , . present = true } ,
[ tegra_clk_vimclk_sync ] = { . dt_id = TEGRA30_CLK_VIMCLK_SYNC , . present = true } ,
[ tegra_clk_audio0 ] = { . dt_id = TEGRA30_CLK_AUDIO0 , . present = true } ,
[ tegra_clk_audio1 ] = { . dt_id = TEGRA30_CLK_AUDIO1 , . present = true } ,
[ tegra_clk_audio2 ] = { . dt_id = TEGRA30_CLK_AUDIO2 , . present = true } ,
[ tegra_clk_audio3 ] = { . dt_id = TEGRA30_CLK_AUDIO3 , . present = true } ,
[ tegra_clk_audio4 ] = { . dt_id = TEGRA30_CLK_AUDIO4 , . present = true } ,
[ tegra_clk_spdif ] = { . dt_id = TEGRA30_CLK_SPDIF , . present = true } ,
[ tegra_clk_audio0_mux ] = { . dt_id = TEGRA30_CLK_AUDIO0_MUX , . present = true } ,
[ tegra_clk_audio1_mux ] = { . dt_id = TEGRA30_CLK_AUDIO1_MUX , . present = true } ,
[ tegra_clk_audio2_mux ] = { . dt_id = TEGRA30_CLK_AUDIO2_MUX , . present = true } ,
[ tegra_clk_audio3_mux ] = { . dt_id = TEGRA30_CLK_AUDIO3_MUX , . present = true } ,
[ tegra_clk_audio4_mux ] = { . dt_id = TEGRA30_CLK_AUDIO4_MUX , . present = true } ,
[ tegra_clk_spdif_mux ] = { . dt_id = TEGRA30_CLK_SPDIF_MUX , . present = true } ,
[ tegra_clk_audio0_2x ] = { . dt_id = TEGRA30_CLK_AUDIO0_2X , . present = true } ,
[ tegra_clk_audio1_2x ] = { . dt_id = TEGRA30_CLK_AUDIO1_2X , . present = true } ,
[ tegra_clk_audio2_2x ] = { . dt_id = TEGRA30_CLK_AUDIO2_2X , . present = true } ,
[ tegra_clk_audio3_2x ] = { . dt_id = TEGRA30_CLK_AUDIO3_2X , . present = true } ,
[ tegra_clk_audio4_2x ] = { . dt_id = TEGRA30_CLK_AUDIO4_2X , . present = true } ,
[ tegra_clk_spdif_2x ] = { . dt_id = TEGRA30_CLK_SPDIF_2X , . present = true } ,
[ tegra_clk_clk_out_1 ] = { . dt_id = TEGRA30_CLK_CLK_OUT_1 , . present = true } ,
[ tegra_clk_clk_out_2 ] = { . dt_id = TEGRA30_CLK_CLK_OUT_2 , . present = true } ,
[ tegra_clk_clk_out_3 ] = { . dt_id = TEGRA30_CLK_CLK_OUT_3 , . present = true } ,
[ tegra_clk_blink ] = { . dt_id = TEGRA30_CLK_BLINK , . present = true } ,
[ tegra_clk_clk_out_1_mux ] = { . dt_id = TEGRA30_CLK_CLK_OUT_1_MUX , . present = true } ,
[ tegra_clk_clk_out_2_mux ] = { . dt_id = TEGRA30_CLK_CLK_OUT_2_MUX , . present = true } ,
[ tegra_clk_clk_out_3_mux ] = { . dt_id = TEGRA30_CLK_CLK_OUT_3_MUX , . present = true } ,
[ tegra_clk_hclk ] = { . dt_id = TEGRA30_CLK_HCLK , . present = true } ,
[ tegra_clk_pclk ] = { . dt_id = TEGRA30_CLK_PCLK , . present = true } ,
[ tegra_clk_i2s0 ] = { . dt_id = TEGRA30_CLK_I2S0 , . present = true } ,
[ tegra_clk_i2s1 ] = { . dt_id = TEGRA30_CLK_I2S1 , . present = true } ,
[ tegra_clk_i2s2 ] = { . dt_id = TEGRA30_CLK_I2S2 , . present = true } ,
[ tegra_clk_i2s3 ] = { . dt_id = TEGRA30_CLK_I2S3 , . present = true } ,
[ tegra_clk_i2s4 ] = { . dt_id = TEGRA30_CLK_I2S4 , . present = true } ,
[ tegra_clk_spdif_in ] = { . dt_id = TEGRA30_CLK_SPDIF_IN , . present = true } ,
[ tegra_clk_hda ] = { . dt_id = TEGRA30_CLK_HDA , . present = true } ,
[ tegra_clk_hda2codec_2x ] = { . dt_id = TEGRA30_CLK_HDA2CODEC_2X , . present = true } ,
[ tegra_clk_sbc1 ] = { . dt_id = TEGRA30_CLK_SBC1 , . present = true } ,
[ tegra_clk_sbc2 ] = { . dt_id = TEGRA30_CLK_SBC2 , . present = true } ,
[ tegra_clk_sbc3 ] = { . dt_id = TEGRA30_CLK_SBC3 , . present = true } ,
[ tegra_clk_sbc4 ] = { . dt_id = TEGRA30_CLK_SBC4 , . present = true } ,
[ tegra_clk_sbc5 ] = { . dt_id = TEGRA30_CLK_SBC5 , . present = true } ,
[ tegra_clk_sbc6 ] = { . dt_id = TEGRA30_CLK_SBC6 , . present = true } ,
[ tegra_clk_ndflash ] = { . dt_id = TEGRA30_CLK_NDFLASH , . present = true } ,
[ tegra_clk_ndspeed ] = { . dt_id = TEGRA30_CLK_NDSPEED , . present = true } ,
[ tegra_clk_vfir ] = { . dt_id = TEGRA30_CLK_VFIR , . present = true } ,
[ tegra_clk_la ] = { . dt_id = TEGRA30_CLK_LA , . present = true } ,
[ tegra_clk_csite ] = { . dt_id = TEGRA30_CLK_CSITE , . present = true } ,
[ tegra_clk_owr ] = { . dt_id = TEGRA30_CLK_OWR , . present = true } ,
[ tegra_clk_mipi ] = { . dt_id = TEGRA30_CLK_MIPI , . present = true } ,
[ tegra_clk_tsensor ] = { . dt_id = TEGRA30_CLK_TSENSOR , . present = true } ,
[ tegra_clk_i2cslow ] = { . dt_id = TEGRA30_CLK_I2CSLOW , . present = true } ,
[ tegra_clk_vde ] = { . dt_id = TEGRA30_CLK_VDE , . present = true } ,
[ tegra_clk_vi ] = { . dt_id = TEGRA30_CLK_VI , . present = true } ,
[ tegra_clk_epp ] = { . dt_id = TEGRA30_CLK_EPP , . present = true } ,
[ tegra_clk_mpe ] = { . dt_id = TEGRA30_CLK_MPE , . present = true } ,
[ tegra_clk_host1x ] = { . dt_id = TEGRA30_CLK_HOST1X , . present = true } ,
[ tegra_clk_gr2d ] = { . dt_id = TEGRA30_CLK_GR2D , . present = true } ,
[ tegra_clk_gr3d ] = { . dt_id = TEGRA30_CLK_GR3D , . present = true } ,
[ tegra_clk_mselect ] = { . dt_id = TEGRA30_CLK_MSELECT , . present = true } ,
[ tegra_clk_nor ] = { . dt_id = TEGRA30_CLK_NOR , . present = true } ,
[ tegra_clk_sdmmc1 ] = { . dt_id = TEGRA30_CLK_SDMMC1 , . present = true } ,
[ tegra_clk_sdmmc2 ] = { . dt_id = TEGRA30_CLK_SDMMC2 , . present = true } ,
[ tegra_clk_sdmmc3 ] = { . dt_id = TEGRA30_CLK_SDMMC3 , . present = true } ,
[ tegra_clk_sdmmc4 ] = { . dt_id = TEGRA30_CLK_SDMMC4 , . present = true } ,
[ tegra_clk_cve ] = { . dt_id = TEGRA30_CLK_CVE , . present = true } ,
[ tegra_clk_tvo ] = { . dt_id = TEGRA30_CLK_TVO , . present = true } ,
[ tegra_clk_tvdac ] = { . dt_id = TEGRA30_CLK_TVDAC , . present = true } ,
[ tegra_clk_actmon ] = { . dt_id = TEGRA30_CLK_ACTMON , . present = true } ,
[ tegra_clk_vi_sensor ] = { . dt_id = TEGRA30_CLK_VI_SENSOR , . present = true } ,
[ tegra_clk_i2c1 ] = { . dt_id = TEGRA30_CLK_I2C1 , . present = true } ,
[ tegra_clk_i2c2 ] = { . dt_id = TEGRA30_CLK_I2C2 , . present = true } ,
[ tegra_clk_i2c3 ] = { . dt_id = TEGRA30_CLK_I2C3 , . present = true } ,
[ tegra_clk_i2c4 ] = { . dt_id = TEGRA30_CLK_I2C4 , . present = true } ,
[ tegra_clk_i2c5 ] = { . dt_id = TEGRA30_CLK_I2C5 , . present = true } ,
[ tegra_clk_uarta ] = { . dt_id = TEGRA30_CLK_UARTA , . present = true } ,
[ tegra_clk_uartb ] = { . dt_id = TEGRA30_CLK_UARTB , . present = true } ,
[ tegra_clk_uartc ] = { . dt_id = TEGRA30_CLK_UARTC , . present = true } ,
[ tegra_clk_uartd ] = { . dt_id = TEGRA30_CLK_UARTD , . present = true } ,
[ tegra_clk_uarte ] = { . dt_id = TEGRA30_CLK_UARTE , . present = true } ,
[ tegra_clk_extern1 ] = { . dt_id = TEGRA30_CLK_EXTERN1 , . present = true } ,
[ tegra_clk_extern2 ] = { . dt_id = TEGRA30_CLK_EXTERN2 , . present = true } ,
[ tegra_clk_extern3 ] = { . dt_id = TEGRA30_CLK_EXTERN3 , . present = true } ,
[ tegra_clk_disp1 ] = { . dt_id = TEGRA30_CLK_DISP1 , . present = true } ,
[ tegra_clk_disp2 ] = { . dt_id = TEGRA30_CLK_DISP2 , . present = true } ,
2017-10-04 02:02:38 +03:00
[ tegra_clk_ahbdma ] = { . dt_id = TEGRA30_CLK_AHBDMA , . present = true } ,
2013-10-07 15:49:04 +04:00
[ tegra_clk_apbdma ] = { . dt_id = TEGRA30_CLK_APBDMA , . present = true } ,
[ tegra_clk_rtc ] = { . dt_id = TEGRA30_CLK_RTC , . present = true } ,
[ tegra_clk_timer ] = { . dt_id = TEGRA30_CLK_TIMER , . present = true } ,
[ tegra_clk_kbc ] = { . dt_id = TEGRA30_CLK_KBC , . present = true } ,
[ tegra_clk_csus ] = { . dt_id = TEGRA30_CLK_CSUS , . present = true } ,
[ tegra_clk_vcp ] = { . dt_id = TEGRA30_CLK_VCP , . present = true } ,
[ tegra_clk_bsea ] = { . dt_id = TEGRA30_CLK_BSEA , . present = true } ,
[ tegra_clk_bsev ] = { . dt_id = TEGRA30_CLK_BSEV , . present = true } ,
[ tegra_clk_usbd ] = { . dt_id = TEGRA30_CLK_USBD , . present = true } ,
[ tegra_clk_usb2 ] = { . dt_id = TEGRA30_CLK_USB2 , . present = true } ,
[ tegra_clk_usb3 ] = { . dt_id = TEGRA30_CLK_USB3 , . present = true } ,
[ tegra_clk_csi ] = { . dt_id = TEGRA30_CLK_CSI , . present = true } ,
[ tegra_clk_isp ] = { . dt_id = TEGRA30_CLK_ISP , . present = true } ,
[ tegra_clk_kfuse ] = { . dt_id = TEGRA30_CLK_KFUSE , . present = true } ,
[ tegra_clk_fuse ] = { . dt_id = TEGRA30_CLK_FUSE , . present = true } ,
[ tegra_clk_fuse_burn ] = { . dt_id = TEGRA30_CLK_FUSE_BURN , . present = true } ,
[ tegra_clk_apbif ] = { . dt_id = TEGRA30_CLK_APBIF , . present = true } ,
[ tegra_clk_hda2hdmi ] = { . dt_id = TEGRA30_CLK_HDA2HDMI , . present = true } ,
[ tegra_clk_sata_cold ] = { . dt_id = TEGRA30_CLK_SATA_COLD , . present = true } ,
[ tegra_clk_sata_oob ] = { . dt_id = TEGRA30_CLK_SATA_OOB , . present = true } ,
[ tegra_clk_sata ] = { . dt_id = TEGRA30_CLK_SATA , . present = true } ,
[ tegra_clk_dtv ] = { . dt_id = TEGRA30_CLK_DTV , . present = true } ,
[ tegra_clk_pll_p ] = { . dt_id = TEGRA30_CLK_PLL_P , . present = true } ,
[ tegra_clk_pll_p_out1 ] = { . dt_id = TEGRA30_CLK_PLL_P_OUT1 , . present = true } ,
[ tegra_clk_pll_p_out2 ] = { . dt_id = TEGRA30_CLK_PLL_P_OUT2 , . present = true } ,
[ tegra_clk_pll_p_out3 ] = { . dt_id = TEGRA30_CLK_PLL_P_OUT3 , . present = true } ,
[ tegra_clk_pll_p_out4 ] = { . dt_id = TEGRA30_CLK_PLL_P_OUT4 , . present = true } ,
[ tegra_clk_pll_a ] = { . dt_id = TEGRA30_CLK_PLL_A , . present = true } ,
[ tegra_clk_pll_a_out0 ] = { . dt_id = TEGRA30_CLK_PLL_A_OUT0 , . present = true } ,
2017-02-28 17:37:17 +03:00
[ tegra_clk_cec ] = { . dt_id = TEGRA30_CLK_CEC , . present = true } ,
2018-01-10 16:59:42 +03:00
[ tegra_clk_emc ] = { . dt_id = TEGRA30_CLK_EMC , . present = true } ,
2013-10-07 15:49:04 +04:00
} ;
2013-01-11 11:46:25 +04:00
2015-11-18 16:10:02 +03:00
static const char * pll_e_parents [ ] = { " pll_ref " , " pll_p " } ;
2013-01-11 11:46:25 +04:00
static void __init tegra30_pll_init ( void )
{
struct clk * clk ;
/* PLLC */
clk = tegra_clk_register_pll ( " pll_c " , " pll_ref " , clk_base , pmc_base , 0 ,
2015-11-18 16:04:20 +03:00
& pll_c_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_C ] = clk ;
2013-01-11 11:46:25 +04:00
/* 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 ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_C_OUT1 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLM */
clk = tegra_clk_register_pll ( " pll_m " , " pll_ref " , clk_base , pmc_base ,
2018-01-10 16:59:42 +03:00
CLK_SET_RATE_GATE , & pll_m_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_M ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLM_OUT1 */
clk = tegra_clk_register_divider ( " pll_m_out1_div " , " pll_m " ,
clk_base + PLLM_OUT , 0 , TEGRA_DIVIDER_ROUND_UP ,
8 , 8 , 1 , NULL ) ;
clk = tegra_clk_register_pll_out ( " pll_m_out1 " , " pll_m_out1_div " ,
2018-01-10 16:59:42 +03:00
clk_base + PLLM_OUT , 1 , 0 ,
2013-01-11 11:46:25 +04:00
CLK_SET_RATE_PARENT , 0 , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_M_OUT1 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLX */
clk = tegra_clk_register_pll ( " pll_x " , " pll_ref " , clk_base , pmc_base , 0 ,
2013-10-04 18:28:34 +04:00
& pll_x_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_X ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLX_OUT0 */
clk = clk_register_fixed_factor ( NULL , " pll_x_out0 " , " pll_x " ,
CLK_SET_RATE_PARENT , 1 , 2 ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_X_OUT0 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLU */
2016-05-26 19:41:31 +03:00
clk = tegra_clk_register_pllu ( " pll_u " , " pll_ref " , clk_base , 0 ,
& pll_u_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_U ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLD */
clk = tegra_clk_register_pll ( " pll_d " , " pll_ref " , clk_base , pmc_base , 0 ,
2013-10-04 18:28:34 +04:00
& pll_d_params , & pll_d_lock ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_D ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLD_OUT0 */
clk = clk_register_fixed_factor ( NULL , " pll_d_out0 " , " pll_d " ,
CLK_SET_RATE_PARENT , 1 , 2 ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_D_OUT0 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLD2 */
clk = tegra_clk_register_pll ( " pll_d2 " , " pll_ref " , clk_base , pmc_base , 0 ,
2013-10-04 18:28:34 +04:00
& pll_d2_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_D2 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLD2_OUT0 */
clk = clk_register_fixed_factor ( NULL , " pll_d2_out0 " , " pll_d2 " ,
CLK_SET_RATE_PARENT , 1 , 2 ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_D2_OUT0 ] = clk ;
2013-01-11 11:46:25 +04:00
/* PLLE */
clk = clk_register_mux ( NULL , " pll_e_mux " , pll_e_parents ,
2013-07-29 15:25:01 +04:00
ARRAY_SIZE ( pll_e_parents ) ,
CLK_SET_RATE_NO_REPARENT ,
2013-01-11 11:46:25 +04:00
clk_base + PLLE_AUX , 2 , 1 , 0 , NULL ) ;
clk = tegra_clk_register_plle ( " pll_e " , " pll_e_mux " , clk_base , pmc_base ,
2013-10-04 18:28:34 +04:00
CLK_GET_RATE_NOCACHE , & pll_e_params , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PLL_E ] = clk ;
2013-01-11 11:46:25 +04:00
}
2013-02-07 20:30:36 +04:00
static const char * cclk_g_parents [ ] = { " clk_m " , " pll_c " , " clk_32k " , " pll_m " ,
" pll_p_cclkg " , " pll_p_out4_cclkg " ,
" pll_p_out3_cclkg " , " unused " , " pll_x " } ;
static const char * cclk_lp_parents [ ] = { " clk_m " , " pll_c " , " clk_32k " , " pll_m " ,
" pll_p_cclklp " , " pll_p_out4_cclklp " ,
" pll_p_out3_cclklp " , " unused " , " pll_x " ,
" pll_x_out0 " } ;
static const char * sclk_parents [ ] = { " clk_m " , " pll_c_out1 " , " pll_p_out4 " ,
" pll_p_out3 " , " pll_p_out2 " , " unused " ,
" clk_32k " , " pll_m_out1 " } ;
2013-01-11 11:46:25 +04:00
static void __init tegra30_super_clk_init ( void )
{
struct clk * clk ;
/*
* Clock input to cclk_g divided from pll_p using
* U71 divider of cclk_g .
*/
clk = tegra_clk_register_divider ( " pll_p_cclkg " , " pll_p " ,
clk_base + SUPER_CCLKG_DIVIDER , 0 ,
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_cclkg " , NULL ) ;
/*
* Clock input to cclk_g divided from pll_p_out3 using
* U71 divider of cclk_g .
*/
clk = tegra_clk_register_divider ( " pll_p_out3_cclkg " , " pll_p_out3 " ,
clk_base + SUPER_CCLKG_DIVIDER , 0 ,
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_out3_cclkg " , NULL ) ;
/*
* Clock input to cclk_g divided from pll_p_out4 using
* U71 divider of cclk_g .
*/
clk = tegra_clk_register_divider ( " pll_p_out4_cclkg " , " pll_p_out4 " ,
clk_base + SUPER_CCLKG_DIVIDER , 0 ,
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_out4_cclkg " , NULL ) ;
/* CCLKG */
clk = tegra_clk_register_super_mux ( " cclk_g " , cclk_g_parents ,
ARRAY_SIZE ( cclk_g_parents ) ,
CLK_SET_RATE_PARENT ,
clk_base + CCLKG_BURST_POLICY ,
0 , 4 , 0 , 0 , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_CCLK_G ] = clk ;
2013-01-11 11:46:25 +04:00
/*
* Clock input to cclk_lp divided from pll_p using
* U71 divider of cclk_lp .
*/
clk = tegra_clk_register_divider ( " pll_p_cclklp " , " pll_p " ,
clk_base + SUPER_CCLKLP_DIVIDER , 0 ,
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_cclklp " , NULL ) ;
/*
* Clock input to cclk_lp divided from pll_p_out3 using
* U71 divider of cclk_lp .
*/
clk = tegra_clk_register_divider ( " pll_p_out3_cclklp " , " pll_p_out3 " ,
2017-09-19 05:48:10 +03:00
clk_base + SUPER_CCLKLP_DIVIDER , 0 ,
2013-01-11 11:46:25 +04:00
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_out3_cclklp " , NULL ) ;
/*
* Clock input to cclk_lp divided from pll_p_out4 using
* U71 divider of cclk_lp .
*/
clk = tegra_clk_register_divider ( " pll_p_out4_cclklp " , " pll_p_out4 " ,
clk_base + SUPER_CCLKLP_DIVIDER , 0 ,
TEGRA_DIVIDER_INT , 16 , 8 , 1 , NULL ) ;
clk_register_clkdev ( clk , " pll_p_out4_cclklp " , NULL ) ;
/* CCLKLP */
clk = tegra_clk_register_super_mux ( " cclk_lp " , cclk_lp_parents ,
ARRAY_SIZE ( cclk_lp_parents ) ,
CLK_SET_RATE_PARENT ,
clk_base + CCLKLP_BURST_POLICY ,
TEGRA_DIVIDER_2 , 4 , 8 , 9 ,
NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_CCLK_LP ] = clk ;
2013-01-11 11:46:25 +04:00
/* SCLK */
clk = tegra_clk_register_super_mux ( " sclk " , sclk_parents ,
ARRAY_SIZE ( sclk_parents ) ,
2018-01-10 16:59:42 +03:00
CLK_SET_RATE_PARENT | CLK_IS_CRITICAL ,
2013-01-11 11:46:25 +04:00
clk_base + SCLK_BURST_POLICY ,
0 , 4 , 0 , 0 , NULL ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_SCLK ] = clk ;
2013-01-11 11:46:25 +04:00
/* twd */
clk = clk_register_fixed_factor ( NULL , " twd " , " cclk_g " ,
CLK_SET_RATE_PARENT , 1 , 2 ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_TWD ] = clk ;
tegra_super_clk_gen4_init ( clk_base , pmc_base , tegra30_clks , NULL ) ;
2013-01-11 11:46:25 +04:00
}
static const char * mux_pllacp_clkm [ ] = { " pll_a_out0 " , " unused " , " pll_p " ,
" clk_m " } ;
static const char * mux_pllpcm_clkm [ ] = { " pll_p " , " pll_c " , " pll_m " , " clk_m " } ;
static const char * mux_pllmcp_clkm [ ] = { " pll_m " , " pll_c " , " pll_p " , " clk_m " } ;
static const char * spdif_out_parents [ ] = { " pll_a_out0 " , " spdif_2x " , " pll_p " ,
" clk_m " } ;
static const char * mux_pllmcpa [ ] = { " pll_m " , " pll_c " , " pll_p " , " pll_a_out0 " } ;
static const char * mux_pllpmdacd2_clkm [ ] = { " pll_p " , " pll_m " , " pll_d_out0 " ,
" pll_a_out0 " , " pll_c " ,
" pll_d2_out0 " , " clk_m " } ;
static const char * mux_plld_out0_plld2_out0 [ ] = { " pll_d_out0 " ,
" pll_d2_out0 " } ;
2013-10-29 19:51:12 +04:00
static const char * pwm_parents [ ] = { " pll_p " , " pll_c " , " clk_32k " , " clk_m " } ;
2013-01-11 11:46:25 +04:00
static struct tegra_periph_init_data tegra_periph_clk_list [ ] = {
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA_MUX ( " spdif_out " , spdif_out_parents , CLK_SOURCE_SPDIF_OUT , 10 , TEGRA_PERIPH_ON_APB , TEGRA30_CLK_SPDIF_OUT ) ,
TEGRA_INIT_DATA_MUX ( " d_audio " , mux_pllacp_clkm , CLK_SOURCE_D_AUDIO , 106 , 0 , TEGRA30_CLK_D_AUDIO ) ,
TEGRA_INIT_DATA_MUX ( " dam0 " , mux_pllacp_clkm , CLK_SOURCE_DAM0 , 108 , 0 , TEGRA30_CLK_DAM0 ) ,
TEGRA_INIT_DATA_MUX ( " dam1 " , mux_pllacp_clkm , CLK_SOURCE_DAM1 , 109 , 0 , TEGRA30_CLK_DAM1 ) ,
TEGRA_INIT_DATA_MUX ( " dam2 " , mux_pllacp_clkm , CLK_SOURCE_DAM2 , 110 , 0 , TEGRA30_CLK_DAM2 ) ,
TEGRA_INIT_DATA_INT ( " 3d2 " , mux_pllmcpa , CLK_SOURCE_3D2 , 98 , TEGRA_PERIPH_MANUAL_RESET , TEGRA30_CLK_GR3D2 ) ,
TEGRA_INIT_DATA_INT ( " se " , mux_pllpcm_clkm , CLK_SOURCE_SE , 127 , 0 , TEGRA30_CLK_SE ) ,
TEGRA_INIT_DATA_MUX8 ( " hdmi " , mux_pllpmdacd2_clkm , CLK_SOURCE_HDMI , 51 , 0 , TEGRA30_CLK_HDMI ) ,
2013-10-29 19:51:12 +04:00
TEGRA_INIT_DATA ( " pwm " , NULL , NULL , pwm_parents , CLK_SOURCE_PWM , 28 , 2 , 0 , 0 , 8 , 1 , 0 , 17 , TEGRA_PERIPH_ON_APB , TEGRA30_CLK_PWM ) ,
2013-01-11 11:46:25 +04:00
} ;
static struct tegra_periph_init_data tegra_periph_nodiv_clk_list [ ] = {
2013-10-07 15:49:04 +04:00
TEGRA_INIT_DATA_NODIV ( " dsib " , mux_plld_out0_plld2_out0 , CLK_SOURCE_DSIB , 25 , 1 , 82 , 0 , TEGRA30_CLK_DSIB ) ,
2013-01-11 11:46:25 +04:00
} ;
static void __init tegra30_periph_clk_init ( void )
{
struct tegra_periph_init_data * data ;
struct clk * clk ;
2015-11-18 16:04:20 +03:00
unsigned int i ;
2013-01-11 11:46:25 +04:00
/* dsia */
clk = tegra_clk_register_periph_gate ( " dsia " , " pll_d_out0 " , 0 , clk_base ,
2013-08-22 19:44:06 +04:00
0 , 48 , periph_clk_enb_refcnt ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_DSIA ] = clk ;
2013-01-11 11:46:25 +04:00
/* pcie */
clk = tegra_clk_register_periph_gate ( " pcie " , " clk_m " , 0 , clk_base , 0 ,
2013-08-22 19:44:06 +04:00
70 , periph_clk_enb_refcnt ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_PCIE ] = clk ;
2013-01-11 11:46:25 +04:00
/* afi */
clk = tegra_clk_register_periph_gate ( " afi " , " clk_m " , 0 , clk_base , 0 , 72 ,
2013-08-22 19:44:06 +04:00
periph_clk_enb_refcnt ) ;
2013-10-07 15:49:04 +04:00
clks [ TEGRA30_CLK_AFI ] = clk ;
2013-01-11 11:46:25 +04:00
/* emc */
clk = clk_register_mux ( NULL , " emc_mux " , mux_pllmcp_clkm ,
2013-07-29 15:25:01 +04:00
ARRAY_SIZE ( mux_pllmcp_clkm ) ,
CLK_SET_RATE_NO_REPARENT ,
2013-01-11 11:46:25 +04:00
clk_base + CLK_SOURCE_EMC ,
2014-07-29 12:17:53 +04:00
30 , 2 , 0 , & emc_lock ) ;
2013-10-07 15:49:04 +04:00
2014-07-29 12:17:53 +04:00
clk = tegra_clk_register_mc ( " mc " , " emc_mux " , clk_base + CLK_SOURCE_EMC ,
& emc_lock ) ;
clks [ TEGRA30_CLK_MC ] = clk ;
2013-10-07 15:49:04 +04:00
/* cml0 */
clk = clk_register_gate ( NULL , " cml0 " , " pll_e " , 0 , clk_base + PLLE_AUX ,
0 , 0 , & cml_lock ) ;
clks [ TEGRA30_CLK_CML0 ] = clk ;
/* cml1 */
clk = clk_register_gate ( NULL , " cml1 " , " pll_e " , 0 , clk_base + PLLE_AUX ,
1 , 0 , & cml_lock ) ;
clks [ TEGRA30_CLK_CML1 ] = clk ;
2013-01-11 11:46:25 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( tegra_periph_clk_list ) ; i + + ) {
data = & tegra_periph_clk_list [ i ] ;
2017-08-30 13:19:08 +03:00
clk = tegra_clk_register_periph_data ( clk_base , data ) ;
2013-01-11 11:46:25 +04:00
clks [ data - > clk_id ] = clk ;
}
for ( i = 0 ; i < ARRAY_SIZE ( tegra_periph_nodiv_clk_list ) ; i + + ) {
data = & tegra_periph_nodiv_clk_list [ i ] ;
clk = tegra_clk_register_periph_nodiv ( data - > name ,
2013-09-04 18:04:19 +04:00
data - > p . parent_names ,
2013-01-11 11:46:25 +04:00
data - > num_parents , & data - > periph ,
clk_base , data - > offset ) ;
clks [ data - > clk_id ] = clk ;
}
2013-10-07 15:49:04 +04:00
tegra_periph_clk_init ( clk_base , pmc_base , tegra30_clks , & pll_p_params ) ;
2013-01-11 11:46:25 +04:00
}
/* Tegra30 CPU clock and reset control functions */
static void tegra30_wait_cpu_in_reset ( u32 cpu )
{
unsigned int reg ;
do {
reg = readl ( clk_base +
TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS ) ;
cpu_relax ( ) ;
} while ( ! ( reg & ( 1 < < cpu ) ) ) ; /* check CPU been reset or not */
return ;
}
static void tegra30_put_cpu_in_reset ( u32 cpu )
{
writel ( CPU_RESET ( cpu ) ,
clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET ) ;
dmb ( ) ;
}
static void tegra30_cpu_out_of_reset ( u32 cpu )
{
writel ( CPU_RESET ( cpu ) ,
clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR ) ;
wmb ( ) ;
}
static void tegra30_enable_cpu_clock ( u32 cpu )
{
unsigned int reg ;
writel ( CPU_CLOCK ( cpu ) ,
clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR ) ;
reg = readl ( clk_base +
TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR ) ;
}
static void tegra30_disable_cpu_clock ( u32 cpu )
{
unsigned int reg ;
reg = readl ( clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX ) ;
writel ( reg | CPU_CLOCK ( cpu ) ,
clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX ) ;
}
# ifdef CONFIG_PM_SLEEP
static bool tegra30_cpu_rail_off_ready ( void )
{
unsigned int cpu_rst_status ;
int cpu_pwr_status ;
cpu_rst_status = readl ( clk_base +
TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS ) ;
2018-12-03 13:28:41 +03:00
cpu_pwr_status = tegra_pmc_cpu_is_powered ( 1 ) | |
tegra_pmc_cpu_is_powered ( 2 ) | |
tegra_pmc_cpu_is_powered ( 3 ) ;
2013-01-11 11:46:25 +04:00
if ( ( ( cpu_rst_status & 0xE ) ! = 0xE ) | | cpu_pwr_status )
return false ;
return true ;
}
static void tegra30_cpu_clock_suspend ( void )
{
/* switch coresite to clk_m, save off original source */
tegra30_cpu_clk_sctx . clk_csite_src =
readl ( clk_base + CLK_RESET_SOURCE_CSITE ) ;
2015-11-18 16:04:20 +03:00
writel ( 3 < < 30 , clk_base + CLK_RESET_SOURCE_CSITE ) ;
2013-01-11 11:46:25 +04:00
tegra30_cpu_clk_sctx . cpu_burst =
readl ( clk_base + CLK_RESET_CCLK_BURST ) ;
tegra30_cpu_clk_sctx . pllx_base =
readl ( clk_base + CLK_RESET_PLLX_BASE ) ;
tegra30_cpu_clk_sctx . pllx_misc =
readl ( clk_base + CLK_RESET_PLLX_MISC ) ;
tegra30_cpu_clk_sctx . cclk_divider =
readl ( clk_base + CLK_RESET_CCLK_DIVIDER ) ;
}
static void tegra30_cpu_clock_resume ( void )
{
unsigned int reg , policy ;
/* Is CPU complex already running on PLLX? */
reg = readl ( clk_base + CLK_RESET_CCLK_BURST ) ;
policy = ( reg > > CLK_RESET_CCLK_BURST_POLICY_SHIFT ) & 0xF ;
if ( policy = = CLK_RESET_CCLK_IDLE_POLICY )
reg = ( reg > > CLK_RESET_CCLK_IDLE_POLICY_SHIFT ) & 0xF ;
else if ( policy = = CLK_RESET_CCLK_RUN_POLICY )
reg = ( reg > > CLK_RESET_CCLK_RUN_POLICY_SHIFT ) & 0xF ;
else
BUG ( ) ;
if ( reg ! = CLK_RESET_CCLK_BURST_POLICY_PLLX ) {
/* restore PLLX settings if CPU is on different PLL */
writel ( tegra30_cpu_clk_sctx . pllx_misc ,
clk_base + CLK_RESET_PLLX_MISC ) ;
writel ( tegra30_cpu_clk_sctx . pllx_base ,
clk_base + CLK_RESET_PLLX_BASE ) ;
/* wait for PLL stabilization if PLLX was enabled */
if ( tegra30_cpu_clk_sctx . pllx_base & ( 1 < < 30 ) )
udelay ( 300 ) ;
}
/*
* Restore original burst policy setting for calls resulting from CPU
* LP2 in idle or system suspend .
*/
writel ( tegra30_cpu_clk_sctx . cclk_divider ,
clk_base + CLK_RESET_CCLK_DIVIDER ) ;
writel ( tegra30_cpu_clk_sctx . cpu_burst ,
clk_base + CLK_RESET_CCLK_BURST ) ;
writel ( tegra30_cpu_clk_sctx . clk_csite_src ,
clk_base + CLK_RESET_SOURCE_CSITE ) ;
}
# endif
static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
. wait_for_reset = tegra30_wait_cpu_in_reset ,
. put_in_reset = tegra30_put_cpu_in_reset ,
. out_of_reset = tegra30_cpu_out_of_reset ,
. enable_clock = tegra30_enable_cpu_clock ,
. disable_clock = tegra30_disable_cpu_clock ,
# ifdef CONFIG_PM_SLEEP
. rail_off_ready = tegra30_cpu_rail_off_ready ,
. suspend = tegra30_cpu_clock_suspend ,
. resume = tegra30_cpu_clock_resume ,
# endif
} ;
2013-08-08 08:25:49 +04:00
static struct tegra_clk_init_table init_table [ ] __initdata = {
2015-11-18 16:10:02 +03:00
{ TEGRA30_CLK_UARTA , TEGRA30_CLK_PLL_P , 408000000 , 0 } ,
{ TEGRA30_CLK_UARTB , TEGRA30_CLK_PLL_P , 408000000 , 0 } ,
{ TEGRA30_CLK_UARTC , TEGRA30_CLK_PLL_P , 408000000 , 0 } ,
{ TEGRA30_CLK_UARTD , TEGRA30_CLK_PLL_P , 408000000 , 0 } ,
{ TEGRA30_CLK_UARTE , TEGRA30_CLK_PLL_P , 408000000 , 0 } ,
{ TEGRA30_CLK_PLL_A , TEGRA30_CLK_CLK_MAX , 564480000 , 1 } ,
{ TEGRA30_CLK_PLL_A_OUT0 , TEGRA30_CLK_CLK_MAX , 11289600 , 1 } ,
{ TEGRA30_CLK_EXTERN1 , TEGRA30_CLK_PLL_A_OUT0 , 0 , 1 } ,
{ TEGRA30_CLK_CLK_OUT_1_MUX , TEGRA30_CLK_EXTERN1 , 0 , 0 } ,
{ TEGRA30_CLK_CLK_OUT_1 , TEGRA30_CLK_CLK_MAX , 0 , 1 } ,
{ TEGRA30_CLK_BLINK , TEGRA30_CLK_CLK_MAX , 0 , 1 } ,
{ TEGRA30_CLK_I2S0 , TEGRA30_CLK_PLL_A_OUT0 , 11289600 , 0 } ,
{ TEGRA30_CLK_I2S1 , TEGRA30_CLK_PLL_A_OUT0 , 11289600 , 0 } ,
{ TEGRA30_CLK_I2S2 , TEGRA30_CLK_PLL_A_OUT0 , 11289600 , 0 } ,
{ TEGRA30_CLK_I2S3 , TEGRA30_CLK_PLL_A_OUT0 , 11289600 , 0 } ,
{ TEGRA30_CLK_I2S4 , TEGRA30_CLK_PLL_A_OUT0 , 11289600 , 0 } ,
{ TEGRA30_CLK_SDMMC1 , TEGRA30_CLK_PLL_P , 48000000 , 0 } ,
{ TEGRA30_CLK_SDMMC2 , TEGRA30_CLK_PLL_P , 48000000 , 0 } ,
{ TEGRA30_CLK_SDMMC3 , TEGRA30_CLK_PLL_P , 48000000 , 0 } ,
{ TEGRA30_CLK_CSITE , TEGRA30_CLK_CLK_MAX , 0 , 1 } ,
{ TEGRA30_CLK_MSELECT , TEGRA30_CLK_CLK_MAX , 0 , 1 } ,
{ TEGRA30_CLK_SBC1 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
{ TEGRA30_CLK_SBC2 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
{ TEGRA30_CLK_SBC3 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
{ TEGRA30_CLK_SBC4 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
{ TEGRA30_CLK_SBC5 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
{ TEGRA30_CLK_SBC6 , TEGRA30_CLK_PLL_P , 100000000 , 0 } ,
2016-02-29 23:46:06 +03:00
{ TEGRA30_CLK_PLL_C , TEGRA30_CLK_CLK_MAX , 600000000 , 0 } ,
2015-11-18 16:10:02 +03:00
{ TEGRA30_CLK_HOST1X , TEGRA30_CLK_PLL_C , 150000000 , 0 } ,
{ TEGRA30_CLK_DISP1 , TEGRA30_CLK_PLL_P , 600000000 , 0 } ,
{ TEGRA30_CLK_DISP2 , TEGRA30_CLK_PLL_P , 600000000 , 0 } ,
{ TEGRA30_CLK_TWD , TEGRA30_CLK_CLK_MAX , 0 , 1 } ,
{ TEGRA30_CLK_GR2D , TEGRA30_CLK_PLL_C , 300000000 , 0 } ,
{ TEGRA30_CLK_GR3D , TEGRA30_CLK_PLL_C , 300000000 , 0 } ,
{ TEGRA30_CLK_GR3D2 , TEGRA30_CLK_PLL_C , 300000000 , 0 } ,
2016-02-29 23:46:07 +03:00
{ TEGRA30_CLK_PLL_U , TEGRA30_CLK_CLK_MAX , 480000000 , 0 } ,
2018-01-10 16:59:44 +03:00
{ TEGRA30_CLK_VDE , TEGRA30_CLK_CLK_MAX , 600000000 , 0 } ,
2018-12-03 13:28:40 +03:00
{ TEGRA30_CLK_SPDIF_IN_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_I2S0_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_I2S1_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_I2S2_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_I2S3_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_I2S4_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
{ TEGRA30_CLK_VIMCLK_SYNC , TEGRA30_CLK_CLK_MAX , 24000000 , 0 } ,
2015-11-18 16:10:02 +03:00
/* must be the last entry */
{ TEGRA30_CLK_CLK_MAX , TEGRA30_CLK_CLK_MAX , 0 , 0 } ,
2013-01-11 11:46:25 +04:00
} ;
2013-03-25 23:22:24 +04:00
static void __init tegra30_clock_apply_init_table ( void )
{
2013-10-07 15:49:04 +04:00
tegra_init_from_table ( init_table , clks , TEGRA30_CLK_CLK_MAX ) ;
2013-03-25 23:22:24 +04:00
}
2013-01-11 11:46:25 +04:00
/*
* Some clocks may be used by different drivers depending on the board
* configuration . List those here to register them twice in the clock lookup
* table under two names .
*/
static struct tegra_clk_duplicate tegra_clk_duplicates [ ] = {
2013-10-07 15:49:04 +04:00
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_USBD , " utmip-pad " , NULL ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_USBD , " tegra-ehci.0 " , NULL ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_USBD , " tegra-otg " , NULL ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_BSEV , " tegra-avp " , " bsev " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_BSEV , " nvavp " , " bsev " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_VDE , " tegra-aes " , " vde " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_BSEA , " tegra-aes " , " bsea " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_BSEA , " nvavp " , " bsea " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_CML1 , " tegra_sata_cml " , NULL ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_CML0 , " tegra_pcie " , " cml " ) ,
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_VCP , " nvavp " , " vcp " ) ,
2015-11-18 16:10:02 +03:00
/* must be the last entry */
TEGRA_CLK_DUPLICATE ( TEGRA30_CLK_CLK_MAX , NULL , NULL ) ,
2013-01-11 11:46:25 +04:00
} ;
static const struct of_device_id pmc_match [ ] __initconst = {
{ . compatible = " nvidia,tegra30-pmc " } ,
2015-11-18 16:04:20 +03:00
{ } ,
2013-01-11 11:46:25 +04:00
} ;
2015-06-19 00:28:17 +03:00
static struct tegra_audio_clk_info tegra30_audio_plls [ ] = {
{ " pll_a " , & pll_a_params , tegra_clk_pll_a , " pll_p_out1 " } ,
} ;
2013-05-27 11:40:09 +04:00
static void __init tegra30_clock_init ( struct device_node * np )
2013-01-11 11:46:25 +04:00
{
struct device_node * node ;
clk_base = of_iomap ( np , 0 ) ;
if ( ! clk_base ) {
pr_err ( " ioremap tegra30 CAR failed \n " ) ;
return ;
}
node = of_find_matching_node ( NULL , pmc_match ) ;
if ( ! node ) {
pr_err ( " Failed to find pmc node \n " ) ;
BUG ( ) ;
}
pmc_base = of_iomap ( node , 0 ) ;
if ( ! pmc_base ) {
pr_err ( " Can't map pmc registers \n " ) ;
BUG ( ) ;
}
2013-11-06 04:33:17 +04:00
clks = tegra_clk_init ( clk_base , TEGRA30_CLK_CLK_MAX ,
TEGRA30_CLK_PERIPH_BANKS ) ;
2013-09-02 16:22:02 +04:00
if ( ! clks )
2013-08-22 19:44:06 +04:00
return ;
2013-10-07 15:49:04 +04:00
if ( tegra_osc_clk_init ( clk_base , tegra30_clks , tegra30_input_freq ,
2015-03-26 19:43:56 +03:00
ARRAY_SIZE ( tegra30_input_freq ) , 1 , & input_freq ,
NULL ) < 0 )
2013-10-07 15:49:04 +04:00
return ;
tegra_fixed_clk_init ( tegra30_clks ) ;
2013-01-11 11:46:25 +04:00
tegra30_pll_init ( ) ;
tegra30_super_clk_init ( ) ;
tegra30_periph_clk_init ( ) ;
2015-06-19 00:28:17 +03:00
tegra_audio_clk_init ( clk_base , pmc_base , tegra30_clks ,
tegra30_audio_plls ,
2018-12-03 13:28:40 +03:00
ARRAY_SIZE ( tegra30_audio_plls ) , 24000000 ) ;
2013-10-07 15:49:04 +04:00
tegra_pmc_clk_init ( pmc_base , tegra30_clks ) ;
2013-01-11 11:46:25 +04:00
2013-10-07 15:49:04 +04:00
tegra_init_dup_clks ( tegra_clk_duplicates , clks , TEGRA30_CLK_CLK_MAX ) ;
2013-01-11 11:46:25 +04:00
2018-05-08 19:26:06 +03:00
tegra_add_of_provider ( np , of_clk_src_onecell_get ) ;
2013-10-07 15:49:04 +04:00
tegra_register_devclks ( devclks , ARRAY_SIZE ( devclks ) ) ;
2013-01-11 11:46:25 +04:00
2013-03-25 23:22:24 +04:00
tegra_clk_apply_init_table = tegra30_clock_apply_init_table ;
2013-01-11 11:46:25 +04:00
tegra_cpu_car_ops = & tegra30_cpu_car_ops ;
}
2013-05-27 11:40:09 +04:00
CLK_OF_DECLARE ( tegra30 , " nvidia,tegra30-car " , tegra30_clock_init ) ;