linux/drivers/clk/tegra/clk-tegra20.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   4 */
   5
   6#include <linux/io.h>
   7#include <linux/clk-provider.h>
   8#include <linux/clkdev.h>
   9#include <linux/of.h>
  10#include <linux/of_address.h>
  11#include <linux/clk/tegra.h>
  12#include <linux/delay.h>
  13#include <dt-bindings/clock/tegra20-car.h>
  14
  15#include "clk.h"
  16#include "clk-id.h"
  17
  18#define MISC_CLK_ENB 0x48
  19
  20#define OSC_CTRL 0x50
  21#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
  22#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
  23#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
  24#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
  25#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
  26#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
  27
  28#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28)
  29#define OSC_CTRL_PLL_REF_DIV_1          (0<<28)
  30#define OSC_CTRL_PLL_REF_DIV_2          (1<<28)
  31#define OSC_CTRL_PLL_REF_DIV_4          (2<<28)
  32
  33#define OSC_FREQ_DET 0x58
  34#define OSC_FREQ_DET_TRIG (1<<31)
  35
  36#define OSC_FREQ_DET_STATUS 0x5c
  37#define OSC_FREQ_DET_BUSY (1<<31)
  38#define OSC_FREQ_DET_CNT_MASK 0xFFFF
  39
  40#define TEGRA20_CLK_PERIPH_BANKS        3
  41
  42#define PLLS_BASE 0xf0
  43#define PLLS_MISC 0xf4
  44#define PLLC_BASE 0x80
  45#define PLLC_MISC 0x8c
  46#define PLLM_BASE 0x90
  47#define PLLM_MISC 0x9c
  48#define PLLP_BASE 0xa0
  49#define PLLP_MISC 0xac
  50#define PLLA_BASE 0xb0
  51#define PLLA_MISC 0xbc
  52#define PLLU_BASE 0xc0
  53#define PLLU_MISC 0xcc
  54#define PLLD_BASE 0xd0
  55#define PLLD_MISC 0xdc
  56#define PLLX_BASE 0xe0
  57#define PLLX_MISC 0xe4
  58#define PLLE_BASE 0xe8
  59#define PLLE_MISC 0xec
  60
  61#define PLL_BASE_LOCK BIT(27)
  62#define PLLE_MISC_LOCK BIT(11)
  63
  64#define PLL_MISC_LOCK_ENABLE 18
  65#define PLLDU_MISC_LOCK_ENABLE 22
  66#define PLLE_MISC_LOCK_ENABLE 9
  67
  68#define PLLC_OUT 0x84
  69#define PLLM_OUT 0x94
  70#define PLLP_OUTA 0xa4
  71#define PLLP_OUTB 0xa8
  72#define PLLA_OUT 0xb4
  73
  74#define CCLK_BURST_POLICY 0x20
  75#define SUPER_CCLK_DIVIDER 0x24
  76#define SCLK_BURST_POLICY 0x28
  77#define SUPER_SCLK_DIVIDER 0x2c
  78#define CLK_SYSTEM_RATE 0x30
  79
  80#define CCLK_BURST_POLICY_SHIFT 28
  81#define CCLK_RUN_POLICY_SHIFT   4
  82#define CCLK_IDLE_POLICY_SHIFT  0
  83#define CCLK_IDLE_POLICY        1
  84#define CCLK_RUN_POLICY         2
  85#define CCLK_BURST_POLICY_PLLX  8
  86
  87#define CLK_SOURCE_I2S1 0x100
  88#define CLK_SOURCE_I2S2 0x104
  89#define CLK_SOURCE_PWM 0x110
  90#define CLK_SOURCE_SPI 0x114
  91#define CLK_SOURCE_XIO 0x120
  92#define CLK_SOURCE_TWC 0x12c
  93#define CLK_SOURCE_IDE 0x144
  94#define CLK_SOURCE_HDMI 0x18c
  95#define CLK_SOURCE_DISP1 0x138
  96#define CLK_SOURCE_DISP2 0x13c
  97#define CLK_SOURCE_CSITE 0x1d4
  98#define CLK_SOURCE_I2C1 0x124
  99#define CLK_SOURCE_I2C2 0x198
 100#define CLK_SOURCE_I2C3 0x1b8
 101#define CLK_SOURCE_DVC 0x128
 102#define CLK_SOURCE_UARTA 0x178
 103#define CLK_SOURCE_UARTB 0x17c
 104#define CLK_SOURCE_UARTC 0x1a0
 105#define CLK_SOURCE_UARTD 0x1c0
 106#define CLK_SOURCE_UARTE 0x1c4
 107#define CLK_SOURCE_EMC 0x19c
 108
 109#define AUDIO_SYNC_CLK 0x38
 110
 111/* Tegra CPU clock and reset control regs */
 112#define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX          0x4c
 113#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET      0x340
 114#define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR      0x344
 115
 116#define CPU_CLOCK(cpu)  (0x1 << (8 + cpu))
 117#define CPU_RESET(cpu)  (0x1111ul << (cpu))
 118
 119#ifdef CONFIG_PM_SLEEP
 120static struct cpu_clk_suspend_context {
 121        u32 pllx_misc;
 122        u32 pllx_base;
 123
 124        u32 cpu_burst;
 125        u32 clk_csite_src;
 126        u32 cclk_divider;
 127} tegra20_cpu_clk_sctx;
 128#endif
 129
 130static void __iomem *clk_base;
 131static void __iomem *pmc_base;
 132
 133#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset,   \
 134                            _clk_num, _gate_flags, _clk_id)     \
 135        TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset,   \
 136                        30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,      \
 137                        _clk_num, \
 138                        _gate_flags, _clk_id)
 139
 140#define TEGRA_INIT_DATA_DIV16(_name, _parents, _offset, \
 141                              _clk_num, _gate_flags, _clk_id)   \
 142        TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset,   \
 143                        30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \
 144                        _clk_num, _gate_flags,  \
 145                        _clk_id)
 146
 147#define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \
 148                              _mux_shift, _mux_width, _clk_num, \
 149                              _gate_flags, _clk_id)                     \
 150        TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset,   \
 151                        _mux_shift, _mux_width, 0, 0, 0, 0, 0, \
 152                        _clk_num, _gate_flags,  \
 153                        _clk_id)
 154
 155static struct clk **clks;
 156
 157static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
 158        { 12000000, 600000000, 600, 12, 1, 8 },
 159        { 13000000, 600000000, 600, 13, 1, 8 },
 160        { 19200000, 600000000, 500, 16, 1, 6 },
 161        { 26000000, 600000000, 600, 26, 1, 8 },
 162        {        0,         0,   0,  0, 0, 0 },
 163};
 164
 165static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
 166        { 12000000, 666000000, 666, 12, 1, 8 },
 167        { 13000000, 666000000, 666, 13, 1, 8 },
 168        { 19200000, 666000000, 555, 16, 1, 8 },
 169        { 26000000, 666000000, 666, 26, 1, 8 },
 170        { 12000000, 600000000, 600, 12, 1, 8 },
 171        { 13000000, 600000000, 600, 13, 1, 8 },
 172        { 19200000, 600000000, 375, 12, 1, 6 },
 173        { 26000000, 600000000, 600, 26, 1, 8 },
 174        {        0,         0,   0,  0, 0, 0 },
 175};
 176
 177static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
 178        { 12000000, 216000000, 432, 12, 2, 8 },
 179        { 13000000, 216000000, 432, 13, 2, 8 },
 180        { 19200000, 216000000,  90,  4, 2, 1 },
 181        { 26000000, 216000000, 432, 26, 2, 8 },
 182        { 12000000, 432000000, 432, 12, 1, 8 },
 183        { 13000000, 432000000, 432, 13, 1, 8 },
 184        { 19200000, 432000000,  90,  4, 1, 1 },
 185        { 26000000, 432000000, 432, 26, 1, 8 },
 186        {        0,         0,   0,  0, 0, 0 },
 187};
 188
 189static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
 190        { 28800000, 56448000, 49, 25, 1, 1 },
 191        { 28800000, 73728000, 64, 25, 1, 1 },
 192        { 28800000, 24000000,  5,  6, 1, 1 },
 193        {        0,        0,  0,  0, 0, 0 },
 194};
 195
 196static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
 197        { 12000000,  216000000,  216, 12, 1,  4 },
 198        { 13000000,  216000000,  216, 13, 1,  4 },
 199        { 19200000,  216000000,  135, 12, 1,  3 },
 200        { 26000000,  216000000,  216, 26, 1,  4 },
 201        { 12000000,  594000000,  594, 12, 1,  8 },
 202        { 13000000,  594000000,  594, 13, 1,  8 },
 203        { 19200000,  594000000,  495, 16, 1,  8 },
 204        { 26000000,  594000000,  594, 26, 1,  8 },
 205        { 12000000, 1000000000, 1000, 12, 1, 12 },
 206        { 13000000, 1000000000, 1000, 13, 1, 12 },
 207        { 19200000, 1000000000,  625, 12, 1,  8 },
 208        { 26000000, 1000000000, 1000, 26, 1, 12 },
 209        {        0,          0,    0,  0, 0,  0 },
 210};
 211
 212static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
 213        { 12000000, 480000000, 960, 12, 1, 0 },
 214        { 13000000, 480000000, 960, 13, 1, 0 },
 215        { 19200000, 480000000, 200,  4, 1, 0 },
 216        { 26000000, 480000000, 960, 26, 1, 0 },
 217        {        0,         0,   0,  0, 0, 0 },
 218};
 219
 220static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
 221        /* 1 GHz */
 222        { 12000000, 1000000000, 1000, 12, 1, 12 },
 223        { 13000000, 1000000000, 1000, 13, 1, 12 },
 224        { 19200000, 1000000000,  625, 12, 1,  8 },
 225        { 26000000, 1000000000, 1000, 26, 1, 12 },
 226        /* 912 MHz */
 227        { 12000000,  912000000,  912, 12, 1, 12 },
 228        { 13000000,  912000000,  912, 13, 1, 12 },
 229        { 19200000,  912000000,  760, 16, 1,  8 },
 230        { 26000000,  912000000,  912, 26, 1, 12 },
 231        /* 816 MHz */
 232        { 12000000,  816000000,  816, 12, 1, 12 },
 233        { 13000000,  816000000,  816, 13, 1, 12 },
 234        { 19200000,  816000000,  680, 16, 1,  8 },
 235        { 26000000,  816000000,  816, 26, 1, 12 },
 236        /* 760 MHz */
 237        { 12000000,  760000000,  760, 12, 1, 12 },
 238        { 13000000,  760000000,  760, 13, 1, 12 },
 239        { 19200000,  760000000,  950, 24, 1,  8 },
 240        { 26000000,  760000000,  760, 26, 1, 12 },
 241        /* 750 MHz */
 242        { 12000000,  750000000,  750, 12, 1, 12 },
 243        { 13000000,  750000000,  750, 13, 1, 12 },
 244        { 19200000,  750000000,  625, 16, 1,  8 },
 245        { 26000000,  750000000,  750, 26, 1, 12 },
 246        /* 608 MHz */
 247        { 12000000,  608000000,  608, 12, 1, 12 },
 248        { 13000000,  608000000,  608, 13, 1, 12 },
 249        { 19200000,  608000000,  380, 12, 1,  8 },
 250        { 26000000,  608000000,  608, 26, 1, 12 },
 251        /* 456 MHz */
 252        { 12000000,  456000000,  456, 12, 1, 12 },
 253        { 13000000,  456000000,  456, 13, 1, 12 },
 254        { 19200000,  456000000,  380, 16, 1,  8 },
 255        { 26000000,  456000000,  456, 26, 1, 12 },
 256        /* 312 MHz */
 257        { 12000000,  312000000,  312, 12, 1, 12 },
 258        { 13000000,  312000000,  312, 13, 1, 12 },
 259        { 19200000,  312000000,  260, 16, 1,  8 },
 260        { 26000000,  312000000,  312, 26, 1, 12 },
 261        {        0,          0,    0,  0, 0,  0 },
 262};
 263
 264static const struct pdiv_map plle_p[] = {
 265        { .pdiv = 1, .hw_val = 1 },
 266        { .pdiv = 0, .hw_val = 0 },
 267};
 268
 269static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
 270        { 12000000, 100000000, 200, 24, 1, 0 },
 271        {        0,         0,   0,  0, 0, 0 },
 272};
 273
 274/* PLL parameters */
 275static struct tegra_clk_pll_params pll_c_params = {
 276        .input_min = 2000000,
 277        .input_max = 31000000,
 278        .cf_min = 1000000,
 279        .cf_max = 6000000,
 280        .vco_min = 20000000,
 281        .vco_max = 1400000000,
 282        .base_reg = PLLC_BASE,
 283        .misc_reg = PLLC_MISC,
 284        .lock_mask = PLL_BASE_LOCK,
 285        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 286        .lock_delay = 300,
 287        .freq_table = pll_c_freq_table,
 288        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 289};
 290
 291static struct tegra_clk_pll_params pll_m_params = {
 292        .input_min = 2000000,
 293        .input_max = 31000000,
 294        .cf_min = 1000000,
 295        .cf_max = 6000000,
 296        .vco_min = 20000000,
 297        .vco_max = 1200000000,
 298        .base_reg = PLLM_BASE,
 299        .misc_reg = PLLM_MISC,
 300        .lock_mask = PLL_BASE_LOCK,
 301        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 302        .lock_delay = 300,
 303        .freq_table = pll_m_freq_table,
 304        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 305};
 306
 307static struct tegra_clk_pll_params pll_p_params = {
 308        .input_min = 2000000,
 309        .input_max = 31000000,
 310        .cf_min = 1000000,
 311        .cf_max = 6000000,
 312        .vco_min = 20000000,
 313        .vco_max = 1400000000,
 314        .base_reg = PLLP_BASE,
 315        .misc_reg = PLLP_MISC,
 316        .lock_mask = PLL_BASE_LOCK,
 317        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 318        .lock_delay = 300,
 319        .freq_table = pll_p_freq_table,
 320        .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON |
 321                 TEGRA_PLL_HAS_LOCK_ENABLE,
 322        .fixed_rate =  216000000,
 323};
 324
 325static struct tegra_clk_pll_params pll_a_params = {
 326        .input_min = 2000000,
 327        .input_max = 31000000,
 328        .cf_min = 1000000,
 329        .cf_max = 6000000,
 330        .vco_min = 20000000,
 331        .vco_max = 1400000000,
 332        .base_reg = PLLA_BASE,
 333        .misc_reg = PLLA_MISC,
 334        .lock_mask = PLL_BASE_LOCK,
 335        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 336        .lock_delay = 300,
 337        .freq_table = pll_a_freq_table,
 338        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 339};
 340
 341static struct tegra_clk_pll_params pll_d_params = {
 342        .input_min = 2000000,
 343        .input_max = 40000000,
 344        .cf_min = 1000000,
 345        .cf_max = 6000000,
 346        .vco_min = 40000000,
 347        .vco_max = 1000000000,
 348        .base_reg = PLLD_BASE,
 349        .misc_reg = PLLD_MISC,
 350        .lock_mask = PLL_BASE_LOCK,
 351        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
 352        .lock_delay = 1000,
 353        .freq_table = pll_d_freq_table,
 354        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 355};
 356
 357static const struct pdiv_map pllu_p[] = {
 358        { .pdiv = 1, .hw_val = 1 },
 359        { .pdiv = 2, .hw_val = 0 },
 360        { .pdiv = 0, .hw_val = 0 },
 361};
 362
 363static struct tegra_clk_pll_params pll_u_params = {
 364        .input_min = 2000000,
 365        .input_max = 40000000,
 366        .cf_min = 1000000,
 367        .cf_max = 6000000,
 368        .vco_min = 48000000,
 369        .vco_max = 960000000,
 370        .base_reg = PLLU_BASE,
 371        .misc_reg = PLLU_MISC,
 372        .lock_mask = PLL_BASE_LOCK,
 373        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
 374        .lock_delay = 1000,
 375        .pdiv_tohw = pllu_p,
 376        .freq_table = pll_u_freq_table,
 377        .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 378};
 379
 380static struct tegra_clk_pll_params pll_x_params = {
 381        .input_min = 2000000,
 382        .input_max = 31000000,
 383        .cf_min = 1000000,
 384        .cf_max = 6000000,
 385        .vco_min = 20000000,
 386        .vco_max = 1200000000,
 387        .base_reg = PLLX_BASE,
 388        .misc_reg = PLLX_MISC,
 389        .lock_mask = PLL_BASE_LOCK,
 390        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 391        .lock_delay = 300,
 392        .freq_table = pll_x_freq_table,
 393        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
 394        .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
 395        .post_rate_change = tegra_cclk_post_pllx_rate_change,
 396};
 397
 398static struct tegra_clk_pll_params pll_e_params = {
 399        .input_min = 12000000,
 400        .input_max = 12000000,
 401        .cf_min = 0,
 402        .cf_max = 0,
 403        .vco_min = 0,
 404        .vco_max = 0,
 405        .base_reg = PLLE_BASE,
 406        .misc_reg = PLLE_MISC,
 407        .lock_mask = PLLE_MISC_LOCK,
 408        .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
 409        .lock_delay = 0,
 410        .pdiv_tohw = plle_p,
 411        .freq_table = pll_e_freq_table,
 412        .flags = TEGRA_PLL_FIXED | TEGRA_PLL_LOCK_MISC |
 413                 TEGRA_PLL_HAS_LOCK_ENABLE,
 414        .fixed_rate = 100000000,
 415};
 416
 417static struct tegra_devclk devclks[] __initdata = {
 418        { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C },
 419        { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 },
 420        { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P },
 421        { .con_id = "pll_p_out1", .dt_id = TEGRA20_CLK_PLL_P_OUT1 },
 422        { .con_id = "pll_p_out2", .dt_id = TEGRA20_CLK_PLL_P_OUT2 },
 423        { .con_id = "pll_p_out3", .dt_id = TEGRA20_CLK_PLL_P_OUT3 },
 424        { .con_id = "pll_p_out4", .dt_id = TEGRA20_CLK_PLL_P_OUT4 },
 425        { .con_id = "pll_m", .dt_id = TEGRA20_CLK_PLL_M },
 426        { .con_id = "pll_m_out1", .dt_id = TEGRA20_CLK_PLL_M_OUT1 },
 427        { .con_id = "pll_x", .dt_id = TEGRA20_CLK_PLL_X },
 428        { .con_id = "pll_u", .dt_id = TEGRA20_CLK_PLL_U },
 429        { .con_id = "pll_d", .dt_id = TEGRA20_CLK_PLL_D },
 430        { .con_id = "pll_d_out0", .dt_id = TEGRA20_CLK_PLL_D_OUT0 },
 431        { .con_id = "pll_a", .dt_id = TEGRA20_CLK_PLL_A },
 432        { .con_id = "pll_a_out0", .dt_id = TEGRA20_CLK_PLL_A_OUT0 },
 433        { .con_id = "pll_e", .dt_id = TEGRA20_CLK_PLL_E },
 434        { .con_id = "cclk", .dt_id = TEGRA20_CLK_CCLK },
 435        { .con_id = "sclk", .dt_id = TEGRA20_CLK_SCLK },
 436        { .con_id = "hclk", .dt_id = TEGRA20_CLK_HCLK },
 437        { .con_id = "pclk", .dt_id = TEGRA20_CLK_PCLK },
 438        { .con_id = "fuse", .dt_id = TEGRA20_CLK_FUSE },
 439        { .con_id = "twd", .dt_id = TEGRA20_CLK_TWD },
 440        { .con_id = "audio", .dt_id = TEGRA20_CLK_AUDIO },
 441        { .con_id = "audio_2x", .dt_id = TEGRA20_CLK_AUDIO_2X },
 442        { .dev_id = "tegra20-ac97", .dt_id = TEGRA20_CLK_AC97 },
 443        { .dev_id = "tegra-apbdma", .dt_id = TEGRA20_CLK_APBDMA },
 444        { .dev_id = "rtc-tegra", .dt_id = TEGRA20_CLK_RTC },
 445        { .dev_id = "timer", .dt_id = TEGRA20_CLK_TIMER },
 446        { .dev_id = "tegra-kbc", .dt_id = TEGRA20_CLK_KBC },
 447        { .con_id = "csus", .dev_id =  "tegra_camera", .dt_id = TEGRA20_CLK_CSUS },
 448        { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_VCP },
 449        { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_BSEA },
 450        { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA20_CLK_BSEV },
 451        { .con_id = "emc", .dt_id = TEGRA20_CLK_EMC },
 452        { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA20_CLK_USBD },
 453        { .dev_id = "tegra-ehci.1", .dt_id = TEGRA20_CLK_USB2 },
 454        { .dev_id = "tegra-ehci.2", .dt_id = TEGRA20_CLK_USB3 },
 455        { .dev_id = "dsi", .dt_id = TEGRA20_CLK_DSI },
 456        { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSI },
 457        { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP },
 458        { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX },
 459        { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI },
 460        { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 },
 461        { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 },
 462        { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K },
 463        { .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M },
 464        { .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF },
 465        { .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 },
 466        { .dev_id = "tegra20-i2s.1", .dt_id = TEGRA20_CLK_I2S2 },
 467        { .con_id = "spdif_out", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_OUT },
 468        { .con_id = "spdif_in", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_IN },
 469        { .dev_id = "spi_tegra.0", .dt_id = TEGRA20_CLK_SBC1 },
 470        { .dev_id = "spi_tegra.1", .dt_id = TEGRA20_CLK_SBC2 },
 471        { .dev_id = "spi_tegra.2", .dt_id = TEGRA20_CLK_SBC3 },
 472        { .dev_id = "spi_tegra.3", .dt_id = TEGRA20_CLK_SBC4 },
 473        { .dev_id = "spi", .dt_id = TEGRA20_CLK_SPI },
 474        { .dev_id = "xio", .dt_id = TEGRA20_CLK_XIO },
 475        { .dev_id = "twc", .dt_id = TEGRA20_CLK_TWC },
 476        { .dev_id = "ide", .dt_id = TEGRA20_CLK_IDE },
 477        { .dev_id = "tegra_nand", .dt_id = TEGRA20_CLK_NDFLASH },
 478        { .dev_id = "vfir", .dt_id = TEGRA20_CLK_VFIR },
 479        { .dev_id = "csite", .dt_id = TEGRA20_CLK_CSITE },
 480        { .dev_id = "la", .dt_id = TEGRA20_CLK_LA },
 481        { .dev_id = "tegra_w1", .dt_id = TEGRA20_CLK_OWR },
 482        { .dev_id = "mipi", .dt_id = TEGRA20_CLK_MIPI },
 483        { .dev_id = "vde", .dt_id = TEGRA20_CLK_VDE },
 484        { .con_id = "vi", .dev_id =  "tegra_camera", .dt_id = TEGRA20_CLK_VI },
 485        { .dev_id = "epp", .dt_id = TEGRA20_CLK_EPP },
 486        { .dev_id = "mpe", .dt_id = TEGRA20_CLK_MPE },
 487        { .dev_id = "host1x", .dt_id = TEGRA20_CLK_HOST1X },
 488        { .dev_id = "3d", .dt_id = TEGRA20_CLK_GR3D },
 489        { .dev_id = "2d", .dt_id = TEGRA20_CLK_GR2D },
 490        { .dev_id = "tegra-nor", .dt_id = TEGRA20_CLK_NOR },
 491        { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA20_CLK_SDMMC1 },
 492        { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA20_CLK_SDMMC2 },
 493        { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA20_CLK_SDMMC3 },
 494        { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA20_CLK_SDMMC4 },
 495        { .dev_id = "cve", .dt_id = TEGRA20_CLK_CVE },
 496        { .dev_id = "tvo", .dt_id = TEGRA20_CLK_TVO },
 497        { .dev_id = "tvdac", .dt_id = TEGRA20_CLK_TVDAC },
 498        { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI_SENSOR },
 499        { .dev_id = "hdmi", .dt_id = TEGRA20_CLK_HDMI },
 500        { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA20_CLK_I2C1 },
 501        { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA20_CLK_I2C2 },
 502        { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA20_CLK_I2C3 },
 503        { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA20_CLK_DVC },
 504        { .dev_id = "tegra-pwm", .dt_id = TEGRA20_CLK_PWM },
 505        { .dev_id = "tegra_uart.0", .dt_id = TEGRA20_CLK_UARTA },
 506        { .dev_id = "tegra_uart.1", .dt_id = TEGRA20_CLK_UARTB },
 507        { .dev_id = "tegra_uart.2", .dt_id = TEGRA20_CLK_UARTC },
 508        { .dev_id = "tegra_uart.3", .dt_id = TEGRA20_CLK_UARTD },
 509        { .dev_id = "tegra_uart.4", .dt_id = TEGRA20_CLK_UARTE },
 510        { .dev_id = "tegradc.0", .dt_id = TEGRA20_CLK_DISP1 },
 511        { .dev_id = "tegradc.1", .dt_id = TEGRA20_CLK_DISP2 },
 512};
 513
 514static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
 515        [tegra_clk_ahbdma] = { .dt_id = TEGRA20_CLK_AHBDMA, .present = true },
 516        [tegra_clk_apbdma] = { .dt_id = TEGRA20_CLK_APBDMA, .present = true },
 517        [tegra_clk_spdif_out] = { .dt_id = TEGRA20_CLK_SPDIF_OUT, .present = true },
 518        [tegra_clk_spdif_in] = { .dt_id = TEGRA20_CLK_SPDIF_IN, .present = true },
 519        [tegra_clk_sdmmc1] = { .dt_id = TEGRA20_CLK_SDMMC1, .present = true },
 520        [tegra_clk_sdmmc2] = { .dt_id = TEGRA20_CLK_SDMMC2, .present = true },
 521        [tegra_clk_sdmmc3] = { .dt_id = TEGRA20_CLK_SDMMC3, .present = true },
 522        [tegra_clk_sdmmc4] = { .dt_id = TEGRA20_CLK_SDMMC4, .present = true },
 523        [tegra_clk_la] = { .dt_id = TEGRA20_CLK_LA, .present = true },
 524        [tegra_clk_csite] = { .dt_id = TEGRA20_CLK_CSITE, .present = true },
 525        [tegra_clk_vfir] = { .dt_id = TEGRA20_CLK_VFIR, .present = true },
 526        [tegra_clk_mipi] = { .dt_id = TEGRA20_CLK_MIPI, .present = true },
 527        [tegra_clk_nor] = { .dt_id = TEGRA20_CLK_NOR, .present = true },
 528        [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true },
 529        [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true },
 530        [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true },
 531        [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true },
 532        [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true },
 533        [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true },
 534        [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true },
 535        [tegra_clk_usbd] = { .dt_id = TEGRA20_CLK_USBD, .present = true },
 536        [tegra_clk_usb2] = { .dt_id = TEGRA20_CLK_USB2, .present = true },
 537        [tegra_clk_usb3] = { .dt_id = TEGRA20_CLK_USB3, .present = true },
 538        [tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true },
 539        [tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true },
 540        [tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true },
 541        [tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true },
 542        [tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true },
 543        [tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true },
 544        [tegra_clk_pll_p_out2] = { .dt_id = TEGRA20_CLK_PLL_P_OUT2, .present = true },
 545        [tegra_clk_pll_p_out3] = { .dt_id = TEGRA20_CLK_PLL_P_OUT3, .present = true },
 546        [tegra_clk_pll_p_out4] = { .dt_id = TEGRA20_CLK_PLL_P_OUT4, .present = true },
 547        [tegra_clk_pll_p] = { .dt_id = TEGRA20_CLK_PLL_P, .present = true },
 548        [tegra_clk_owr] = { .dt_id = TEGRA20_CLK_OWR, .present = true },
 549        [tegra_clk_sbc1] = { .dt_id = TEGRA20_CLK_SBC1, .present = true },
 550        [tegra_clk_sbc2] = { .dt_id = TEGRA20_CLK_SBC2, .present = true },
 551        [tegra_clk_sbc3] = { .dt_id = TEGRA20_CLK_SBC3, .present = true },
 552        [tegra_clk_sbc4] = { .dt_id = TEGRA20_CLK_SBC4, .present = true },
 553        [tegra_clk_vde] = { .dt_id = TEGRA20_CLK_VDE, .present = true },
 554        [tegra_clk_vi] = { .dt_id = TEGRA20_CLK_VI, .present = true },
 555        [tegra_clk_epp] = { .dt_id = TEGRA20_CLK_EPP, .present = true },
 556        [tegra_clk_mpe] = { .dt_id = TEGRA20_CLK_MPE, .present = true },
 557        [tegra_clk_host1x] = { .dt_id = TEGRA20_CLK_HOST1X, .present = true },
 558        [tegra_clk_gr2d] = { .dt_id = TEGRA20_CLK_GR2D, .present = true },
 559        [tegra_clk_gr3d] = { .dt_id = TEGRA20_CLK_GR3D, .present = true },
 560        [tegra_clk_ndflash] = { .dt_id = TEGRA20_CLK_NDFLASH, .present = true },
 561        [tegra_clk_cve] = { .dt_id = TEGRA20_CLK_CVE, .present = true },
 562        [tegra_clk_tvo] = { .dt_id = TEGRA20_CLK_TVO, .present = true },
 563        [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true },
 564        [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true },
 565        [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true },
 566        [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true },
 567        [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true },
 568};
 569
 570static unsigned long tegra20_clk_measure_input_freq(void)
 571{
 572        u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL);
 573        u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK;
 574        u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
 575        unsigned long input_freq;
 576
 577        switch (auto_clk_control) {
 578        case OSC_CTRL_OSC_FREQ_12MHZ:
 579                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
 580                input_freq = 12000000;
 581                break;
 582        case OSC_CTRL_OSC_FREQ_13MHZ:
 583                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
 584                input_freq = 13000000;
 585                break;
 586        case OSC_CTRL_OSC_FREQ_19_2MHZ:
 587                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
 588                input_freq = 19200000;
 589                break;
 590        case OSC_CTRL_OSC_FREQ_26MHZ:
 591                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
 592                input_freq = 26000000;
 593                break;
 594        default:
 595                pr_err("Unexpected clock autodetect value %d",
 596                       auto_clk_control);
 597                BUG();
 598                return 0;
 599        }
 600
 601        return input_freq;
 602}
 603
 604static unsigned int tegra20_get_pll_ref_div(void)
 605{
 606        u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) &
 607                OSC_CTRL_PLL_REF_DIV_MASK;
 608
 609        switch (pll_ref_div) {
 610        case OSC_CTRL_PLL_REF_DIV_1:
 611                return 1;
 612        case OSC_CTRL_PLL_REF_DIV_2:
 613                return 2;
 614        case OSC_CTRL_PLL_REF_DIV_4:
 615                return 4;
 616        default:
 617                pr_err("Invalid pll ref divider %d\n", pll_ref_div);
 618                BUG();
 619        }
 620        return 0;
 621}
 622
 623static void tegra20_pll_init(void)
 624{
 625        struct clk *clk;
 626
 627        /* PLLC */
 628        clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0,
 629                            &pll_c_params, NULL);
 630        clks[TEGRA20_CLK_PLL_C] = clk;
 631
 632        /* PLLC_OUT1 */
 633        clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
 634                                clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
 635                                8, 8, 1, NULL);
 636        clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
 637                                clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT,
 638                                0, NULL);
 639        clks[TEGRA20_CLK_PLL_C_OUT1] = clk;
 640
 641        /* PLLM */
 642        clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL,
 643                            CLK_SET_RATE_GATE, &pll_m_params, NULL);
 644        clks[TEGRA20_CLK_PLL_M] = clk;
 645
 646        /* PLLM_OUT1 */
 647        clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
 648                                clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
 649                                8, 8, 1, NULL);
 650        clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
 651                                clk_base + PLLM_OUT, 1, 0,
 652                                CLK_SET_RATE_PARENT, 0, NULL);
 653        clks[TEGRA20_CLK_PLL_M_OUT1] = clk;
 654
 655        /* PLLX */
 656        clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0,
 657                            &pll_x_params, NULL);
 658        clks[TEGRA20_CLK_PLL_X] = clk;
 659
 660        /* PLLU */
 661        clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0,
 662                            &pll_u_params, NULL);
 663        clks[TEGRA20_CLK_PLL_U] = clk;
 664
 665        /* PLLD */
 666        clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0,
 667                            &pll_d_params, NULL);
 668        clks[TEGRA20_CLK_PLL_D] = clk;
 669
 670        /* PLLD_OUT0 */
 671        clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
 672                                        CLK_SET_RATE_PARENT, 1, 2);
 673        clks[TEGRA20_CLK_PLL_D_OUT0] = clk;
 674
 675        /* PLLA */
 676        clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0,
 677                            &pll_a_params, NULL);
 678        clks[TEGRA20_CLK_PLL_A] = clk;
 679
 680        /* PLLA_OUT0 */
 681        clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
 682                                clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
 683                                8, 8, 1, NULL);
 684        clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
 685                                clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
 686                                CLK_SET_RATE_PARENT, 0, NULL);
 687        clks[TEGRA20_CLK_PLL_A_OUT0] = clk;
 688
 689        /* PLLE */
 690        clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base,
 691                             0, &pll_e_params, NULL);
 692        clks[TEGRA20_CLK_PLL_E] = clk;
 693}
 694
 695static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
 696                                      "pll_p", "pll_p_out4",
 697                                      "pll_p_out3", "clk_d", "pll_x" };
 698static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
 699                                      "pll_p_out3", "pll_p_out2", "clk_d",
 700                                      "clk_32k", "pll_m_out1" };
 701
 702static void tegra20_super_clk_init(void)
 703{
 704        struct clk *clk;
 705
 706        /* CCLK */
 707        clk = tegra_clk_register_super_cclk("cclk", cclk_parents,
 708                              ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
 709                              clk_base + CCLK_BURST_POLICY, TEGRA20_SUPER_CLK,
 710                              NULL);
 711        clks[TEGRA20_CLK_CCLK] = clk;
 712
 713        /* SCLK */
 714        clk = tegra_clk_register_super_mux("sclk", sclk_parents,
 715                              ARRAY_SIZE(sclk_parents),
 716                              CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
 717                              clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
 718        clks[TEGRA20_CLK_SCLK] = clk;
 719
 720        /* twd */
 721        clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4);
 722        clks[TEGRA20_CLK_TWD] = clk;
 723}
 724
 725static const char *audio_parents[] = { "spdif_in", "i2s1", "i2s2", "unused",
 726                                       "pll_a_out0", "unused", "unused",
 727                                       "unused" };
 728
 729static void __init tegra20_audio_clk_init(void)
 730{
 731        struct clk *clk;
 732
 733        /* audio */
 734        clk = clk_register_mux(NULL, "audio_mux", audio_parents,
 735                                ARRAY_SIZE(audio_parents),
 736                                CLK_SET_RATE_NO_REPARENT,
 737                                clk_base + AUDIO_SYNC_CLK, 0, 3, 0, NULL);
 738        clk = clk_register_gate(NULL, "audio", "audio_mux", 0,
 739                                clk_base + AUDIO_SYNC_CLK, 4,
 740                                CLK_GATE_SET_TO_DISABLE, NULL);
 741        clks[TEGRA20_CLK_AUDIO] = clk;
 742
 743        /* audio_2x */
 744        clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio",
 745                                        CLK_SET_RATE_PARENT, 2, 1);
 746        clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler",
 747                                    TEGRA_PERIPH_NO_RESET, clk_base,
 748                                    CLK_SET_RATE_PARENT, 89,
 749                                    periph_clk_enb_refcnt);
 750        clks[TEGRA20_CLK_AUDIO_2X] = clk;
 751}
 752
 753static const char *i2s1_parents[] = { "pll_a_out0", "audio_2x", "pll_p",
 754                                      "clk_m" };
 755static const char *i2s2_parents[] = { "pll_a_out0", "audio_2x", "pll_p",
 756                                      "clk_m" };
 757static const char *pwm_parents[] = { "pll_p", "pll_c", "audio", "clk_m",
 758                                     "clk_32k" };
 759static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" };
 760static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c",
 761                                         "clk_m" };
 762
 763static struct tegra_periph_init_data tegra_periph_clk_list[] = {
 764        TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents,     CLK_SOURCE_I2S1,   11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1),
 765        TEGRA_INIT_DATA_MUX("i2s2", i2s2_parents,     CLK_SOURCE_I2S2,   18, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S2),
 766        TEGRA_INIT_DATA_MUX("spi",   mux_pllpcm_clkm,   CLK_SOURCE_SPI,   43, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_SPI),
 767        TEGRA_INIT_DATA_MUX("xio",   mux_pllpcm_clkm,   CLK_SOURCE_XIO,   45, 0, TEGRA20_CLK_XIO),
 768        TEGRA_INIT_DATA_MUX("twc",   mux_pllpcm_clkm,   CLK_SOURCE_TWC,   16, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_TWC),
 769        TEGRA_INIT_DATA_MUX("ide",   mux_pllpcm_clkm,   CLK_SOURCE_XIO,   25, 0, TEGRA20_CLK_IDE),
 770        TEGRA_INIT_DATA_DIV16("dvc", mux_pllpcm_clkm,   CLK_SOURCE_DVC,   47, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_DVC),
 771        TEGRA_INIT_DATA_DIV16("i2c1", mux_pllpcm_clkm,   CLK_SOURCE_I2C1,   12, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C1),
 772        TEGRA_INIT_DATA_DIV16("i2c2", mux_pllpcm_clkm,   CLK_SOURCE_I2C2,   54, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C2),
 773        TEGRA_INIT_DATA_DIV16("i2c3", mux_pllpcm_clkm,   CLK_SOURCE_I2C3,   67, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C3),
 774        TEGRA_INIT_DATA_MUX("hdmi", mux_pllpdc_clkm,   CLK_SOURCE_HDMI,   51, 0, TEGRA20_CLK_HDMI),
 775        TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents,     CLK_SOURCE_PWM,   28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_PWM),
 776};
 777
 778static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
 779        TEGRA_INIT_DATA_NODIV("uarta",  mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6,   TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTA),
 780        TEGRA_INIT_DATA_NODIV("uartb",  mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7,   TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTB),
 781        TEGRA_INIT_DATA_NODIV("uartc",  mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55,  TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTC),
 782        TEGRA_INIT_DATA_NODIV("uartd",  mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65,  TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTD),
 783        TEGRA_INIT_DATA_NODIV("uarte",  mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66,  TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTE),
 784        TEGRA_INIT_DATA_NODIV("disp1",  mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27,  0, TEGRA20_CLK_DISP1),
 785        TEGRA_INIT_DATA_NODIV("disp2",  mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26,  0, TEGRA20_CLK_DISP2),
 786};
 787
 788static void __init tegra20_periph_clk_init(void)
 789{
 790        struct tegra_periph_init_data *data;
 791        struct clk *clk;
 792        unsigned int i;
 793
 794        /* ac97 */
 795        clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0",
 796                                    TEGRA_PERIPH_ON_APB,
 797                                    clk_base, 0, 3, periph_clk_enb_refcnt);
 798        clks[TEGRA20_CLK_AC97] = clk;
 799
 800        /* emc */
 801        clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, false);
 802
 803        clks[TEGRA20_CLK_EMC] = clk;
 804
 805        clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC,
 806                                    NULL);
 807        clks[TEGRA20_CLK_MC] = clk;
 808
 809        /* dsi */
 810        clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
 811                                    48, periph_clk_enb_refcnt);
 812        clk_register_clkdev(clk, NULL, "dsi");
 813        clks[TEGRA20_CLK_DSI] = clk;
 814
 815        /* pex */
 816        clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70,
 817                                    periph_clk_enb_refcnt);
 818        clks[TEGRA20_CLK_PEX] = clk;
 819
 820        /* dev1 OSC divider */
 821        clk_register_divider(NULL, "dev1_osc_div", "clk_m",
 822                             0, clk_base + MISC_CLK_ENB, 22, 2,
 823                             CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
 824                             NULL);
 825
 826        /* dev2 OSC divider */
 827        clk_register_divider(NULL, "dev2_osc_div", "clk_m",
 828                             0, clk_base + MISC_CLK_ENB, 20, 2,
 829                             CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
 830                             NULL);
 831
 832        /* cdev1 */
 833        clk = tegra_clk_register_periph_gate("cdev1", "cdev1_mux", 0,
 834                                    clk_base, 0, 94, periph_clk_enb_refcnt);
 835        clks[TEGRA20_CLK_CDEV1] = clk;
 836
 837        /* cdev2 */
 838        clk = tegra_clk_register_periph_gate("cdev2", "cdev2_mux", 0,
 839                                    clk_base, 0, 93, periph_clk_enb_refcnt);
 840        clks[TEGRA20_CLK_CDEV2] = clk;
 841
 842        for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
 843                data = &tegra_periph_clk_list[i];
 844                clk = tegra_clk_register_periph_data(clk_base, data);
 845                clks[data->clk_id] = clk;
 846        }
 847
 848        for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) {
 849                data = &tegra_periph_nodiv_clk_list[i];
 850                clk = tegra_clk_register_periph_nodiv(data->name,
 851                                        data->p.parent_names,
 852                                        data->num_parents, &data->periph,
 853                                        clk_base, data->offset);
 854                clks[data->clk_id] = clk;
 855        }
 856
 857        tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params);
 858}
 859
 860static void __init tegra20_osc_clk_init(void)
 861{
 862        struct clk *clk;
 863        unsigned long input_freq;
 864        unsigned int pll_ref_div;
 865
 866        input_freq = tegra20_clk_measure_input_freq();
 867
 868        /* clk_m */
 869        clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IGNORE_UNUSED,
 870                                      input_freq);
 871        clks[TEGRA20_CLK_CLK_M] = clk;
 872
 873        /* pll_ref */
 874        pll_ref_div = tegra20_get_pll_ref_div();
 875        clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
 876                                        CLK_SET_RATE_PARENT, 1, pll_ref_div);
 877        clks[TEGRA20_CLK_PLL_REF] = clk;
 878}
 879
 880/* Tegra20 CPU clock and reset control functions */
 881static void tegra20_wait_cpu_in_reset(u32 cpu)
 882{
 883        unsigned int reg;
 884
 885        do {
 886                reg = readl(clk_base +
 887                            TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
 888                cpu_relax();
 889        } while (!(reg & (1 << cpu)));  /* check CPU been reset or not */
 890
 891        return;
 892}
 893
 894static void tegra20_put_cpu_in_reset(u32 cpu)
 895{
 896        writel(CPU_RESET(cpu),
 897               clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
 898        dmb();
 899}
 900
 901static void tegra20_cpu_out_of_reset(u32 cpu)
 902{
 903        writel(CPU_RESET(cpu),
 904               clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
 905        wmb();
 906}
 907
 908static void tegra20_enable_cpu_clock(u32 cpu)
 909{
 910        unsigned int reg;
 911
 912        reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 913        writel(reg & ~CPU_CLOCK(cpu),
 914               clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 915        barrier();
 916        reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 917}
 918
 919static void tegra20_disable_cpu_clock(u32 cpu)
 920{
 921        unsigned int reg;
 922
 923        reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 924        writel(reg | CPU_CLOCK(cpu),
 925               clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 926}
 927
 928#ifdef CONFIG_PM_SLEEP
 929static bool tegra20_cpu_rail_off_ready(void)
 930{
 931        unsigned int cpu_rst_status;
 932
 933        cpu_rst_status = readl(clk_base +
 934                               TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
 935
 936        return !!(cpu_rst_status & 0x2);
 937}
 938
 939static void tegra20_cpu_clock_suspend(void)
 940{
 941        /* switch coresite to clk_m, save off original source */
 942        tegra20_cpu_clk_sctx.clk_csite_src =
 943                                readl(clk_base + CLK_SOURCE_CSITE);
 944        writel(3<<30, clk_base + CLK_SOURCE_CSITE);
 945
 946        tegra20_cpu_clk_sctx.cpu_burst =
 947                                readl(clk_base + CCLK_BURST_POLICY);
 948        tegra20_cpu_clk_sctx.pllx_base =
 949                                readl(clk_base + PLLX_BASE);
 950        tegra20_cpu_clk_sctx.pllx_misc =
 951                                readl(clk_base + PLLX_MISC);
 952        tegra20_cpu_clk_sctx.cclk_divider =
 953                                readl(clk_base + SUPER_CCLK_DIVIDER);
 954}
 955
 956static void tegra20_cpu_clock_resume(void)
 957{
 958        unsigned int reg, policy;
 959        u32 misc, base;
 960
 961        /* Is CPU complex already running on PLLX? */
 962        reg = readl(clk_base + CCLK_BURST_POLICY);
 963        policy = (reg >> CCLK_BURST_POLICY_SHIFT) & 0xF;
 964
 965        if (policy == CCLK_IDLE_POLICY)
 966                reg = (reg >> CCLK_IDLE_POLICY_SHIFT) & 0xF;
 967        else if (policy == CCLK_RUN_POLICY)
 968                reg = (reg >> CCLK_RUN_POLICY_SHIFT) & 0xF;
 969        else
 970                BUG();
 971
 972        if (reg != CCLK_BURST_POLICY_PLLX) {
 973                misc = readl_relaxed(clk_base + PLLX_MISC);
 974                base = readl_relaxed(clk_base + PLLX_BASE);
 975
 976                if (misc != tegra20_cpu_clk_sctx.pllx_misc ||
 977                    base != tegra20_cpu_clk_sctx.pllx_base) {
 978                        /* restore PLLX settings if CPU is on different PLL */
 979                        writel(tegra20_cpu_clk_sctx.pllx_misc,
 980                                                clk_base + PLLX_MISC);
 981                        writel(tegra20_cpu_clk_sctx.pllx_base,
 982                                                clk_base + PLLX_BASE);
 983
 984                        /* wait for PLL stabilization if PLLX was enabled */
 985                        if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30))
 986                                udelay(300);
 987                }
 988        }
 989
 990        /*
 991         * Restore original burst policy setting for calls resulting from CPU
 992         * LP2 in idle or system suspend.
 993         */
 994        writel(tegra20_cpu_clk_sctx.cclk_divider,
 995                                        clk_base + SUPER_CCLK_DIVIDER);
 996        writel(tegra20_cpu_clk_sctx.cpu_burst,
 997                                        clk_base + CCLK_BURST_POLICY);
 998
 999        writel(tegra20_cpu_clk_sctx.clk_csite_src,
1000                                        clk_base + CLK_SOURCE_CSITE);
1001}
1002#endif
1003
1004static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
1005        .wait_for_reset = tegra20_wait_cpu_in_reset,
1006        .put_in_reset   = tegra20_put_cpu_in_reset,
1007        .out_of_reset   = tegra20_cpu_out_of_reset,
1008        .enable_clock   = tegra20_enable_cpu_clock,
1009        .disable_clock  = tegra20_disable_cpu_clock,
1010#ifdef CONFIG_PM_SLEEP
1011        .rail_off_ready = tegra20_cpu_rail_off_ready,
1012        .suspend        = tegra20_cpu_clock_suspend,
1013        .resume         = tegra20_cpu_clock_resume,
1014#endif
1015};
1016
1017static struct tegra_clk_init_table init_table[] __initdata = {
1018        { TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1 },
1019        { TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1 },
1020        { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 },
1021        { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 },
1022        { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 },
1023        { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 0 },
1024        { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 0 },
1025        { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 120000000, 0 },
1026        { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 120000000, 0 },
1027        { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 0 },
1028        { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 },
1029        { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 },
1030        { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 },
1031        { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 },
1032        { TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0 },
1033        { TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0 },
1034        { TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0 },
1035        { TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 0 },
1036        { TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 0 },
1037        { TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 },
1038        { TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 },
1039        { TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0 },
1040        { TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0 },
1041        { TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0 },
1042        { TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0 },
1043        { TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0 },
1044        { TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0 },
1045        { TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0 },
1046        { TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0 },
1047        { TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0 },
1048        { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1049        { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1050        { TEGRA20_CLK_VDE, TEGRA20_CLK_PLL_C, 300000000, 0 },
1051        /* must be the last entry */
1052        { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
1053};
1054
1055static void __init tegra20_clock_apply_init_table(void)
1056{
1057        tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX);
1058}
1059
1060/*
1061 * Some clocks may be used by different drivers depending on the board
1062 * configuration.  List those here to register them twice in the clock lookup
1063 * table under two names.
1064 */
1065static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
1066        TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD,    "utmip-pad",     NULL),
1067        TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD,    "tegra-ehci.0",  NULL),
1068        TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD,    "tegra-otg",     NULL),
1069        TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK,    NULL,           "cpu"),
1070        /* must be the last entry */
1071        TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL,            NULL),
1072};
1073
1074static const struct of_device_id pmc_match[] __initconst = {
1075        { .compatible = "nvidia,tegra20-pmc" },
1076        { },
1077};
1078
1079static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
1080                                               void *data)
1081{
1082        struct clk_hw *parent_hw;
1083        struct clk_hw *hw;
1084        struct clk *clk;
1085
1086        clk = of_clk_src_onecell_get(clkspec, data);
1087        if (IS_ERR(clk))
1088                return clk;
1089
1090        hw = __clk_get_hw(clk);
1091
1092        /*
1093         * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent
1094         * clock is created by the pinctrl driver. It is possible for clk user
1095         * to request these clocks before pinctrl driver got probed and hence
1096         * user will get an orphaned clock. That might be undesirable because
1097         * user may expect parent clock to be enabled by the child.
1098         */
1099        if (clkspec->args[0] == TEGRA20_CLK_CDEV1 ||
1100            clkspec->args[0] == TEGRA20_CLK_CDEV2) {
1101                parent_hw = clk_hw_get_parent(hw);
1102                if (!parent_hw)
1103                        return ERR_PTR(-EPROBE_DEFER);
1104        }
1105
1106        if (clkspec->args[0] == TEGRA20_CLK_EMC) {
1107                if (!tegra20_clk_emc_driver_available(hw))
1108                        return ERR_PTR(-EPROBE_DEFER);
1109        }
1110
1111        return clk;
1112}
1113
1114static void __init tegra20_clock_init(struct device_node *np)
1115{
1116        struct device_node *node;
1117
1118        clk_base = of_iomap(np, 0);
1119        if (!clk_base) {
1120                pr_err("Can't map CAR registers\n");
1121                BUG();
1122        }
1123
1124        node = of_find_matching_node(NULL, pmc_match);
1125        if (!node) {
1126                pr_err("Failed to find pmc node\n");
1127                BUG();
1128        }
1129
1130        pmc_base = of_iomap(node, 0);
1131        if (!pmc_base) {
1132                pr_err("Can't map pmc registers\n");
1133                BUG();
1134        }
1135
1136        clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX,
1137                                TEGRA20_CLK_PERIPH_BANKS);
1138        if (!clks)
1139                return;
1140
1141        tegra20_osc_clk_init();
1142        tegra_fixed_clk_init(tegra20_clks);
1143        tegra20_pll_init();
1144        tegra20_super_clk_init();
1145        tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL);
1146        tegra20_periph_clk_init();
1147        tegra20_audio_clk_init();
1148
1149        tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
1150
1151        tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
1152        tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
1153
1154        tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
1155
1156        tegra_cpu_car_ops = &tegra20_cpu_car_ops;
1157}
1158CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
1159