From 1d15cb9ce9a220192f672cd32369f8d3c7d3a89b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 16 Nov 2015 06:51:36 +0100 Subject: clk: tegra: Add Tegra210 device tree binding Add a header file that defines the clock numbers for Tegra210. It is meant to be included by device trees so that they can refer to the clocks by symbolic name instead of numeric value. Also add the device tree binding documentation which is largely the same as for earlier generations of Tegra. Extracted from a larger patch by Rhyland Klein . Signed-off-by: Thierry Reding --- .../bindings/clock/nvidia,tegra210-car.txt | 56 +++ include/dt-bindings/clock/tegra210-car.h | 401 +++++++++++++++++++++ 2 files changed, 457 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt create mode 100644 include/dt-bindings/clock/tegra210-car.h diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt new file mode 100644 index 000000000000..26f237f641b7 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra210-car.txt @@ -0,0 +1,56 @@ +NVIDIA Tegra210 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra210-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in". +- #clock-cells : Should be 1. + In clock consumers, this cell represents the clock ID exposed by the + CAR. The assignments may be found in header file + . +- #reset-cells : Should be 1. + In clock consumers, this cell represents the bit number in the CAR's + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers. + +Example SoC include file: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra210-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car TEGRA210_CLK_USB2>; + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k>; + }; +}; diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h new file mode 100644 index 000000000000..6f45aea49e4f --- /dev/null +++ b/include/dt-bindings/clock/tegra210-car.h @@ -0,0 +1,401 @@ +/* + * This header provides constants for binding nvidia,tegra210-car. + * + * The first 224 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + * registers. These IDs often match those in the CAR's RST_DEVICES registers, + * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + * this case, those clocks are assigned IDs above 224 in order to highlight + * this issue. Implementations that interpret these clock IDs as bit values + * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + * explicitly handle these special cases. + * + * The balance of the clocks controlled by the CAR are assigned IDs of 224 and + * above. + */ + +#ifndef _DT_BINDINGS_CLOCK_TEGRA210_CAR_H +#define _DT_BINDINGS_CLOCK_TEGRA210_CAR_H + +/* 0 */ +/* 1 */ +/* 2 */ +#define TEGRA210_CLK_ISPB 3 +#define TEGRA210_CLK_RTC 4 +#define TEGRA210_CLK_TIMER 5 +#define TEGRA210_CLK_UARTA 6 +/* 7 (register bit affects uartb and vfir) */ +#define TEGRA210_CLK_GPIO 8 +#define TEGRA210_CLK_SDMMC2 9 +/* 10 (register bit affects spdif_in and spdif_out) */ +#define TEGRA210_CLK_I2S1 11 +#define TEGRA210_CLK_I2C1 12 +/* 13 */ +#define TEGRA210_CLK_SDMMC1 14 +#define TEGRA210_CLK_SDMMC4 15 +/* 16 */ +#define TEGRA210_CLK_PWM 17 +#define TEGRA210_CLK_I2S2 18 +/* 19 */ +/* 20 (register bit affects vi and vi_sensor) */ +/* 21 */ +#define TEGRA210_CLK_USBD 22 +#define TEGRA210_CLK_ISP 23 +/* 24 */ +/* 25 */ +#define TEGRA210_CLK_DISP2 26 +#define TEGRA210_CLK_DISP1 27 +#define TEGRA210_CLK_HOST1X 28 +/* 29 */ +#define TEGRA210_CLK_I2S0 30 +/* 31 */ + +#define TEGRA210_CLK_MC 32 +#define TEGRA210_CLK_AHBDMA 33 +#define TEGRA210_CLK_APBDMA 34 +/* 35 */ +/* 36 */ +/* 37 */ +#define TEGRA210_CLK_PMC 38 +/* 39 (register bit affects fuse and fuse_burn) */ +#define TEGRA210_CLK_KFUSE 40 +#define TEGRA210_CLK_SBC1 41 +/* 42 */ +/* 43 */ +#define TEGRA210_CLK_SBC2 44 +/* 45 */ +#define TEGRA210_CLK_SBC3 46 +#define TEGRA210_CLK_I2C5 47 +#define TEGRA210_CLK_DSIA 48 +/* 49 */ +/* 50 */ +/* 51 */ +#define TEGRA210_CLK_CSI 52 +/* 53 */ +#define TEGRA210_CLK_I2C2 54 +#define TEGRA210_CLK_UARTC 55 +#define TEGRA210_CLK_MIPI_CAL 56 +#define TEGRA210_CLK_EMC 57 +#define TEGRA210_CLK_USB2 58 +/* 59 */ +/* 60 */ +/* 61 */ +/* 62 */ +#define TEGRA210_CLK_BSEV 63 + +/* 64 */ +#define TEGRA210_CLK_UARTD 65 +/* 66 */ +#define TEGRA210_CLK_I2C3 67 +#define TEGRA210_CLK_SBC4 68 +#define TEGRA210_CLK_SDMMC3 69 +#define TEGRA210_CLK_PCIE 70 +#define TEGRA210_CLK_OWR 71 +#define TEGRA210_CLK_AFI 72 +#define TEGRA210_CLK_CSITE 73 +/* 74 */ +/* 75 */ +/* 76 */ +/* 77 */ +#define TEGRA210_CLK_SOC_THERM 78 +#define TEGRA210_CLK_DTV 79 +/* 80 */ +#define TEGRA210_CLK_I2CSLOW 81 +#define TEGRA210_CLK_DSIB 82 +#define TEGRA210_CLK_TSEC 83 +/* 84 */ +/* 85 */ +/* 86 */ +/* 87 */ +/* 88 */ +#define TEGRA210_CLK_XUSB_HOST 89 +/* 90 */ +/* 91 */ +#define TEGRA210_CLK_CSUS 92 +/* 93 */ +/* 94 */ +/* 95 (bit affects xusb_dev and xusb_dev_src) */ + +/* 96 */ +/* 97 */ +/* 98 */ +#define TEGRA210_CLK_MSELECT 99 +#define TEGRA210_CLK_TSENSOR 100 +#define TEGRA210_CLK_I2S3 101 +#define TEGRA210_CLK_I2S4 102 +#define TEGRA210_CLK_I2C4 103 +/* 104 */ +/* 105 */ +#define TEGRA210_CLK_D_AUDIO 106 +/* 107 ( affects abp -> ape) */ +/* 108 */ +/* 109 */ +/* 110 */ +#define TEGRA210_CLK_HDA2CODEC_2X 111 +/* 112 */ +/* 113 */ +/* 114 */ +/* 115 */ +/* 116 */ +/* 117 */ +#define TEGRA210_CLK_SPDIF_2X 118 +#define TEGRA210_CLK_ACTMON 119 +#define TEGRA210_CLK_EXTERN1 120 +#define TEGRA210_CLK_EXTERN2 121 +#define TEGRA210_CLK_EXTERN3 122 +#define TEGRA210_CLK_SATA_OOB 123 +#define TEGRA210_CLK_SATA 124 +#define TEGRA210_CLK_HDA 125 +/* 126 */ +/* 127 */ + +#define TEGRA210_CLK_HDA2HDMI 128 +/* 129 */ +/* 130 */ +/* 131 */ +/* 132 */ +/* 133 */ +/* 134 */ +/* 135 */ +/* 136 */ +/* 137 */ +/* 138 */ +/* 139 */ +/* 140 */ +/* 141 */ +/* 142 */ +/* (bit affects xusb_falcon_src, xusb_fs_src, xusb_host_src and xusb_ss_src) */ +#define TEGRA210_CLK_XUSB_GATE 143 +#define TEGRA210_CLK_CILAB 144 +#define TEGRA210_CLK_CILCD 145 +#define TEGRA210_CLK_CILE 146 +#define TEGRA210_CLK_DSIALP 147 +#define TEGRA210_CLK_DSIBLP 148 +#define TEGRA210_CLK_ENTROPY 149 +/* 150 */ +/* 151 */ +/* 152 */ +/* 153 */ +/* 154 */ +/* 155 (bit affects dfll_ref and dfll_soc) */ +#define TEGRA210_CLK_XUSB_SS 156 +/* 157 */ +/* 158 */ +/* 159 */ + +/* 160 */ +#define TEGRA210_CLK_DMIC1 161 +#define TEGRA210_CLK_DMIC2 162 +/* 163 */ +/* 164 */ +/* 165 */ +#define TEGRA210_CLK_I2C6 166 +/* 167 */ +/* 168 */ +/* 169 */ +/* 170 */ +#define TEGRA210_CLK_VIM2_CLK 171 +/* 172 */ +#define TEGRA210_CLK_MIPIBIF 173 +/* 174 */ +/* 175 */ +/* 176 */ +#define TEGRA210_CLK_CLK72MHZ 177 +#define TEGRA210_CLK_VIC03 178 +/* 179 */ +/* 180 */ +#define TEGRA210_CLK_DPAUX 181 +#define TEGRA210_CLK_SOR0 182 +#define TEGRA210_CLK_SOR1 183 +#define TEGRA210_CLK_GPU 184 +#define TEGRA210_CLK_DBGAPB 185 +/* 186 */ +#define TEGRA210_CLK_PLL_P_OUT_ADSP 187 +/* 188 */ +#define TEGRA210_CLK_PLL_G_REF 189 +/* 190 */ +/* 191 */ + +/* 192 */ +#define TEGRA210_CLK_SDMMC_LEGACY 193 +#define TEGRA210_CLK_NVDEC 194 +#define TEGRA210_CLK_NVJPG 195 +/* 196 */ +#define TEGRA210_CLK_DMIC3 197 +#define TEGRA210_CLK_APE 198 +/* 199 */ +/* 200 */ +/* 201 */ +#define TEGRA210_CLK_MAUD 202 +/* 203 */ +/* 204 */ +/* 205 */ +#define TEGRA210_CLK_TSECB 206 +#define TEGRA210_CLK_DPAUX1 207 +#define TEGRA210_CLK_VI_I2C 208 +#define TEGRA210_CLK_HSIC_TRK 209 +#define TEGRA210_CLK_USB2_TRK 210 +#define TEGRA210_CLK_QSPI 211 +#define TEGRA210_CLK_UARTAPE 212 +/* 213 */ +/* 214 */ +/* 215 */ +/* 216 */ +/* 217 */ +/* 218 */ +#define TEGRA210_CLK_NVENC 219 +/* 220 */ +/* 221 */ +#define TEGRA210_CLK_SOR_SAFE 222 +#define TEGRA210_CLK_PLL_P_OUT_CPU 223 + + +#define TEGRA210_CLK_UARTB 224 +#define TEGRA210_CLK_VFIR 225 +#define TEGRA210_CLK_SPDIF_IN 226 +#define TEGRA210_CLK_SPDIF_OUT 227 +#define TEGRA210_CLK_VI 228 +#define TEGRA210_CLK_VI_SENSOR 229 +#define TEGRA210_CLK_FUSE 230 +#define TEGRA210_CLK_FUSE_BURN 231 +#define TEGRA210_CLK_CLK_32K 232 +#define TEGRA210_CLK_CLK_M 233 +#define TEGRA210_CLK_CLK_M_DIV2 234 +#define TEGRA210_CLK_CLK_M_DIV4 235 +#define TEGRA210_CLK_PLL_REF 236 +#define TEGRA210_CLK_PLL_C 237 +#define TEGRA210_CLK_PLL_C_OUT1 238 +#define TEGRA210_CLK_PLL_C2 239 +#define TEGRA210_CLK_PLL_C3 240 +#define TEGRA210_CLK_PLL_M 241 +#define TEGRA210_CLK_PLL_M_OUT1 242 +#define TEGRA210_CLK_PLL_P 243 +#define TEGRA210_CLK_PLL_P_OUT1 244 +#define TEGRA210_CLK_PLL_P_OUT2 245 +#define TEGRA210_CLK_PLL_P_OUT3 246 +#define TEGRA210_CLK_PLL_P_OUT4 247 +#define TEGRA210_CLK_PLL_A 248 +#define TEGRA210_CLK_PLL_A_OUT0 249 +#define TEGRA210_CLK_PLL_D 250 +#define TEGRA210_CLK_PLL_D_OUT0 251 +#define TEGRA210_CLK_PLL_D2 252 +#define TEGRA210_CLK_PLL_D2_OUT0 253 +#define TEGRA210_CLK_PLL_U 254 +#define TEGRA210_CLK_PLL_U_480M 255 + +#define TEGRA210_CLK_PLL_U_60M 256 +#define TEGRA210_CLK_PLL_U_48M 257 +/* 258 */ +#define TEGRA210_CLK_PLL_X 259 +#define TEGRA210_CLK_PLL_X_OUT0 260 +#define TEGRA210_CLK_PLL_RE_VCO 261 +#define TEGRA210_CLK_PLL_RE_OUT 262 +#define TEGRA210_CLK_PLL_E 263 +#define TEGRA210_CLK_SPDIF_IN_SYNC 264 +#define TEGRA210_CLK_I2S0_SYNC 265 +#define TEGRA210_CLK_I2S1_SYNC 266 +#define TEGRA210_CLK_I2S2_SYNC 267 +#define TEGRA210_CLK_I2S3_SYNC 268 +#define TEGRA210_CLK_I2S4_SYNC 269 +#define TEGRA210_CLK_VIMCLK_SYNC 270 +#define TEGRA210_CLK_AUDIO0 271 +#define TEGRA210_CLK_AUDIO1 272 +#define TEGRA210_CLK_AUDIO2 273 +#define TEGRA210_CLK_AUDIO3 274 +#define TEGRA210_CLK_AUDIO4 275 +#define TEGRA210_CLK_SPDIF 276 +#define TEGRA210_CLK_CLK_OUT_1 277 +#define TEGRA210_CLK_CLK_OUT_2 278 +#define TEGRA210_CLK_CLK_OUT_3 279 +#define TEGRA210_CLK_BLINK 280 +/* 281 */ +/* 282 */ +/* 283 */ +#define TEGRA210_CLK_XUSB_HOST_SRC 284 +#define TEGRA210_CLK_XUSB_FALCON_SRC 285 +#define TEGRA210_CLK_XUSB_FS_SRC 286 +#define TEGRA210_CLK_XUSB_SS_SRC 287 + +#define TEGRA210_CLK_XUSB_DEV_SRC 288 +#define TEGRA210_CLK_XUSB_DEV 289 +#define TEGRA210_CLK_XUSB_HS_SRC 290 +#define TEGRA210_CLK_SCLK 291 +#define TEGRA210_CLK_HCLK 292 +#define TEGRA210_CLK_PCLK 293 +#define TEGRA210_CLK_CCLK_G 294 +#define TEGRA210_CLK_CCLK_LP 295 +#define TEGRA210_CLK_DFLL_REF 296 +#define TEGRA210_CLK_DFLL_SOC 297 +#define TEGRA210_CLK_VI_SENSOR2 298 +#define TEGRA210_CLK_PLL_P_OUT5 299 +#define TEGRA210_CLK_CML0 300 +#define TEGRA210_CLK_CML1 301 +#define TEGRA210_CLK_PLL_C4 302 +#define TEGRA210_CLK_PLL_DP 303 +#define TEGRA210_CLK_PLL_E_MUX 304 +#define TEGRA210_CLK_PLL_MB 305 +#define TEGRA210_CLK_PLL_A1 306 +#define TEGRA210_CLK_PLL_D_DSI_OUT 307 +#define TEGRA210_CLK_PLL_C4_OUT0 308 +#define TEGRA210_CLK_PLL_C4_OUT1 309 +#define TEGRA210_CLK_PLL_C4_OUT2 310 +#define TEGRA210_CLK_PLL_C4_OUT3 311 +#define TEGRA210_CLK_PLL_U_OUT 312 +#define TEGRA210_CLK_PLL_U_OUT1 313 +#define TEGRA210_CLK_PLL_U_OUT2 314 +#define TEGRA210_CLK_USB2_HSIC_TRK 315 +#define TEGRA210_CLK_PLL_P_OUT_HSIO 316 +#define TEGRA210_CLK_PLL_P_OUT_XUSB 317 +#define TEGRA210_CLK_XUSB_SSP_SRC 318 +/* 319 */ +/* 320 */ +/* 321 */ +/* 322 */ +/* 323 */ +/* 324 */ +/* 325 */ +/* 326 */ +/* 327 */ +/* 328 */ +/* 329 */ +/* 330 */ +/* 331 */ +/* 332 */ +/* 333 */ +/* 334 */ +/* 335 */ +/* 336 */ +/* 337 */ +/* 338 */ +/* 339 */ +/* 340 */ +/* 341 */ +/* 342 */ +/* 343 */ +/* 344 */ +/* 345 */ +/* 346 */ +/* 347 */ +/* 348 */ +/* 349 */ + +#define TEGRA210_CLK_AUDIO0_MUX 350 +#define TEGRA210_CLK_AUDIO1_MUX 351 +#define TEGRA210_CLK_AUDIO2_MUX 352 +#define TEGRA210_CLK_AUDIO3_MUX 353 +#define TEGRA210_CLK_AUDIO4_MUX 354 +#define TEGRA210_CLK_SPDIF_MUX 355 +#define TEGRA210_CLK_CLK_OUT_1_MUX 356 +#define TEGRA210_CLK_CLK_OUT_2_MUX 357 +#define TEGRA210_CLK_CLK_OUT_3_MUX 358 +#define TEGRA210_CLK_DSIA_MUX 359 +#define TEGRA210_CLK_DSIB_MUX 360 +#define TEGRA210_CLK_SOR0_LVDS 361 +#define TEGRA210_CLK_XUSB_SS_DIV2 362 + +#define TEGRA210_CLK_PLL_M_UD 363 +#define TEGRA210_CLK_PLL_C_UD 364 +#define TEGRA210_CLK_SCLK_MUX 365 + +#define TEGRA210_CLK_CLK_MAX 366 + +#endif /* _DT_BINDINGS_CLOCK_TEGRA210_CAR_H */ -- cgit v1.2.3 From c4947e364b5096f00f3cfc0a7af2a4f688ffb919 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 18 Nov 2015 13:23:46 +0100 Subject: clk: tegra: Fix 26 MHz oscillator frequency The OSC_FREQ field of the OSC_CTRL register uses the value 12 for an oscillator frequency of 26 MHz, not 260 MHz. This isn't really critical because I don't think boards with such an oscillator have ever existed, much less been supported upstream. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra114.c | 2 +- drivers/clk/tegra/clk-tegra124.c | 2 +- drivers/clk/tegra/clk-tegra30.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index b7d03e9add97..9a50471009d8 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -625,7 +625,7 @@ static unsigned long tegra114_input_freq[] = { [5] = 38400000, [8] = 12000000, [9] = 48000000, - [12] = 260000000, + [12] = 26000000, }; #define MASK(x) (BIT(x) - 1) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 87975f7adddc..9b78e1c77f77 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -156,7 +156,7 @@ static unsigned long tegra124_input_freq[] = { [5] = 38400000, [8] = 12000000, [9] = 48000000, - [12] = 260000000, + [12] = 26000000, }; static struct div_nmp pllxc_nmp = { diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index b90db615c29e..c1d065d61156 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -583,7 +583,7 @@ static unsigned long tegra30_input_freq[] = { [5] = 38400000, [8] = 12000000, [9] = 48000000, - [12] = 260000000, + [12] = 26000000, }; static struct tegra_devclk devclks[] __initdata = { -- cgit v1.2.3 From e52d7c04bb3911d4ce98bd237f69f5246d9c7083 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 18 Nov 2015 14:04:20 +0100 Subject: clk: tegra: Miscellaneous coding style cleanups Use unsigned int for loop variables that can never become negative and remove a couple of gratuitous blank lines. Also use single spaces around operators and use a single space instead of a tab to separate comments from code. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 6 +++--- drivers/clk/tegra/clk-tegra114.c | 12 ++++++------ drivers/clk/tegra/clk-tegra124.c | 6 +++--- drivers/clk/tegra/clk-tegra20.c | 5 ++--- drivers/clk/tegra/clk-tegra30.c | 15 +++++---------- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index d6d4ecb88e94..c72340830521 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -439,7 +439,7 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, /* * PLL_P_OUT1 rate is not listed in PLLA table */ - cfreq = parent_rate/(parent_rate/1000000); + cfreq = parent_rate / (parent_rate / 1000000); break; default: pr_err("%s Unexpected reference rate %lu\n", @@ -936,8 +936,8 @@ static int _calc_dynamic_ramp_rate(struct clk_hw *hw, p_div = _p_div_to_hw(hw, p); if (p_div < 0) return p_div; - else - cfg->p = p_div; + + cfg->p = p_div; if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) return -EINVAL; diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9a50471009d8..8668ecd0046c 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -215,7 +215,7 @@ static struct tegra_clk_pll_params pll_c_params = { .input_min = 12000000, .input_max = 800000000, .cf_min = 12000000, - .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ .vco_min = 600000000, .vco_max = 1400000000, .base_reg = PLLC_BASE, @@ -337,7 +337,7 @@ static struct tegra_clk_pll_params pll_m_params = { .input_min = 12000000, .input_max = 500000000, .cf_min = 12000000, - .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ .vco_min = 400000000, .vco_max = 1066000000, .base_reg = PLLM_BASE, @@ -534,7 +534,7 @@ static struct tegra_clk_pll_params pll_x_params = { .input_min = 12000000, .input_max = 800000000, .cf_min = 12000000, - .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ .vco_min = 700000000, .vco_max = 2400000000U, .base_reg = PLLX_BASE, @@ -965,8 +965,8 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) static __init void tegra114_utmi_param_configure(void __iomem *clk_base) { + unsigned int i; u32 reg; - int i; for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { if (osc_freq == utmi_parameters[i].osc_frequency) @@ -1173,7 +1173,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base, { struct clk *clk; struct tegra_periph_init_data *data; - int i; + unsigned int i; /* xusb_ss_div2 */ clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, @@ -1278,7 +1278,7 @@ static struct tegra_cpu_car_ops tegra114_cpu_car_ops = { static const struct of_device_id pmc_match[] __initconst = { { .compatible = "nvidia,tegra114-pmc" }, - {}, + { }, }; /* diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 9b78e1c77f77..b58f58576e77 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -235,7 +235,7 @@ static struct tegra_clk_pll_params pll_c_params = { .input_min = 12000000, .input_max = 800000000, .cf_min = 12000000, - .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ .vco_min = 600000000, .vco_max = 1400000000, .base_reg = PLLC_BASE, @@ -1024,8 +1024,8 @@ static struct clk **clks; static void tegra124_utmi_param_configure(void __iomem *clk_base) { + unsigned int i; u32 reg; - int i; for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { if (osc_freq == utmi_parameters[i].osc_frequency) @@ -1356,7 +1356,7 @@ static struct tegra_cpu_car_ops tegra124_cpu_car_ops = { static const struct of_device_id pmc_match[] __initconst = { { .compatible = "nvidia,tegra124-pmc" }, - {}, + { }, }; static struct tegra_clk_init_table common_init_table[] __initdata = { diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index bf004f0e4f65..319e80ef69e1 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -759,7 +759,6 @@ static void __init tegra20_audio_clk_init(void) CLK_SET_RATE_PARENT, 89, periph_clk_enb_refcnt); clks[TEGRA20_CLK_AUDIO_2X] = clk; - } static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", @@ -802,7 +801,7 @@ static void __init tegra20_periph_clk_init(void) { struct tegra_periph_init_data *data; struct clk *clk; - int i; + unsigned int i; /* ac97 */ clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", @@ -1085,7 +1084,7 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { static const struct of_device_id pmc_match[] __initconst = { { .compatible = "nvidia,tegra20-pmc" }, - {}, + { }, }; static void __init tegra20_clock_init(struct device_node *np) diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index c1d065d61156..b670e315be4d 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -505,7 +505,6 @@ static struct tegra_clk_pll_params pll_d_params = { .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, - }; static struct tegra_clk_pll_params pll_d2_params = { @@ -861,13 +860,12 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [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 }, - }; static void tegra30_utmi_param_configure(void) { + unsigned int i; u32 reg; - int i; for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { if (input_freq == utmi_parameters[i].osc_frequency) @@ -925,7 +923,7 @@ static void __init tegra30_pll_init(void) /* PLLC */ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, - &pll_c_params, NULL); + &pll_c_params, NULL); clks[TEGRA30_CLK_PLL_C] = clk; /* PLLC_OUT1 */ @@ -1135,7 +1133,7 @@ static void __init tegra30_periph_clk_init(void) { struct tegra_periph_init_data *data; struct clk *clk; - int i; + unsigned int i; /* dsia */ clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, @@ -1224,7 +1222,6 @@ static void tegra30_cpu_out_of_reset(u32 cpu) wmb(); } - static void tegra30_enable_cpu_clock(u32 cpu) { unsigned int reg; @@ -1237,7 +1234,6 @@ static void tegra30_enable_cpu_clock(u32 cpu) static void tegra30_disable_cpu_clock(u32 cpu) { - unsigned int reg; reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); @@ -1268,7 +1264,7 @@ 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); - writel(3<<30, clk_base + CLK_RESET_SOURCE_CSITE); + writel(3 << 30, clk_base + CLK_RESET_SOURCE_CSITE); tegra30_cpu_clk_sctx.cpu_burst = readl(clk_base + CLK_RESET_CCLK_BURST); @@ -1402,7 +1398,7 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { static const struct of_device_id pmc_match[] __initconst = { { .compatible = "nvidia,tegra30-pmc" }, - {}, + { }, }; static struct tegra_audio_clk_info tegra30_audio_plls[] = { @@ -1441,7 +1437,6 @@ static void __init tegra30_clock_init(struct device_node *np) NULL) < 0) return; - tegra_fixed_clk_init(tegra30_clks); tegra30_pll_init(); tegra30_super_clk_init(); -- cgit v1.2.3 From 8d99704fde54cd1df08065801e9b3196d88630f1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 18 Nov 2015 14:10:02 +0100 Subject: clk: tegra: Format tables consistently Use spaces around { and } and pad values so that the cells are properly aligned. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra114.c | 273 ++++++++++++++-------------- drivers/clk/tegra/clk-tegra124.c | 370 +++++++++++++++++++------------------- drivers/clk/tegra/clk-tegra20.c | 277 ++++++++++++++-------------- drivers/clk/tegra/clk-tegra30.c | 378 +++++++++++++++++++-------------------- 4 files changed, 646 insertions(+), 652 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 8668ecd0046c..1931f84f2a14 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -183,32 +183,32 @@ static struct div_nmp pllxc_nmp = { }; static struct pdiv_map pllxc_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 3, .hw_val = 2 }, - { .pdiv = 4, .hw_val = 3 }, - { .pdiv = 5, .hw_val = 4 }, - { .pdiv = 6, .hw_val = 5 }, - { .pdiv = 8, .hw_val = 6 }, - { .pdiv = 10, .hw_val = 7 }, - { .pdiv = 12, .hw_val = 8 }, - { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, { .pdiv = 12, .hw_val = 10 }, { .pdiv = 16, .hw_val = 11 }, { .pdiv = 20, .hw_val = 12 }, { .pdiv = 24, .hw_val = 13 }, { .pdiv = 32, .hw_val = 14 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 624000000, 104, 0, 2}, - { 12000000, 600000000, 100, 0, 2}, - { 13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 624000000, 104, 0, 2, 0 }, + { 12000000, 600000000, 100, 0, 2, 0 }, + { 13000000, 600000000, 92, 0, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 0, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 0, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_c_params = { @@ -245,21 +245,21 @@ static struct div_nmp pllcx_nmp = { }; static struct pdiv_map pllc_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 4, .hw_val = 3 }, - { .pdiv = 8, .hw_val = 5 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 8, .hw_val = 5 }, { .pdiv = 16, .hw_val = 7 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { - {12000000, 600000000, 100, 0, 2}, - {13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */ - {16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */ - {19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */ - {26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ - {0, 0, 0, 0, 0, 0}, + { 12000000, 600000000, 100, 0, 2, 0 }, + { 13000000, 600000000, 92, 0, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 0, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 0, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_c2_params = { @@ -325,12 +325,12 @@ static struct pdiv_map pllm_p[] = { }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - {12000000, 800000000, 66, 0, 1}, /* actual: 792.0 MHz */ - {13000000, 800000000, 61, 0, 1}, /* actual: 793.0 MHz */ - {16800000, 800000000, 47, 0, 1}, /* actual: 789.6 MHz */ - {19200000, 800000000, 41, 0, 1}, /* actual: 787.2 MHz */ - {26000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ - {0, 0, 0, 0, 0, 0}, + { 12000000, 800000000, 66, 0, 1, 0 }, /* actual: 792.0 MHz */ + { 13000000, 800000000, 61, 0, 1, 0 }, /* actual: 793.0 MHz */ + { 16800000, 800000000, 47, 0, 1, 0 }, /* actual: 789.6 MHz */ + { 19200000, 800000000, 41, 0, 1, 0 }, /* actual: 787.2 MHz */ + { 26000000, 800000000, 61, 1, 1, 0 }, /* actual: 793.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_m_params = { @@ -364,12 +364,12 @@ static struct div_nmp pllp_nmp = { }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - {12000000, 216000000, 432, 12, 1, 8}, - {13000000, 216000000, 432, 13, 1, 8}, - {16800000, 216000000, 360, 14, 1, 8}, - {19200000, 216000000, 360, 16, 1, 8}, - {26000000, 216000000, 432, 26, 1, 8}, - {0, 0, 0, 0, 0, 0}, + { 12000000, 216000000, 432, 12, 1, 8 }, + { 13000000, 216000000, 432, 13, 1, 8 }, + { 16800000, 216000000, 360, 14, 1, 8 }, + { 19200000, 216000000, 360, 16, 1, 8 }, + { 26000000, 216000000, 432, 26, 1, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_p_params = { @@ -391,14 +391,13 @@ static struct tegra_clk_pll_params pll_p_params = { }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - {9600000, 282240000, 147, 5, 0, 4}, - {9600000, 368640000, 192, 5, 0, 4}, - {9600000, 240000000, 200, 8, 0, 8}, - - {28800000, 282240000, 245, 25, 0, 8}, - {28800000, 368640000, 320, 25, 0, 8}, - {28800000, 240000000, 200, 24, 0, 8}, - {0, 0, 0, 0, 0, 0}, + { 9600000, 282240000, 147, 5, 0, 4 }, + { 9600000, 368640000, 192, 5, 0, 4 }, + { 9600000, 240000000, 200, 8, 0, 8 }, + { 28800000, 282240000, 245, 25, 0, 8 }, + { 28800000, 368640000, 320, 25, 0, 8 }, + { 28800000, 240000000, 200, 24, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; @@ -420,24 +419,21 @@ static struct tegra_clk_pll_params pll_a_params = { }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - {12000000, 216000000, 864, 12, 2, 12}, - {13000000, 216000000, 864, 13, 2, 12}, - {16800000, 216000000, 720, 14, 2, 12}, - {19200000, 216000000, 720, 16, 2, 12}, - {26000000, 216000000, 864, 26, 2, 12}, - - {12000000, 594000000, 594, 12, 0, 12}, - {13000000, 594000000, 594, 13, 0, 12}, - {16800000, 594000000, 495, 14, 0, 12}, - {19200000, 594000000, 495, 16, 0, 12}, - {26000000, 594000000, 594, 26, 0, 12}, - - {12000000, 1000000000, 1000, 12, 0, 12}, - {13000000, 1000000000, 1000, 13, 0, 12}, - {19200000, 1000000000, 625, 12, 0, 12}, - {26000000, 1000000000, 1000, 26, 0, 12}, - - {0, 0, 0, 0, 0, 0}, + { 12000000, 216000000, 864, 12, 2, 12 }, + { 13000000, 216000000, 864, 13, 2, 12 }, + { 16800000, 216000000, 720, 14, 2, 12 }, + { 19200000, 216000000, 720, 16, 2, 12 }, + { 26000000, 216000000, 864, 26, 2, 12 }, + { 12000000, 594000000, 594, 12, 0, 12 }, + { 13000000, 594000000, 594, 13, 0, 12 }, + { 16800000, 594000000, 495, 14, 0, 12 }, + { 19200000, 594000000, 495, 16, 0, 12 }, + { 26000000, 594000000, 594, 26, 0, 12 }, + { 12000000, 1000000000, 1000, 12, 0, 12 }, + { 13000000, 1000000000, 1000, 13, 0, 12 }, + { 19200000, 1000000000, 625, 12, 0, 12 }, + { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_d_params = { @@ -492,12 +488,12 @@ static struct div_nmp pllu_nmp = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - {12000000, 480000000, 960, 12, 0, 12}, - {13000000, 480000000, 960, 13, 0, 12}, - {16800000, 480000000, 400, 7, 0, 5}, - {19200000, 480000000, 200, 4, 0, 3}, - {26000000, 480000000, 960, 26, 0, 12}, - {0, 0, 0, 0, 0, 0}, + { 12000000, 480000000, 960, 12, 0, 12 }, + { 13000000, 480000000, 960, 13, 0, 12 }, + { 16800000, 480000000, 400, 7, 0, 5 }, + { 19200000, 480000000, 200, 4, 0, 3 }, + { 26000000, 480000000, 960, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_u_params = { @@ -521,13 +517,12 @@ static struct tegra_clk_pll_params pll_u_params = { static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ - {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ - {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ - {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ - {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ - - {0, 0, 0, 0, 0, 0}, + { 12000000, 1000000000, 83, 0, 1, 0 }, /* actual: 996.0 MHz */ + { 13000000, 1000000000, 76, 0, 1, 0 }, /* actual: 988.0 MHz */ + { 16800000, 1000000000, 59, 0, 1, 0 }, /* actual: 991.2 MHz */ + { 19200000, 1000000000, 52, 0, 1, 0 }, /* actual: 998.4 MHz */ + { 26000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_x_params = { @@ -556,10 +551,10 @@ static struct tegra_clk_pll_params pll_x_params = { static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ - {336000000, 100000000, 100, 21, 16, 11}, - {312000000, 100000000, 200, 26, 24, 13}, - {12000000, 100000000, 200, 1, 24, 13}, - {0, 0, 0, 0, 0, 0}, + { 336000000, 100000000, 100, 21, 16, 11 }, + { 312000000, 100000000, 200, 26, 24, 13 }, + { 12000000, 100000000, 200, 1, 24, 13 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct div_nmp plle_nmp = { @@ -619,12 +614,12 @@ static struct tegra_clk_pll_params pll_re_vco_params = { /* possible OSC frequencies in Hz */ static unsigned long tegra114_input_freq[] = { - [0] = 13000000, - [1] = 16800000, - [4] = 19200000, - [5] = 38400000, - [8] = 12000000, - [9] = 48000000, + [ 0] = 13000000, + [ 1] = 16800000, + [ 4] = 19200000, + [ 5] = 38400000, + [ 8] = 12000000, + [ 9] = 48000000, [12] = 26000000, }; @@ -644,21 +639,27 @@ struct utmi_clk_param { }; static const struct utmi_clk_param utmi_parameters[] = { - {.osc_frequency = 13000000, .enable_delay_count = 0x02, - .stable_count = 0x33, .active_delay_count = 0x05, - .xtal_freq_count = 0x7F}, - {.osc_frequency = 19200000, .enable_delay_count = 0x03, - .stable_count = 0x4B, .active_delay_count = 0x06, - .xtal_freq_count = 0xBB}, - {.osc_frequency = 12000000, .enable_delay_count = 0x02, - .stable_count = 0x2F, .active_delay_count = 0x04, - .xtal_freq_count = 0x76}, - {.osc_frequency = 26000000, .enable_delay_count = 0x04, - .stable_count = 0x66, .active_delay_count = 0x09, - .xtal_freq_count = 0xFE}, - {.osc_frequency = 16800000, .enable_delay_count = 0x03, - .stable_count = 0x41, .active_delay_count = 0x0A, - .xtal_freq_count = 0xA4}, + { + .osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7f + }, { + .osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4b, .active_delay_count = 0x06, + .xtal_freq_count = 0xbb + }, { + .osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2f, .active_delay_count = 0x04, + .xtal_freq_count = 0x76 + }, { + .osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xfe + }, { + .osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0a, + .xtal_freq_count = 0xa4 + }, }; /* peripheral mux definitions */ @@ -1286,37 +1287,37 @@ static const struct of_device_id pmc_match[] __initconst = { * breaks */ static struct tegra_clk_init_table init_table[] __initdata = { - {TEGRA114_CLK_UARTA, TEGRA114_CLK_PLL_P, 408000000, 0}, - {TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0}, - {TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0}, - {TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0}, - {TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1}, - {TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1}, - {TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1}, - {TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1}, - {TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1}, - {TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, - {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, - {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, - {TEGRA114_CLK_DISP1, TEGRA114_CLK_PLL_P, 0, 0}, - {TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0}, - {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, - {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, - {TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0}, - {TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0}, - {TEGRA114_CLK_PLL_RE_VCO, TEGRA114_CLK_CLK_MAX, 612000000, 0}, - {TEGRA114_CLK_XUSB_SS_SRC, TEGRA114_CLK_PLL_RE_OUT, 122400000, 0}, - {TEGRA114_CLK_XUSB_FS_SRC, TEGRA114_CLK_PLL_U_48M, 48000000, 0}, - {TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0}, - {TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0}, - {TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0}, - /* This MUST be the last entry. */ - {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, + { TEGRA114_CLK_UARTA, TEGRA114_CLK_PLL_P, 408000000, 0 }, + { TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0 }, + { TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0 }, + { TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0 }, + { TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1 }, + { TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1 }, + { TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1 }, + { TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1 }, + { TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1 }, + { TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0 }, + { TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1 }, + { TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1 }, + { TEGRA114_CLK_DISP1, TEGRA114_CLK_PLL_P, 0, 0 }, + { TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0 }, + { TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0 }, + { TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0 }, + { TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0 }, + { TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0 }, + { TEGRA114_CLK_PLL_RE_VCO, TEGRA114_CLK_CLK_MAX, 612000000, 0 }, + { TEGRA114_CLK_XUSB_SS_SRC, TEGRA114_CLK_PLL_RE_OUT, 122400000, 0 }, + { TEGRA114_CLK_XUSB_FS_SRC, TEGRA114_CLK_PLL_U_48M, 48000000, 0 }, + { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 }, + { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 }, + { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 }, + /* must be the last entry */ + { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 }, }; static void __init tegra114_clock_apply_init_table(void) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index b58f58576e77..d98bf688b3b0 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -150,12 +150,12 @@ static DEFINE_SPINLOCK(emc_lock); /* possible OSC frequencies in Hz */ static unsigned long tegra124_input_freq[] = { - [0] = 13000000, - [1] = 16800000, - [4] = 19200000, - [5] = 38400000, - [8] = 12000000, - [9] = 48000000, + [ 0] = 13000000, + [ 1] = 16800000, + [ 4] = 19200000, + [ 5] = 38400000, + [ 8] = 12000000, + [ 9] = 48000000, [12] = 26000000, }; @@ -169,32 +169,32 @@ static struct div_nmp pllxc_nmp = { }; static struct pdiv_map pllxc_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 3, .hw_val = 2 }, - { .pdiv = 4, .hw_val = 3 }, - { .pdiv = 5, .hw_val = 4 }, - { .pdiv = 6, .hw_val = 5 }, - { .pdiv = 8, .hw_val = 6 }, - { .pdiv = 10, .hw_val = 7 }, - { .pdiv = 12, .hw_val = 8 }, - { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, { .pdiv = 12, .hw_val = 10 }, { .pdiv = 16, .hw_val = 11 }, { .pdiv = 20, .hw_val = 12 }, { .pdiv = 24, .hw_val = 13 }, { .pdiv = 32, .hw_val = 14 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ - {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ - {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ - {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ - {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ - {0, 0, 0, 0, 0, 0}, + { 12000000, 1000000000, 83, 0, 1, 0 }, /* actual: 996.0 MHz */ + { 13000000, 1000000000, 76, 0, 1, 0 }, /* actual: 988.0 MHz */ + { 16800000, 1000000000, 59, 0, 1, 0 }, /* actual: 991.2 MHz */ + { 19200000, 1000000000, 52, 0, 1, 0 }, /* actual: 998.4 MHz */ + { 26000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_x_params = { @@ -222,13 +222,13 @@ static struct tegra_clk_pll_params pll_x_params = { }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 624000000, 104, 1, 2}, - { 12000000, 600000000, 100, 1, 2}, - { 13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 624000000, 104, 1, 2, 0 }, + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_c_params = { @@ -265,24 +265,24 @@ static struct div_nmp pllcx_nmp = { }; static struct pdiv_map pllc_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 3, .hw_val = 2 }, - { .pdiv = 4, .hw_val = 3 }, - { .pdiv = 6, .hw_val = 4 }, - { .pdiv = 8, .hw_val = 5 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 6, .hw_val = 4 }, + { .pdiv = 8, .hw_val = 5 }, { .pdiv = 12, .hw_val = 6 }, { .pdiv = 16, .hw_val = 7 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { - {12000000, 600000000, 100, 1, 2}, - {13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ - {16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ - {19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ - {26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ - {0, 0, 0, 0, 0, 0}, + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_c2_params = { @@ -339,31 +339,31 @@ static struct div_nmp pllss_nmp = { }; static struct pdiv_map pll12g_ssd_esd_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 3, .hw_val = 2 }, - { .pdiv = 4, .hw_val = 3 }, - { .pdiv = 5, .hw_val = 4 }, - { .pdiv = 6, .hw_val = 5 }, - { .pdiv = 8, .hw_val = 6 }, - { .pdiv = 10, .hw_val = 7 }, - { .pdiv = 12, .hw_val = 8 }, - { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, { .pdiv = 12, .hw_val = 10 }, { .pdiv = 16, .hw_val = 11 }, { .pdiv = 20, .hw_val = 12 }, { .pdiv = 24, .hw_val = 13 }, { .pdiv = 32, .hw_val = 14 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_c4_freq_table[] = { - { 12000000, 600000000, 100, 1, 1}, - { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 600000000, 100, 1, 1, 0 }, + { 13000000, 600000000, 92, 1, 1, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_c4_params = { @@ -395,12 +395,12 @@ static struct pdiv_map pllm_p[] = { }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - {12000000, 800000000, 66, 1, 1}, /* actual: 792.0 MHz */ - {13000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ - {16800000, 800000000, 47, 1, 1}, /* actual: 789.6 MHz */ - {19200000, 800000000, 41, 1, 1}, /* actual: 787.2 MHz */ - {26000000, 800000000, 61, 2, 1}, /* actual: 793.0 MHz */ - {0, 0, 0, 0, 0, 0}, + { 12000000, 800000000, 66, 1, 1, 0 }, /* actual: 792.0 MHz */ + { 13000000, 800000000, 61, 1, 1, 0 }, /* actual: 793.0 MHz */ + { 16800000, 800000000, 47, 1, 1, 0 }, /* actual: 789.6 MHz */ + { 19200000, 800000000, 41, 1, 1, 0 }, /* actual: 787.2 MHz */ + { 26000000, 800000000, 61, 2, 1, 0 }, /* actual: 793.0 MHz */ + { 0, 0, 0, 0, 0, 0}, }; static struct div_nmp pllm_nmp = { @@ -438,11 +438,11 @@ static struct tegra_clk_pll_params pll_m_params = { static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ - {336000000, 100000000, 100, 21, 16, 11}, - {312000000, 100000000, 200, 26, 24, 13}, - {13000000, 100000000, 200, 1, 26, 13}, - {12000000, 100000000, 200, 1, 24, 13}, - {0, 0, 0, 0, 0, 0}, + { 336000000, 100000000, 100, 21, 16, 11 }, + { 312000000, 100000000, 200, 26, 24, 13 }, + { 13000000, 100000000, 200, 1, 26, 13 }, + { 12000000, 100000000, 200, 1, 24, 13 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct div_nmp plle_nmp = { @@ -520,12 +520,12 @@ static struct div_nmp pllp_nmp = { }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - {12000000, 408000000, 408, 12, 0, 8}, - {13000000, 408000000, 408, 13, 0, 8}, - {16800000, 408000000, 340, 14, 0, 8}, - {19200000, 408000000, 340, 16, 0, 8}, - {26000000, 408000000, 408, 26, 0, 8}, - {0, 0, 0, 0, 0, 0}, + { 12000000, 408000000, 408, 12, 0, 8 }, + { 13000000, 408000000, 408, 13, 0, 8 }, + { 16800000, 408000000, 340, 14, 0, 8 }, + { 19200000, 408000000, 340, 16, 0, 8 }, + { 26000000, 408000000, 408, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_p_params = { @@ -547,14 +547,13 @@ static struct tegra_clk_pll_params pll_p_params = { }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - {9600000, 282240000, 147, 5, 0, 4}, - {9600000, 368640000, 192, 5, 0, 4}, - {9600000, 240000000, 200, 8, 0, 8}, - - {28800000, 282240000, 245, 25, 0, 8}, - {28800000, 368640000, 320, 25, 0, 8}, - {28800000, 240000000, 200, 24, 0, 8}, - {0, 0, 0, 0, 0, 0}, + { 9600000, 282240000, 147, 5, 0, 4 }, + { 9600000, 368640000, 192, 5, 0, 4 }, + { 9600000, 240000000, 200, 8, 0, 8 }, + { 28800000, 282240000, 245, 25, 0, 8 }, + { 28800000, 368640000, 320, 25, 0, 8 }, + { 28800000, 240000000, 200, 24, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_a_params = { @@ -584,24 +583,21 @@ static struct div_nmp plld_nmp = { }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - {12000000, 216000000, 864, 12, 4, 12}, - {13000000, 216000000, 864, 13, 4, 12}, - {16800000, 216000000, 720, 14, 4, 12}, - {19200000, 216000000, 720, 16, 4, 12}, - {26000000, 216000000, 864, 26, 4, 12}, - - {12000000, 594000000, 594, 12, 1, 12}, - {13000000, 594000000, 594, 13, 1, 12}, - {16800000, 594000000, 495, 14, 1, 12}, - {19200000, 594000000, 495, 16, 1, 12}, - {26000000, 594000000, 594, 26, 1, 12}, - - {12000000, 1000000000, 1000, 12, 1, 12}, - {13000000, 1000000000, 1000, 13, 1, 12}, - {19200000, 1000000000, 625, 12, 1, 12}, - {26000000, 1000000000, 1000, 26, 1, 12}, - - {0, 0, 0, 0, 0, 0}, + { 12000000, 216000000, 864, 12, 4, 12 }, + { 13000000, 216000000, 864, 13, 4, 12 }, + { 16800000, 216000000, 720, 14, 4, 12 }, + { 19200000, 216000000, 720, 16, 4, 12 }, + { 26000000, 216000000, 864, 26, 4, 12 }, + { 12000000, 594000000, 594, 12, 1, 12 }, + { 13000000, 594000000, 594, 13, 1, 12 }, + { 16800000, 594000000, 495, 14, 1, 12 }, + { 19200000, 594000000, 495, 16, 1, 12 }, + { 26000000, 594000000, 594, 26, 1, 12 }, + { 12000000, 1000000000, 1000, 12, 1, 12 }, + { 13000000, 1000000000, 1000, 13, 1, 12 }, + { 19200000, 1000000000, 625, 12, 1, 12 }, + { 26000000, 1000000000, 1000, 26, 1, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_d_params = { @@ -623,12 +619,12 @@ static struct tegra_clk_pll_params pll_d_params = { }; static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { - { 12000000, 594000000, 99, 1, 2}, - { 13000000, 594000000, 91, 1, 2}, /* actual: 591.5 MHz */ - { 16800000, 594000000, 71, 1, 2}, /* actual: 596.4 MHz */ - { 19200000, 594000000, 62, 1, 2}, /* actual: 595.2 MHz */ - { 26000000, 594000000, 91, 2, 2}, /* actual: 591.5 MHz */ - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 594000000, 99, 1, 2, 0 }, + { 13000000, 594000000, 91, 1, 2, 0 }, /* actual: 591.5 MHz */ + { 16800000, 594000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 594000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 594000000, 91, 2, 2, 0 }, /* actual: 591.5 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params tegra124_pll_d2_params = { @@ -655,12 +651,12 @@ static struct tegra_clk_pll_params tegra124_pll_d2_params = { }; static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { - { 12000000, 600000000, 100, 1, 1}, - { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 600000000, 100, 1, 1, 0 }, + { 13000000, 600000000, 92, 1, 1, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 1, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 1, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 1, 0 }, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_dp_params = { @@ -702,12 +698,12 @@ static struct div_nmp pllu_nmp = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - {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}, - {0, 0, 0, 0, 0, 0}, + { 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 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_params pll_u_params = { @@ -743,21 +739,27 @@ struct utmi_clk_param { }; static const struct utmi_clk_param utmi_parameters[] = { - {.osc_frequency = 13000000, .enable_delay_count = 0x02, - .stable_count = 0x33, .active_delay_count = 0x05, - .xtal_freq_count = 0x7F}, - {.osc_frequency = 19200000, .enable_delay_count = 0x03, - .stable_count = 0x4B, .active_delay_count = 0x06, - .xtal_freq_count = 0xBB}, - {.osc_frequency = 12000000, .enable_delay_count = 0x02, - .stable_count = 0x2F, .active_delay_count = 0x04, - .xtal_freq_count = 0x76}, - {.osc_frequency = 26000000, .enable_delay_count = 0x04, - .stable_count = 0x66, .active_delay_count = 0x09, - .xtal_freq_count = 0xFE}, - {.osc_frequency = 16800000, .enable_delay_count = 0x03, - .stable_count = 0x41, .active_delay_count = 0x0A, - .xtal_freq_count = 0xA4}, + { + .osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7f + }, { + .osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4b, .active_delay_count = 0x06, + .xtal_freq_count = 0xbb + }, { + .osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2f, .active_delay_count = 0x04, + .xtal_freq_count = 0x76 + }, { + .osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xfe + }, { + .osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0a, + .xtal_freq_count = 0xa4 + }, }; static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { @@ -1360,61 +1362,61 @@ static const struct of_device_id pmc_match[] __initconst = { }; static struct tegra_clk_init_table common_init_table[] __initdata = { - {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, - {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, - {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, - {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0}, - {TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1}, - {TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1}, - {TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1}, - {TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1}, - {TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1}, - {TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0}, - {TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1}, - {TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0}, - {TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0}, - {TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1}, - {TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1}, - {TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1}, - {TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0}, - {TEGRA124_CLK_PLL_C_OUT1, TEGRA124_CLK_CLK_MAX, 100000000, 0}, - {TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1}, - {TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0}, - {TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0}, - {TEGRA124_CLK_PLL_RE_VCO, TEGRA124_CLK_CLK_MAX, 672000000, 0}, - {TEGRA124_CLK_XUSB_SS_SRC, TEGRA124_CLK_PLL_U_480M, 120000000, 0}, - {TEGRA124_CLK_XUSB_FS_SRC, TEGRA124_CLK_PLL_U_48M, 48000000, 0}, - {TEGRA124_CLK_XUSB_HS_SRC, TEGRA124_CLK_PLL_U_60M, 60000000, 0}, - {TEGRA124_CLK_XUSB_FALCON_SRC, TEGRA124_CLK_PLL_RE_OUT, 224000000, 0}, - {TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0}, - {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0}, - {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0}, - {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1}, - {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1}, - {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0}, - /* This MUST be the last entry. */ - {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, + { TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0 }, + { TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 }, + { TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0 }, + { TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0 }, + { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1 }, + { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1 }, + { TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1 }, + { TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1 }, + { TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1 }, + { TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0 }, + { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, + { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, + { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, + { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1 }, + { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 }, + { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 }, + { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 }, + { TEGRA124_CLK_PLL_C_OUT1, TEGRA124_CLK_CLK_MAX, 100000000, 0 }, + { TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1 }, + { TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0 }, + { TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0 }, + { TEGRA124_CLK_PLL_RE_VCO, TEGRA124_CLK_CLK_MAX, 672000000, 0 }, + { TEGRA124_CLK_XUSB_SS_SRC, TEGRA124_CLK_PLL_U_480M, 120000000, 0 }, + { TEGRA124_CLK_XUSB_FS_SRC, TEGRA124_CLK_PLL_U_48M, 48000000, 0 }, + { TEGRA124_CLK_XUSB_HS_SRC, TEGRA124_CLK_PLL_U_60M, 60000000, 0 }, + { TEGRA124_CLK_XUSB_FALCON_SRC, TEGRA124_CLK_PLL_RE_OUT, 224000000, 0 }, + { TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0 }, + { TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0 }, + { TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0 }, + { TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1 }, + { TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1 }, + { TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0 }, + /* must be the last entry */ + { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, }; static struct tegra_clk_init_table tegra124_init_table[] __initdata = { - {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0}, - {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1}, - {TEGRA124_CLK_HDA, TEGRA124_CLK_PLL_P, 102000000, 0}, - {TEGRA124_CLK_HDA2CODEC_2X, TEGRA124_CLK_PLL_P, 48000000, 0}, - /* This MUST be the last entry. */ - {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, + { TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0 }, + { TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1 }, + { TEGRA124_CLK_HDA, TEGRA124_CLK_PLL_P, 102000000, 0 }, + { TEGRA124_CLK_HDA2CODEC_2X, TEGRA124_CLK_PLL_P, 48000000, 0 }, + /* must be the last entry */ + { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, }; /* Tegra132 requires the SOC_THERM clock to remain active */ static struct tegra_clk_init_table tegra132_init_table[] __initdata = { - {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1}, - /* This MUST be the last entry. */ - {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, + { TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1 }, + /* must be the last entry */ + { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, }; static struct tegra_audio_clk_info tegra124_audio_plls[] = { diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 319e80ef69e1..7ac9aba59f69 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -170,122 +170,111 @@ static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { { 13000000, 600000000, 600, 13, 0, 8 }, { 19200000, 600000000, 500, 16, 0, 6 }, { 26000000, 600000000, 600, 26, 0, 8 }, - { 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 0, 8}, - { 13000000, 666000000, 666, 13, 0, 8}, - { 19200000, 666000000, 555, 16, 0, 8}, - { 26000000, 666000000, 666, 26, 0, 8}, - { 12000000, 600000000, 600, 12, 0, 8}, - { 13000000, 600000000, 600, 13, 0, 8}, - { 19200000, 600000000, 375, 12, 0, 6}, - { 26000000, 600000000, 600, 26, 0, 8}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 666000000, 666, 12, 0, 8 }, + { 13000000, 666000000, 666, 13, 0, 8 }, + { 19200000, 666000000, 555, 16, 0, 8 }, + { 26000000, 666000000, 666, 26, 0, 8 }, + { 12000000, 600000000, 600, 12, 0, 8 }, + { 13000000, 600000000, 600, 13, 0, 8 }, + { 19200000, 600000000, 375, 12, 0, 6 }, + { 26000000, 600000000, 600, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 1, 8}, - { 13000000, 216000000, 432, 13, 1, 8}, - { 19200000, 216000000, 90, 4, 1, 1}, - { 26000000, 216000000, 432, 26, 1, 8}, - { 12000000, 432000000, 432, 12, 0, 8}, - { 13000000, 432000000, 432, 13, 0, 8}, - { 19200000, 432000000, 90, 4, 0, 1}, - { 26000000, 432000000, 432, 26, 0, 8}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 216000000, 432, 12, 1, 8 }, + { 13000000, 216000000, 432, 13, 1, 8 }, + { 19200000, 216000000, 90, 4, 1, 1 }, + { 26000000, 216000000, 432, 26, 1, 8 }, + { 12000000, 432000000, 432, 12, 0, 8 }, + { 13000000, 432000000, 432, 13, 0, 8 }, + { 19200000, 432000000, 90, 4, 0, 1 }, + { 26000000, 432000000, 432, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 28800000, 56448000, 49, 25, 0, 1}, - { 28800000, 73728000, 64, 25, 0, 1}, - { 28800000, 24000000, 5, 6, 0, 1}, - { 0, 0, 0, 0, 0, 0 }, + { 28800000, 56448000, 49, 25, 0, 1 }, + { 28800000, 73728000, 64, 25, 0, 1 }, + { 28800000, 24000000, 5, 6, 0, 1 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 0, 4}, - { 13000000, 216000000, 216, 13, 0, 4}, - { 19200000, 216000000, 135, 12, 0, 3}, - { 26000000, 216000000, 216, 26, 0, 4}, - - { 12000000, 594000000, 594, 12, 0, 8}, - { 13000000, 594000000, 594, 13, 0, 8}, - { 19200000, 594000000, 495, 16, 0, 8}, - { 26000000, 594000000, 594, 26, 0, 8}, - - { 12000000, 1000000000, 1000, 12, 0, 12}, - { 13000000, 1000000000, 1000, 13, 0, 12}, - { 19200000, 1000000000, 625, 12, 0, 8}, - { 26000000, 1000000000, 1000, 26, 0, 12}, - - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 216000000, 216, 12, 0, 4 }, + { 13000000, 216000000, 216, 13, 0, 4 }, + { 19200000, 216000000, 135, 12, 0, 3 }, + { 26000000, 216000000, 216, 26, 0, 4 }, + { 12000000, 594000000, 594, 12, 0, 8 }, + { 13000000, 594000000, 594, 13, 0, 8 }, + { 19200000, 594000000, 495, 16, 0, 8 }, + { 26000000, 594000000, 594, 26, 0, 8 }, + { 12000000, 1000000000, 1000, 12, 0, 12 }, + { 13000000, 1000000000, 1000, 13, 0, 12 }, + { 19200000, 1000000000, 625, 12, 0, 8 }, + { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 0}, - { 13000000, 480000000, 960, 13, 0, 0}, - { 19200000, 480000000, 200, 4, 0, 0}, - { 26000000, 480000000, 960, 26, 0, 0}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 480000000, 960, 12, 0, 0 }, + { 13000000, 480000000, 960, 13, 0, 0 }, + { 19200000, 480000000, 200, 4, 0, 0 }, + { 26000000, 480000000, 960, 26, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 0, 12}, - { 13000000, 1000000000, 1000, 13, 0, 12}, - { 19200000, 1000000000, 625, 12, 0, 8}, - { 26000000, 1000000000, 1000, 26, 0, 12}, - + { 12000000, 1000000000, 1000, 12, 0, 12 }, + { 13000000, 1000000000, 1000, 13, 0, 12 }, + { 19200000, 1000000000, 625, 12, 0, 8 }, + { 26000000, 1000000000, 1000, 26, 0, 12 }, /* 912 MHz */ - { 12000000, 912000000, 912, 12, 0, 12}, - { 13000000, 912000000, 912, 13, 0, 12}, - { 19200000, 912000000, 760, 16, 0, 8}, - { 26000000, 912000000, 912, 26, 0, 12}, - + { 12000000, 912000000, 912, 12, 0, 12 }, + { 13000000, 912000000, 912, 13, 0, 12 }, + { 19200000, 912000000, 760, 16, 0, 8 }, + { 26000000, 912000000, 912, 26, 0, 12 }, /* 816 MHz */ - { 12000000, 816000000, 816, 12, 0, 12}, - { 13000000, 816000000, 816, 13, 0, 12}, - { 19200000, 816000000, 680, 16, 0, 8}, - { 26000000, 816000000, 816, 26, 0, 12}, - + { 12000000, 816000000, 816, 12, 0, 12 }, + { 13000000, 816000000, 816, 13, 0, 12 }, + { 19200000, 816000000, 680, 16, 0, 8 }, + { 26000000, 816000000, 816, 26, 0, 12 }, /* 760 MHz */ - { 12000000, 760000000, 760, 12, 0, 12}, - { 13000000, 760000000, 760, 13, 0, 12}, - { 19200000, 760000000, 950, 24, 0, 8}, - { 26000000, 760000000, 760, 26, 0, 12}, - + { 12000000, 760000000, 760, 12, 0, 12 }, + { 13000000, 760000000, 760, 13, 0, 12 }, + { 19200000, 760000000, 950, 24, 0, 8 }, + { 26000000, 760000000, 760, 26, 0, 12 }, /* 750 MHz */ - { 12000000, 750000000, 750, 12, 0, 12}, - { 13000000, 750000000, 750, 13, 0, 12}, - { 19200000, 750000000, 625, 16, 0, 8}, - { 26000000, 750000000, 750, 26, 0, 12}, - + { 12000000, 750000000, 750, 12, 0, 12 }, + { 13000000, 750000000, 750, 13, 0, 12 }, + { 19200000, 750000000, 625, 16, 0, 8 }, + { 26000000, 750000000, 750, 26, 0, 12 }, /* 608 MHz */ - { 12000000, 608000000, 608, 12, 0, 12}, - { 13000000, 608000000, 608, 13, 0, 12}, - { 19200000, 608000000, 380, 12, 0, 8}, - { 26000000, 608000000, 608, 26, 0, 12}, - + { 12000000, 608000000, 608, 12, 0, 12 }, + { 13000000, 608000000, 608, 13, 0, 12 }, + { 19200000, 608000000, 380, 12, 0, 8 }, + { 26000000, 608000000, 608, 26, 0, 12 }, /* 456 MHz */ - { 12000000, 456000000, 456, 12, 0, 12}, - { 13000000, 456000000, 456, 13, 0, 12}, - { 19200000, 456000000, 380, 16, 0, 8}, - { 26000000, 456000000, 456, 26, 0, 12}, - + { 12000000, 456000000, 456, 12, 0, 12 }, + { 13000000, 456000000, 456, 13, 0, 12 }, + { 19200000, 456000000, 380, 16, 0, 8 }, + { 26000000, 456000000, 456, 26, 0, 12 }, /* 312 MHz */ - { 12000000, 312000000, 312, 12, 0, 12}, - { 13000000, 312000000, 312, 13, 0, 12}, - { 19200000, 312000000, 260, 16, 0, 8}, - { 26000000, 312000000, 312, 26, 0, 12}, - - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 312000000, 312, 12, 0, 12 }, + { 13000000, 312000000, 312, 13, 0, 12 }, + { 19200000, 312000000, 260, 16, 0, 8 }, + { 26000000, 312000000, 312, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { - { 12000000, 100000000, 200, 24, 0, 0 }, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 100000000, 200, 24, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, }; /* PLL parameters */ @@ -733,9 +722,9 @@ static void tegra20_super_clk_init(void) clks[TEGRA20_CLK_TWD] = clk; } -static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", - "pll_a_out0", "unused", "unused", - "unused"}; +static const char *audio_parents[] = { "spdif_in", "i2s1", "i2s2", "unused", + "pll_a_out0", "unused", "unused", + "unused" }; static void __init tegra20_audio_clk_init(void) { @@ -761,16 +750,16 @@ static void __init tegra20_audio_clk_init(void) clks[TEGRA20_CLK_AUDIO_2X] = clk; } -static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", - "clk_m"}; -static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", - "clk_m"}; -static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", - "clk_32k"}; -static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; -static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", - "clk_m"}; -static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; +static const char *i2s1_parents[] = { "pll_a_out0", "audio_2x", "pll_p", + "clk_m" }; +static const char *i2s2_parents[] = { "pll_a_out0", "audio_2x", "pll_p", + "clk_m" }; +static const char *pwm_parents[] = { "pll_p", "pll_c", "audio", "clk_m", + "clk_32k" }; +static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; +static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", + "clk_m" }; +static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), @@ -1024,44 +1013,45 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1}, - {TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1}, - {TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1}, - {TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1}, - {TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1}, - {TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1}, - {TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1}, - {TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1}, - {TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, - {TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1}, - {TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1}, - {TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1}, - {TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, - {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0}, - {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0}, - {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0}, - {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0}, - {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0}, - {TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1}, - {TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1}, - {TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1}, - {TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1}, - {TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, - {TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0}, - {TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0}, - {TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0}, - {TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0}, - {TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0}, - {TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0}, - {TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0}, - {TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0}, - {TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0}, - {TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0}, - {TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0}, - {TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0}, - {TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0}, - {TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry */ + { TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1 }, + { TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1 }, + { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 }, + { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 }, + { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 }, + { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1 }, + { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1 }, + { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1 }, + { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, + { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1 }, + { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 }, + { TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1 }, + { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, + { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 }, + { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 }, + { TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0 }, + { TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0 }, + { TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0 }, + { TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1 }, + { TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1 }, + { TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1 }, + { TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1 }, + { TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0 }, + { TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0 }, + { TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0 }, + { TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0 }, + { TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0 }, + { TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0 }, + { TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0 }, + { TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0 }, + { TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0 }, + { TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0 }, + { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 }, + { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 }, + { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 }, + /* must be the last entry */ + { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 }, }; static void __init tegra20_clock_apply_init_table(void) @@ -1075,11 +1065,12 @@ static void __init tegra20_clock_apply_init_table(void) * table under two names. */ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { - TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "utmip-pad", NULL), - TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-ehci.0", NULL), - TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-otg", NULL), - TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK, NULL, "cpu"), - TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL), /* Must be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "utmip-pad", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-ehci.0", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-otg", NULL), + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK, NULL, "cpu"), + /* must be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL), }; static const struct of_device_id pmc_match[] __initconst = { diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index b670e315be4d..a6f90b9e04fc 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -224,106 +224,112 @@ struct utmi_clk_param { }; static const struct utmi_clk_param utmi_parameters[] = { -/* OSC_FREQUENCY, ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT */ - {13000000, 0x02, 0x33, 0x05, 0x7F}, - {19200000, 0x03, 0x4B, 0x06, 0xBB}, - {12000000, 0x02, 0x2F, 0x04, 0x76}, - {26000000, 0x04, 0x66, 0x09, 0xFE}, - {16800000, 0x03, 0x41, 0x0A, 0xA4}, + { + .osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7f + }, { + .osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4b, .active_delay_count = 0x06, + .xtal_freq_count = 0xbb + }, { + .osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2f, .active_delay_count = 0x04, + .xtal_freq_count = 0x76 + }, { + .osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xfe + }, { + .osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0a, + .xtal_freq_count = 0xa4 + }, }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 1040000000, 520, 6, 0, 8}, - { 13000000, 1040000000, 480, 6, 0, 8}, - { 16800000, 1040000000, 495, 8, 0, 8}, /* actual: 1039.5 MHz */ - { 19200000, 1040000000, 325, 6, 0, 6}, - { 26000000, 1040000000, 520, 13, 0, 8}, - - { 12000000, 832000000, 416, 6, 0, 8}, - { 13000000, 832000000, 832, 13, 0, 8}, - { 16800000, 832000000, 396, 8, 0, 8}, /* actual: 831.6 MHz */ - { 19200000, 832000000, 260, 6, 0, 8}, - { 26000000, 832000000, 416, 13, 0, 8}, - - { 12000000, 624000000, 624, 12, 0, 8}, - { 13000000, 624000000, 624, 13, 0, 8}, - { 16800000, 600000000, 520, 14, 0, 8}, - { 19200000, 624000000, 520, 16, 0, 8}, - { 26000000, 624000000, 624, 26, 0, 8}, - - { 12000000, 600000000, 600, 12, 0, 8}, - { 13000000, 600000000, 600, 13, 0, 8}, - { 16800000, 600000000, 500, 14, 0, 8}, - { 19200000, 600000000, 375, 12, 0, 6}, - { 26000000, 600000000, 600, 26, 0, 8}, - - { 12000000, 520000000, 520, 12, 0, 8}, - { 13000000, 520000000, 520, 13, 0, 8}, - { 16800000, 520000000, 495, 16, 0, 8}, /* actual: 519.75 MHz */ - { 19200000, 520000000, 325, 12, 0, 6}, - { 26000000, 520000000, 520, 26, 0, 8}, - - { 12000000, 416000000, 416, 12, 0, 8}, - { 13000000, 416000000, 416, 13, 0, 8}, - { 16800000, 416000000, 396, 16, 0, 8}, /* actual: 415.8 MHz */ - { 19200000, 416000000, 260, 12, 0, 6}, - { 26000000, 416000000, 416, 26, 0, 8}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 1040000000, 520, 6, 0, 8 }, + { 13000000, 1040000000, 480, 6, 0, 8 }, + { 16800000, 1040000000, 495, 8, 0, 8 }, /* actual: 1039.5 MHz */ + { 19200000, 1040000000, 325, 6, 0, 6 }, + { 26000000, 1040000000, 520, 13, 0, 8 }, + { 12000000, 832000000, 416, 6, 0, 8 }, + { 13000000, 832000000, 832, 13, 0, 8 }, + { 16800000, 832000000, 396, 8, 0, 8 }, /* actual: 831.6 MHz */ + { 19200000, 832000000, 260, 6, 0, 8 }, + { 26000000, 832000000, 416, 13, 0, 8 }, + { 12000000, 624000000, 624, 12, 0, 8 }, + { 13000000, 624000000, 624, 13, 0, 8 }, + { 16800000, 600000000, 520, 14, 0, 8 }, + { 19200000, 624000000, 520, 16, 0, 8 }, + { 26000000, 624000000, 624, 26, 0, 8 }, + { 12000000, 600000000, 600, 12, 0, 8 }, + { 13000000, 600000000, 600, 13, 0, 8 }, + { 16800000, 600000000, 500, 14, 0, 8 }, + { 19200000, 600000000, 375, 12, 0, 6 }, + { 26000000, 600000000, 600, 26, 0, 8 }, + { 12000000, 520000000, 520, 12, 0, 8 }, + { 13000000, 520000000, 520, 13, 0, 8 }, + { 16800000, 520000000, 495, 16, 0, 8 }, /* actual: 519.75 MHz */ + { 19200000, 520000000, 325, 12, 0, 6 }, + { 26000000, 520000000, 520, 26, 0, 8 }, + { 12000000, 416000000, 416, 12, 0, 8 }, + { 13000000, 416000000, 416, 13, 0, 8 }, + { 16800000, 416000000, 396, 16, 0, 8 }, /* actual: 415.8 MHz */ + { 19200000, 416000000, 260, 12, 0, 6 }, + { 26000000, 416000000, 416, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 0, 8}, - { 13000000, 666000000, 666, 13, 0, 8}, - { 16800000, 666000000, 555, 14, 0, 8}, - { 19200000, 666000000, 555, 16, 0, 8}, - { 26000000, 666000000, 666, 26, 0, 8}, - { 12000000, 600000000, 600, 12, 0, 8}, - { 13000000, 600000000, 600, 13, 0, 8}, - { 16800000, 600000000, 500, 14, 0, 8}, - { 19200000, 600000000, 375, 12, 0, 6}, - { 26000000, 600000000, 600, 26, 0, 8}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 666000000, 666, 12, 0, 8 }, + { 13000000, 666000000, 666, 13, 0, 8 }, + { 16800000, 666000000, 555, 14, 0, 8 }, + { 19200000, 666000000, 555, 16, 0, 8 }, + { 26000000, 666000000, 666, 26, 0, 8 }, + { 12000000, 600000000, 600, 12, 0, 8 }, + { 13000000, 600000000, 600, 13, 0, 8 }, + { 16800000, 600000000, 500, 14, 0, 8 }, + { 19200000, 600000000, 375, 12, 0, 6 }, + { 26000000, 600000000, 600, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 1, 8}, - { 13000000, 216000000, 432, 13, 1, 8}, - { 16800000, 216000000, 360, 14, 1, 8}, - { 19200000, 216000000, 360, 16, 1, 8}, - { 26000000, 216000000, 432, 26, 1, 8}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 216000000, 432, 12, 1, 8 }, + { 13000000, 216000000, 432, 13, 1, 8 }, + { 16800000, 216000000, 360, 14, 1, 8 }, + { 19200000, 216000000, 360, 16, 1, 8 }, + { 26000000, 216000000, 432, 26, 1, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 9600000, 564480000, 294, 5, 0, 4}, - { 9600000, 552960000, 288, 5, 0, 4}, - { 9600000, 24000000, 5, 2, 0, 1}, - - { 28800000, 56448000, 49, 25, 0, 1}, - { 28800000, 73728000, 64, 25, 0, 1}, - { 28800000, 24000000, 5, 6, 0, 1}, - { 0, 0, 0, 0, 0, 0 }, + { 9600000, 564480000, 294, 5, 0, 4 }, + { 9600000, 552960000, 288, 5, 0, 4 }, + { 9600000, 24000000, 5, 2, 0, 1 }, + { 28800000, 56448000, 49, 25, 0, 1 }, + { 28800000, 73728000, 64, 25, 0, 1 }, + { 28800000, 24000000, 5, 6, 0, 1 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 0, 4}, - { 13000000, 216000000, 216, 13, 0, 4}, - { 16800000, 216000000, 180, 14, 0, 4}, - { 19200000, 216000000, 180, 16, 0, 4}, - { 26000000, 216000000, 216, 26, 0, 4}, - - { 12000000, 594000000, 594, 12, 0, 8}, - { 13000000, 594000000, 594, 13, 0, 8}, - { 16800000, 594000000, 495, 14, 0, 8}, - { 19200000, 594000000, 495, 16, 0, 8}, - { 26000000, 594000000, 594, 26, 0, 8}, - - { 12000000, 1000000000, 1000, 12, 0, 12}, - { 13000000, 1000000000, 1000, 13, 0, 12}, - { 19200000, 1000000000, 625, 12, 0, 8}, - { 26000000, 1000000000, 1000, 26, 0, 12}, - - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 216000000, 216, 12, 0, 4 }, + { 13000000, 216000000, 216, 13, 0, 4 }, + { 16800000, 216000000, 180, 14, 0, 4 }, + { 19200000, 216000000, 180, 16, 0, 4 }, + { 26000000, 216000000, 216, 26, 0, 4 }, + { 12000000, 594000000, 594, 12, 0, 8 }, + { 13000000, 594000000, 594, 13, 0, 8 }, + { 16800000, 594000000, 495, 14, 0, 8 }, + { 19200000, 594000000, 495, 16, 0, 8 }, + { 26000000, 594000000, 594, 26, 0, 8 }, + { 12000000, 1000000000, 1000, 12, 0, 12 }, + { 13000000, 1000000000, 1000, 13, 0, 12 }, + { 19200000, 1000000000, 625, 12, 0, 8 }, + { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct pdiv_map pllu_p[] = { @@ -333,79 +339,71 @@ static struct pdiv_map pllu_p[] = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 12}, - { 13000000, 480000000, 960, 13, 0, 12}, - { 16800000, 480000000, 400, 7, 0, 5}, - { 19200000, 480000000, 200, 4, 0, 3}, - { 26000000, 480000000, 960, 26, 0, 12}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 480000000, 960, 12, 0, 12 }, + { 13000000, 480000000, 960, 13, 0, 12 }, + { 16800000, 480000000, 400, 7, 0, 5 }, + { 19200000, 480000000, 200, 4, 0, 3 }, + { 26000000, 480000000, 960, 26, 0, 12 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1.7 GHz */ - { 12000000, 1700000000, 850, 6, 0, 8}, - { 13000000, 1700000000, 915, 7, 0, 8}, /* actual: 1699.2 MHz */ - { 16800000, 1700000000, 708, 7, 0, 8}, /* actual: 1699.2 MHz */ - { 19200000, 1700000000, 885, 10, 0, 8}, /* actual: 1699.2 MHz */ - { 26000000, 1700000000, 850, 13, 0, 8}, - + { 12000000, 1700000000, 850, 6, 0, 8 }, + { 13000000, 1700000000, 915, 7, 0, 8 }, /* actual: 1699.2 MHz */ + { 16800000, 1700000000, 708, 7, 0, 8 }, /* actual: 1699.2 MHz */ + { 19200000, 1700000000, 885, 10, 0, 8 }, /* actual: 1699.2 MHz */ + { 26000000, 1700000000, 850, 13, 0, 8 }, /* 1.6 GHz */ - { 12000000, 1600000000, 800, 6, 0, 8}, - { 13000000, 1600000000, 738, 6, 0, 8}, /* actual: 1599.0 MHz */ - { 16800000, 1600000000, 857, 9, 0, 8}, /* actual: 1599.7 MHz */ - { 19200000, 1600000000, 500, 6, 0, 8}, - { 26000000, 1600000000, 800, 13, 0, 8}, - + { 12000000, 1600000000, 800, 6, 0, 8 }, + { 13000000, 1600000000, 738, 6, 0, 8 }, /* actual: 1599.0 MHz */ + { 16800000, 1600000000, 857, 9, 0, 8 }, /* actual: 1599.7 MHz */ + { 19200000, 1600000000, 500, 6, 0, 8 }, + { 26000000, 1600000000, 800, 13, 0, 8 }, /* 1.5 GHz */ - { 12000000, 1500000000, 750, 6, 0, 8}, - { 13000000, 1500000000, 923, 8, 0, 8}, /* actual: 1499.8 MHz */ - { 16800000, 1500000000, 625, 7, 0, 8}, - { 19200000, 1500000000, 625, 8, 0, 8}, - { 26000000, 1500000000, 750, 13, 0, 8}, - + { 12000000, 1500000000, 750, 6, 0, 8 }, + { 13000000, 1500000000, 923, 8, 0, 8 }, /* actual: 1499.8 MHz */ + { 16800000, 1500000000, 625, 7, 0, 8 }, + { 19200000, 1500000000, 625, 8, 0, 8 }, + { 26000000, 1500000000, 750, 13, 0, 8 }, /* 1.4 GHz */ - { 12000000, 1400000000, 700, 6, 0, 8}, - { 13000000, 1400000000, 969, 9, 0, 8}, /* actual: 1399.7 MHz */ - { 16800000, 1400000000, 1000, 12, 0, 8}, - { 19200000, 1400000000, 875, 12, 0, 8}, - { 26000000, 1400000000, 700, 13, 0, 8}, - + { 12000000, 1400000000, 700, 6, 0, 8 }, + { 13000000, 1400000000, 969, 9, 0, 8 }, /* actual: 1399.7 MHz */ + { 16800000, 1400000000, 1000, 12, 0, 8 }, + { 19200000, 1400000000, 875, 12, 0, 8 }, + { 26000000, 1400000000, 700, 13, 0, 8 }, /* 1.3 GHz */ - { 12000000, 1300000000, 975, 9, 0, 8}, - { 13000000, 1300000000, 1000, 10, 0, 8}, - { 16800000, 1300000000, 928, 12, 0, 8}, /* actual: 1299.2 MHz */ - { 19200000, 1300000000, 812, 12, 0, 8}, /* actual: 1299.2 MHz */ - { 26000000, 1300000000, 650, 13, 0, 8}, - + { 12000000, 1300000000, 975, 9, 0, 8 }, + { 13000000, 1300000000, 1000, 10, 0, 8 }, + { 16800000, 1300000000, 928, 12, 0, 8 }, /* actual: 1299.2 MHz */ + { 19200000, 1300000000, 812, 12, 0, 8 }, /* actual: 1299.2 MHz */ + { 26000000, 1300000000, 650, 13, 0, 8 }, /* 1.2 GHz */ - { 12000000, 1200000000, 1000, 10, 0, 8}, - { 13000000, 1200000000, 923, 10, 0, 8}, /* actual: 1199.9 MHz */ - { 16800000, 1200000000, 1000, 14, 0, 8}, - { 19200000, 1200000000, 1000, 16, 0, 8}, - { 26000000, 1200000000, 600, 13, 0, 8}, - + { 12000000, 1200000000, 1000, 10, 0, 8 }, + { 13000000, 1200000000, 923, 10, 0, 8 }, /* actual: 1199.9 MHz */ + { 16800000, 1200000000, 1000, 14, 0, 8 }, + { 19200000, 1200000000, 1000, 16, 0, 8 }, + { 26000000, 1200000000, 600, 13, 0, 8 }, /* 1.1 GHz */ - { 12000000, 1100000000, 825, 9, 0, 8}, - { 13000000, 1100000000, 846, 10, 0, 8}, /* actual: 1099.8 MHz */ - { 16800000, 1100000000, 982, 15, 0, 8}, /* actual: 1099.8 MHz */ - { 19200000, 1100000000, 859, 15, 0, 8}, /* actual: 1099.5 MHz */ - { 26000000, 1100000000, 550, 13, 0, 8}, - + { 12000000, 1100000000, 825, 9, 0, 8 }, + { 13000000, 1100000000, 846, 10, 0, 8 }, /* actual: 1099.8 MHz */ + { 16800000, 1100000000, 982, 15, 0, 8 }, /* actual: 1099.8 MHz */ + { 19200000, 1100000000, 859, 15, 0, 8 }, /* actual: 1099.5 MHz */ + { 26000000, 1100000000, 550, 13, 0, 8 }, /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 0, 8}, - { 13000000, 1000000000, 1000, 13, 0, 8}, - { 16800000, 1000000000, 833, 14, 0, 8}, /* actual: 999.6 MHz */ - { 19200000, 1000000000, 625, 12, 0, 8}, - { 26000000, 1000000000, 1000, 26, 0, 8}, - - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 1000000000, 1000, 12, 0, 8 }, + { 13000000, 1000000000, 1000, 13, 0, 8 }, + { 16800000, 1000000000, 833, 14, 0, 8 }, /* actual: 999.6 MHz */ + { 19200000, 1000000000, 625, 12, 0, 8 }, + { 26000000, 1000000000, 1000, 26, 0, 8 }, + { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ - { 12000000, 100000000, 150, 1, 18, 11}, - { 216000000, 100000000, 200, 18, 24, 13}, - { 0, 0, 0, 0, 0, 0 }, + { 12000000, 100000000, 150, 1, 18, 11 }, + { 216000000, 100000000, 200, 18, 24, 13 }, + { 0, 0, 0, 0, 0, 0 }, }; /* PLL parameters */ @@ -576,12 +574,12 @@ static struct tegra_clk_pll_params pll_e_params = { }; static unsigned long tegra30_input_freq[] = { - [0] = 13000000, - [1] = 16800000, - [4] = 19200000, - [5] = 38400000, - [8] = 12000000, - [9] = 48000000, + [ 0] = 13000000, + [ 1] = 16800000, + [ 4] = 19200000, + [ 5] = 38400000, + [ 8] = 12000000, + [ 9] = 48000000, [12] = 26000000, }; @@ -915,7 +913,7 @@ static void tegra30_utmi_param_configure(void) writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); } -static const char *pll_e_parents[] = {"pll_ref", "pll_p"}; +static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; static void __init tegra30_pll_init(void) { @@ -1331,44 +1329,45 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { }; static struct tegra_clk_init_table init_table[] __initdata = { - {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_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1}, - {TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1}, - {TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1}, - {TEGRA30_CLK_EMC, 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}, - {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}, - {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ + { 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_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1 }, + { TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1 }, + { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 }, + { TEGRA30_CLK_EMC, 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 }, + { 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 }, + /* must be the last entry */ + { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, }; static void __init tegra30_clock_apply_init_table(void) @@ -1393,7 +1392,8 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { 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"), - TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ + /* must be the last entry */ + TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), }; static const struct of_device_id pmc_match[] __initconst = { -- cgit v1.2.3 From 385f9adf625f706ea3db80f08d723bd0dd5d1b03 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 19 Nov 2015 16:34:06 +0100 Subject: clk: tegra: Constify pdiv-to-hw mappings This is static data that is never modified, so make it const. Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 6 +++--- drivers/clk/tegra/clk-tegra114.c | 8 ++++---- drivers/clk/tegra/clk-tegra124.c | 10 +++++----- drivers/clk/tegra/clk-tegra20.c | 2 +- drivers/clk/tegra/clk-tegra30.c | 2 +- drivers/clk/tegra/clk.h | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index c72340830521..e14d3ae2d74c 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -359,7 +359,7 @@ static void clk_pll_disable(struct clk_hw *hw) static int _p_div_to_hw(struct clk_hw *hw, u8 p_div) { struct tegra_clk_pll *pll = to_clk_pll(hw); - struct pdiv_map *p_tohw = pll->params->pdiv_tohw; + const struct pdiv_map *p_tohw = pll->params->pdiv_tohw; if (p_tohw) { while (p_tohw->pdiv) { @@ -375,7 +375,7 @@ static int _p_div_to_hw(struct clk_hw *hw, u8 p_div) static int _hw_to_p_div(struct clk_hw *hw, u8 p_div_hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); - struct pdiv_map *p_tohw = pll->params->pdiv_tohw; + const struct pdiv_map *p_tohw = pll->params->pdiv_tohw; if (p_tohw) { while (p_tohw->pdiv) { @@ -1700,7 +1700,7 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, spinlock_t *lock) { struct clk *parent, *clk; - struct pdiv_map *p_tohw = pll_params->pdiv_tohw; + const struct pdiv_map *p_tohw = pll_params->pdiv_tohw; struct tegra_clk_pll *pll; struct tegra_clk_pll_freq_table cfg; unsigned long parent_rate; diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 1931f84f2a14..a373d9f7397d 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -182,7 +182,7 @@ static struct div_nmp pllxc_nmp = { .divp_width = 4, }; -static struct pdiv_map pllxc_p[] = { +static const struct pdiv_map pllxc_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 3, .hw_val = 2 }, @@ -244,7 +244,7 @@ static struct div_nmp pllcx_nmp = { .divp_width = 3, }; -static struct pdiv_map pllc_p[] = { +static const struct pdiv_map pllc_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 4, .hw_val = 3 }, @@ -318,7 +318,7 @@ static struct div_nmp pllm_nmp = { .override_divp_shift = 27, }; -static struct pdiv_map pllm_p[] = { +static const struct pdiv_map pllm_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 0, .hw_val = 0 }, @@ -472,7 +472,7 @@ static struct tegra_clk_pll_params pll_d2_params = { TEGRA_PLL_USE_LOCK, }; -static struct pdiv_map pllu_p[] = { +static const struct pdiv_map pllu_p[] = { { .pdiv = 1, .hw_val = 1 }, { .pdiv = 2, .hw_val = 0 }, { .pdiv = 0, .hw_val = 0 }, diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index d98bf688b3b0..156a753e902d 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -168,7 +168,7 @@ static struct div_nmp pllxc_nmp = { .divp_width = 4, }; -static struct pdiv_map pllxc_p[] = { +static const struct pdiv_map pllxc_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 3, .hw_val = 2 }, @@ -264,7 +264,7 @@ static struct div_nmp pllcx_nmp = { .divp_width = 3, }; -static struct pdiv_map pllc_p[] = { +static const struct pdiv_map pllc_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 3, .hw_val = 2 }, @@ -338,7 +338,7 @@ static struct div_nmp pllss_nmp = { .divp_width = 4, }; -static struct pdiv_map pll12g_ssd_esd_p[] = { +static const struct pdiv_map pll12g_ssd_esd_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 3, .hw_val = 2 }, @@ -388,7 +388,7 @@ static struct tegra_clk_pll_params pll_c4_params = { .freq_table = pll_c4_freq_table, }; -static struct pdiv_map pllm_p[] = { +static const struct pdiv_map pllm_p[] = { { .pdiv = 1, .hw_val = 0 }, { .pdiv = 2, .hw_val = 1 }, { .pdiv = 0, .hw_val = 0 }, @@ -682,7 +682,7 @@ static struct tegra_clk_pll_params pll_dp_params = { .freq_table = pll_dp_freq_table, }; -static struct pdiv_map pllu_p[] = { +static const struct pdiv_map pllu_p[] = { { .pdiv = 1, .hw_val = 1 }, { .pdiv = 2, .hw_val = 0 }, { .pdiv = 0, .hw_val = 0 }, diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 7ac9aba59f69..d7da6fd8ca30 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -359,7 +359,7 @@ static struct tegra_clk_pll_params pll_d_params = { .flags = TEGRA_PLL_HAS_CPCON, }; -static struct pdiv_map pllu_p[] = { +static const struct pdiv_map pllu_p[] = { { .pdiv = 1, .hw_val = 1 }, { .pdiv = 2, .hw_val = 0 }, { .pdiv = 0, .hw_val = 0 }, diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index a6f90b9e04fc..019a7fc5512d 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -332,7 +332,7 @@ static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { { 0, 0, 0, 0, 0, 0 }, }; -static struct pdiv_map pllu_p[] = { +static const struct pdiv_map pllu_p[] = { { .pdiv = 1, .hw_val = 1 }, { .pdiv = 2, .hw_val = 0 }, { .pdiv = 0, .hw_val = 0 }, diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 5d2678914160..bdaec2b01295 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -233,7 +233,7 @@ struct tegra_clk_pll_params { int stepb_shift; int lock_delay; int max_p; - struct pdiv_map *pdiv_tohw; + const struct pdiv_map *pdiv_tohw; struct div_nmp *div_nmp; struct tegra_clk_pll_freq_table *freq_table; unsigned long fixed_rate; -- cgit v1.2.3 From dc37fec48314d942003a414a4bab38f4688f09a3 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:18 -0400 Subject: clk: tegra: periph: Add new periph clks and muxes for Tegra210 Tegra210 has significant differences in muxes for peripheral clocks. One of the most important changes is that pll_m isn't to be used as a source for peripherals. Therefore, we need to define the new muxes and new clocks to use those muxes for Tegra210 support. Tegra210 has some differences in the PLLP clock tree: - Four new output clocks: PLLP_OUT_CPU, PLLP_OUT_ADSP, PLLP_OUT_HSIO, and PLLP_OUT_XUSB. - PLLP_OUT2 is fixed at 1/2 the rate of PLLP_VCO. - PLLP_OUT4 is the child of PLLP_OUT_CPU. Update the xusb_hs_src mux and add the xusb_ssp_src mux for Tegra210. Including work by Andrew Bresticker and Bill Huang . Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-id.h | 68 ++++++- drivers/clk/tegra/clk-tegra-periph.c | 371 ++++++++++++++++++++++++++++++++++- 2 files changed, 434 insertions(+), 5 deletions(-) diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index 60738cc954cb..e0ea78792983 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -13,6 +13,7 @@ enum clk_id { tegra_clk_amx1, tegra_clk_apbdma, tegra_clk_apbif, + tegra_clk_ape, tegra_clk_audio0, tegra_clk_audio0_2x, tegra_clk_audio0_mux, @@ -38,6 +39,7 @@ enum clk_id { tegra_clk_cile, tegra_clk_clk_32k, tegra_clk_clk72Mhz, + tegra_clk_clk72Mhz_8, tegra_clk_clk_m, tegra_clk_clk_m_div2, tegra_clk_clk_m_div4, @@ -51,17 +53,21 @@ enum clk_id { tegra_clk_cml1, tegra_clk_csi, tegra_clk_csite, + tegra_clk_csite_8, tegra_clk_csus, tegra_clk_cve, tegra_clk_dam0, tegra_clk_dam1, tegra_clk_dam2, tegra_clk_d_audio, + tegra_clk_dbgapb, tegra_clk_dds, tegra_clk_dfll_ref, tegra_clk_dfll_soc, tegra_clk_disp1, + tegra_clk_disp1_8, tegra_clk_disp2, + tegra_clk_disp2_8, tegra_clk_dp2, tegra_clk_dpaux, tegra_clk_dsialp, @@ -71,6 +77,7 @@ enum clk_id { tegra_clk_dtv, tegra_clk_emc, tegra_clk_entropy, + tegra_clk_entropy_8, tegra_clk_epp, tegra_clk_epp_8, tegra_clk_extern1, @@ -85,12 +92,16 @@ enum clk_id { tegra_clk_gr3d_8, tegra_clk_hclk, tegra_clk_hda, + tegra_clk_hda_8, tegra_clk_hda2codec_2x, + tegra_clk_hda2codec_2x_8, tegra_clk_hda2hdmi, tegra_clk_hdmi, tegra_clk_hdmi_audio, tegra_clk_host1x, tegra_clk_host1x_8, + tegra_clk_host1x_9, + tegra_clk_hsic_trk, tegra_clk_i2c1, tegra_clk_i2c2, tegra_clk_i2c3, @@ -110,11 +121,14 @@ enum clk_id { tegra_clk_i2s4_sync, tegra_clk_isp, tegra_clk_isp_8, + tegra_clk_isp_9, tegra_clk_ispb, tegra_clk_kbc, tegra_clk_kfuse, tegra_clk_la, + tegra_clk_maud, tegra_clk_mipi, + tegra_clk_mipibif, tegra_clk_mipi_cal, tegra_clk_mpe, tegra_clk_mselect, @@ -124,11 +138,16 @@ enum clk_id { tegra_clk_ndspeed, tegra_clk_ndspeed_8, tegra_clk_nor, + tegra_clk_nvdec, + tegra_clk_nvenc, + tegra_clk_nvjpg, tegra_clk_owr, + tegra_clk_owr_8, tegra_clk_pcie, tegra_clk_pclk, tegra_clk_pll_a, tegra_clk_pll_a_out0, + tegra_clk_pll_a1, tegra_clk_pll_c, tegra_clk_pll_c2, tegra_clk_pll_c3, @@ -140,15 +159,22 @@ enum clk_id { tegra_clk_pll_d_out0, tegra_clk_pll_dp, tegra_clk_pll_e_out0, + tegra_clk_pll_g_ref, tegra_clk_pll_m, tegra_clk_pll_m_out1, + tegra_clk_pll_mb, tegra_clk_pll_p, tegra_clk_pll_p_out1, tegra_clk_pll_p_out2, tegra_clk_pll_p_out2_int, tegra_clk_pll_p_out3, tegra_clk_pll_p_out4, + tegra_clk_pll_p_out4_cpu, tegra_clk_pll_p_out5, + tegra_clk_pll_p_out_hsio, + tegra_clk_pll_p_out_xusb, + tegra_clk_pll_p_out_cpu, + tegra_clk_pll_p_out_adsp, tegra_clk_pll_ref, tegra_clk_pll_re_out, tegra_clk_pll_re_vco, @@ -160,53 +186,80 @@ enum clk_id { tegra_clk_pll_x, tegra_clk_pll_x_out0, tegra_clk_pwm, + tegra_clk_qspi, tegra_clk_rtc, tegra_clk_sata, + tegra_clk_sata_8, tegra_clk_sata_cold, tegra_clk_sata_oob, + tegra_clk_sata_oob_8, tegra_clk_sbc1, tegra_clk_sbc1_8, + tegra_clk_sbc1_9, tegra_clk_sbc2, tegra_clk_sbc2_8, + tegra_clk_sbc2_9, tegra_clk_sbc3, tegra_clk_sbc3_8, + tegra_clk_sbc3_9, tegra_clk_sbc4, tegra_clk_sbc4_8, + tegra_clk_sbc4_9, tegra_clk_sbc5, tegra_clk_sbc5_8, tegra_clk_sbc6, tegra_clk_sbc6_8, tegra_clk_sclk, + tegra_clk_sdmmc_legacy, tegra_clk_sdmmc1, tegra_clk_sdmmc1_8, + tegra_clk_sdmmc1_9, tegra_clk_sdmmc2, tegra_clk_sdmmc2_8, + tegra_clk_sdmmc2_9, tegra_clk_sdmmc3, tegra_clk_sdmmc3_8, + tegra_clk_sdmmc3_9, tegra_clk_sdmmc4, tegra_clk_sdmmc4_8, + tegra_clk_sdmmc4_9, tegra_clk_se, tegra_clk_soc_therm, + tegra_clk_soc_therm_8, tegra_clk_sor0, tegra_clk_sor0_lvds, + tegra_clk_sor1, + tegra_clk_sor1_brick, + tegra_clk_sor1_src, tegra_clk_spdif, tegra_clk_spdif_2x, tegra_clk_spdif_in, + tegra_clk_spdif_in_8, tegra_clk_spdif_in_sync, tegra_clk_spdif_mux, tegra_clk_spdif_out, tegra_clk_timer, tegra_clk_trace, tegra_clk_tsec, + tegra_clk_tsec_8, + tegra_clk_tsecb, tegra_clk_tsensor, tegra_clk_tvdac, tegra_clk_tvo, tegra_clk_uarta, + tegra_clk_uarta_8, tegra_clk_uartb, + tegra_clk_uartb_8, tegra_clk_uartc, + tegra_clk_uartc_8, tegra_clk_uartd, + tegra_clk_uartd_8, tegra_clk_uarte, + tegra_clk_uarte_8, + tegra_clk_uartape, tegra_clk_usb2, + tegra_clk_usb2_hsic_trk, + tegra_clk_usb2_trk, tegra_clk_usb3, tegra_clk_usbd, tegra_clk_vcp, @@ -216,22 +269,35 @@ enum clk_id { tegra_clk_vi, tegra_clk_vi_8, tegra_clk_vi_9, + tegra_clk_vi_10, + tegra_clk_vi_i2c, tegra_clk_vic03, + tegra_clk_vic03_8, tegra_clk_vim2_clk, tegra_clk_vimclk_sync, tegra_clk_vi_sensor, - tegra_clk_vi_sensor2, tegra_clk_vi_sensor_8, + tegra_clk_vi_sensor_9, + tegra_clk_vi_sensor2, + tegra_clk_vi_sensor2_8, tegra_clk_xusb_dev, tegra_clk_xusb_dev_src, + tegra_clk_xusb_dev_src_8, tegra_clk_xusb_falcon_src, + tegra_clk_xusb_falcon_src_8, tegra_clk_xusb_fs_src, + tegra_clk_xusb_gate, tegra_clk_xusb_host, tegra_clk_xusb_host_src, + tegra_clk_xusb_host_src_8, tegra_clk_xusb_hs_src, + tegra_clk_xusb_hs_src_4, tegra_clk_xusb_ss, tegra_clk_xusb_ss_src, + tegra_clk_xusb_ss_src_8, tegra_clk_xusb_ss_div2, + tegra_clk_xusb_ssp_src, + tegra_clk_sclk_mux, tegra_clk_max, }; diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index cb6ab830941d..6ad381a888a6 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -124,6 +124,20 @@ #define CLK_SOURCE_HDMI_AUDIO 0x668 #define CLK_SOURCE_VIC03 0x678 #define CLK_SOURCE_CLK72MHZ 0x66c +#define CLK_SOURCE_DBGAPB 0x718 +#define CLK_SOURCE_NVENC 0x6a0 +#define CLK_SOURCE_NVDEC 0x698 +#define CLK_SOURCE_NVJPG 0x69c +#define CLK_SOURCE_APE 0x6c0 +#define CLK_SOURCE_SOR1 0x410 +#define CLK_SOURCE_SDMMC_LEGACY 0x694 +#define CLK_SOURCE_QSPI 0x6c4 +#define CLK_SOURCE_VI_I2C 0x6c8 +#define CLK_SOURCE_MIPIBIF 0x660 +#define CLK_SOURCE_UARTAPE 0x710 +#define CLK_SOURCE_TSECB 0x6d8 +#define CLK_SOURCE_MAUD 0x6d4 +#define CLK_SOURCE_USB2_HSIC_TRK 0x6cc #define MASK(x) (BIT(x) - 1) @@ -182,6 +196,13 @@ TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ _parents##_idx, 0, NULL) +#define UART8(_name, _parents, _offset,\ + _clk_num, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + 29, MASK(3), 0, 0, 16, 1, TEGRA_DIVIDER_UART| \ + TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ + _parents##_idx, 0, NULL) + #define I2C(_name, _parents, _offset,\ _clk_num, _clk_id) \ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ @@ -221,8 +242,21 @@ .flags = _flags \ } +#define DIV8(_name, _parent_name, _offset, _clk_id, _flags) \ + { \ + .name = _name, \ + .clk_id = _clk_id, \ + .p.parent_name = _parent_name, \ + .periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 8, 1, \ + TEGRA_DIVIDER_ROUND_UP, 0, 0, \ + NULL, NULL), \ + .offset = _offset, \ + .flags = _flags, \ + } + #define PLLP_BASE 0xa0 #define PLLP_MISC 0xac +#define PLLP_MISC1 0x680 #define PLLP_OUTA 0xa4 #define PLLP_OUTB 0xa8 #define PLLP_OUTC 0x67c @@ -234,6 +268,7 @@ static DEFINE_SPINLOCK(PLLP_OUTA_lock); static DEFINE_SPINLOCK(PLLP_OUTB_lock); static DEFINE_SPINLOCK(PLLP_OUTC_lock); static DEFINE_SPINLOCK(sor0_lock); +static DEFINE_SPINLOCK(sor1_lock); #define MUX_I2S_SPDIF(_id) \ static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ @@ -285,6 +320,68 @@ static u32 mux_pllp_clkm_idx[] = { [0] = 0, [1] = 3, }; +static const char *mux_pllp_clkm_2[] = { + "pll_p", "clk_m" +}; +static u32 mux_pllp_clkm_2_idx[] = { + [0] = 2, [1] = 6, +}; + +static const char *mux_pllc2_c_c3_pllp_plla1_clkm[] = { + "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a1", "clk_m" +}; +static u32 mux_pllc2_c_c3_pllp_plla1_clkm_idx[] = { + [0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 6, [5] = 7, +}; + +static const char * +mux_pllc4_out1_pllc_pllc4_out2_pllp_clkm_plla_pllc4_out0[] = { + "pll_c4_out1", "pll_c", "pll_c4_out2", "pll_p", "clk_m", + "pll_a_out0", "pll_c4_out0" +}; +static u32 mux_pllc4_out1_pllc_pllc4_out2_pllp_clkm_plla_pllc4_out0_idx[] = { + [0] = 0, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = 6, [6] = 7, +}; + +static const char *mux_pllc_pllp_plla[] = { + "pll_c", "pll_p", "pll_a_out0" +}; +static u32 mux_pllc_pllp_plla_idx[] = { + [0] = 1, [1] = 2, [2] = 3, +}; + +static const char *mux_clkm_pllc_pllp_plla[] = { + "clk_m", "pll_c", "pll_p", "pll_a_out0" +}; +#define mux_clkm_pllc_pllp_plla_idx NULL + +static const char *mux_pllc_pllp_plla1_pllc2_c3_clkm[] = { + "pll_c", "pll_p", "pll_a1", "pll_c2", "pll_c3", "clk_m" +}; +static u32 mux_pllc_pllp_plla1_pllc2_c3_clkm_idx[] = { + [0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = 6, +}; + +static const char *mux_pllc2_c_c3_pllp_clkm_plla1_pllc4[] = { + "pll_c2", "pll_c", "pll_c3", "pll_p", "clk_m", "pll_a1", "pll_c4_out0", +}; +static u32 mux_pllc2_c_c3_pllp_clkm_plla1_pllc4_idx[] = { + [0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5, [5] = 6, [6] = 7, +}; + +static const char *mux_pllc_pllp_plla1_pllc2_c3_clkm_pllc4[] = { + "pll_c", "pll_p", "pll_a1", "pll_c2", "pll_c3", "clk_m", "pll_c4_out0", +}; +#define mux_pllc_pllp_plla1_pllc2_c3_clkm_pllc4_idx \ + mux_pllc2_c_c3_pllp_clkm_plla1_pllc4_idx + +static const char * +mux_plla_pllc4_out0_pllc_pllc4_out1_pllp_pllc4_out2_clkm[] = { + "pll_a_out0", "pll_c4_out0", "pll_c", "pll_c4_out1", "pll_p", + "pll_c4_out2", "clk_m" +}; +#define mux_plla_pllc4_out0_pllc_pllc4_out1_pllp_pllc4_out2_clkm_idx NULL + static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" }; @@ -302,12 +399,93 @@ static const char *mux_pllm_pllc_pllp_plla[] = { #define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx static const char *mux_pllp_pllc_clkm[] = { - "pll_p", "pll_c", "pll_m" + "pll_p", "pll_c", "clk_m" }; static u32 mux_pllp_pllc_clkm_idx[] = { [0] = 0, [1] = 1, [2] = 3, }; +static const char *mux_pllp_pllc_clkm_1[] = { + "pll_p", "pll_c", "clk_m" +}; +static u32 mux_pllp_pllc_clkm_1_idx[] = { + [0] = 0, [1] = 2, [2] = 5, +}; + +static const char *mux_pllp_pllc_plla_clkm[] = { + "pll_p", "pll_c", "pll_a_out0", "clk_m" +}; +static u32 mux_pllp_pllc_plla_clkm_idx[] = { + [0] = 0, [1] = 2, [2] = 4, [3] = 6, +}; + +static const char *mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2[] = { + "pll_p", "pll_c", "pll_c4_out0", "pll_c4_out1", "clk_m", "pll_c4_out2" +}; +static u32 mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2_idx[] = { + [0] = 0, [1] = 2, [2] = 3, [3] = 5, [4] = 6, [5] = 7, +}; + +static const char * +mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0[] = { + "pll_p", "pll_c_out1", "pll_c", "pll_c4_out2", "pll_c4_out1", + "clk_m", "pll_c4_out0" +}; +static u32 +mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 4, [4] = 5, [5] = 6, [6] = 7, +}; + +static const char *mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0[] = { + "pll_p", "pll_c4_out2", "pll_c4_out1", "clk_m", "pll_c4_out0" +}; +static u32 mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0_idx[] = { + [0] = 0, [1] = 3, [2] = 4, [3] = 6, [4] = 7, +}; + +static const char *mux_pllp_clkm_pllc4_out2_out1_out0_lj[] = { + "pll_p", + "pll_c4_out2", "pll_c4_out0", /* LJ input */ + "pll_c4_out2", "pll_c4_out1", + "pll_c4_out1", /* LJ input */ + "clk_m", "pll_c4_out0" +}; +#define mux_pllp_clkm_pllc4_out2_out1_out0_lj_idx NULL + +static const char *mux_pllp_pllc2_c_c3_clkm[] = { + "pll_p", "pll_c2", "pll_c", "pll_c3", "clk_m" +}; +static u32 mux_pllp_pllc2_c_c3_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 6, +}; + +static const char *mux_pllp_clkm_clk32_plle[] = { + "pll_p", "clk_m", "clk_32k", "pll_e" +}; +static u32 mux_pllp_clkm_clk32_plle_idx[] = { + [0] = 0, [1] = 2, [2] = 4, [3] = 6, +}; + +static const char *mux_pllp_pllp_out3_clkm_clk32k_plla[] = { + "pll_p", "pll_p_out3", "clk_m", "clk_32k", "pll_a_out0" +}; +#define mux_pllp_pllp_out3_clkm_clk32k_plla_idx NULL + +static const char *mux_pllp_out3_clkm_pllp_pllc4[] = { + "pll_p_out3", "clk_m", "pll_p", "pll_c4_out0", "pll_c4_out1", + "pll_c4_out2" +}; +static u32 mux_pllp_out3_clkm_pllp_pllc4_idx[] = { + [0] = 0, [1] = 3, [2] = 4, [3] = 5, [4] = 6, [5] = 7, +}; + +static const char *mux_clkm_pllp_pllre[] = { + "clk_m", "pll_p_out_xusb", "pll_re_out" +}; +static u32 mux_clkm_pllp_pllre_idx[] = { + [0] = 0, [1] = 1, [2] = 5, +}; + static const char *mux_pllp_pllc_clkm_clk32[] = { "pll_p", "pll_c", "clk_m", "clk_32k" }; @@ -332,6 +510,11 @@ static u32 mux_clkm_48M_pllp_480M_idx[] = { [0] = 0, [1] = 2, [2] = 4, [3] = 6, }; +static const char *mux_clkm_pllre_clk32_480M[] = { + "clk_m", "pll_re_out", "clk_32k", "pll_u_480M" +}; +#define mux_clkm_pllre_clk32_480M_idx NULL + static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" }; @@ -339,10 +522,27 @@ static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, }; -static const char *mux_ss_60M[] = { +static const char *mux_pllp_out3_pllp_pllc_clkm[] = { + "pll_p_out3", "pll_p", "pll_c", "clk_m" +}; +static u32 mux_pllp_out3_pllp_pllc_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 6, +}; + +static const char *mux_ss_div2_60M[] = { "xusb_ss_div2", "pll_u_60M" }; -#define mux_ss_60M_idx NULL +#define mux_ss_div2_60M_idx NULL + +static const char *mux_ss_div2_60M_ss[] = { + "xusb_ss_div2", "pll_u_60M", "xusb_ss_src" +}; +#define mux_ss_div2_60M_ss_idx NULL + +static const char *mux_ss_clkm[] = { + "xusb_ss_src", "clk_m" +}; +#define mux_ss_clkm_idx NULL static const char *mux_d_audio_clk[] = { "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", @@ -386,6 +586,32 @@ static u32 mux_pllm_pllc2_c_c3_pllp_plla_pllc4_idx[] = { [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, [6] = 7, }; +/* SOR1 mux'es */ +static const char *mux_pllp_plld_plld2_clkm[] = { + "pll_p", "pll_d_out0", "pll_d2_out0", "clk_m" +}; +static u32 mux_pllp_plld_plld2_clkm_idx[] = { + [0] = 0, [1] = 2, [2] = 5, [3] = 6 +}; + +static const char *mux_plldp_sor1_src[] = { + "pll_dp", "clk_sor1_src" +}; +#define mux_plldp_sor1_src_idx NULL + +static const char *mux_clkm_sor1_brick_sor1_src[] = { + "clk_m", "sor1_brick", "sor1_src", "sor1_brick" +}; +#define mux_clkm_sor1_brick_sor1_src_idx NULL + +static const char *mux_pllp_pllre_clkm[] = { + "pll_p", "pll_re_out1", "clk_m" +}; + +static u32 mux_pllp_pllre_clkm_idx[] = { + [0] = 0, [1] = 2, [2] = 3, +}; + static const char *mux_clkm_plldp_sor0lvds[] = { "clk_m", "pll_dp", "sor0_lvds", }; @@ -401,6 +627,7 @@ static struct tegra_periph_init_data periph_clks[] = { I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, tegra_clk_i2c3), I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, tegra_clk_i2c4), I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, tegra_clk_i2c5), + I2C("i2c6", mux_pllp_clkm, CLK_SOURCE_I2C6, 166, tegra_clk_i2c6), INT("vde", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde), INT("vi", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi), INT("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp), @@ -411,14 +638,19 @@ static struct tegra_periph_init_data periph_clks[] = { INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8), INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8), INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9), + INT8("vi", mux_pllc2_c_c3_pllp_clkm_plla1_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_10), INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp_8), INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, tegra_clk_msenc), INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec), + INT("tsec", mux_pllp_pllc_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec_8), INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), + INT8("host1x", mux_pllc4_out1_pllc_pllc4_out2_pllp_clkm_plla_pllc4_out0, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_9), INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), + INT8("se", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03), + INT8("vic03", mux_pllc_pllp_plla1_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03_8), INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, tegra_clk_mselect, CLK_IGNORE_UNUSED), MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, tegra_clk_i2s0), MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, tegra_clk_i2s1), @@ -427,22 +659,31 @@ static struct tegra_periph_init_data periph_clks[] = { MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, tegra_clk_i2s4), MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_out), MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_in), + MUX8("spdif_in", mux_pllp_pllc_clkm_1, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_in_8), MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, tegra_clk_pwm), MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, tegra_clk_adx), MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, tegra_clk_amx), MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda), + MUX("hda", mux_pllp_pllc_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda_8), MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x), + MUX8("hda2codec_2x", mux_pllp_pllc_plla_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x_8), MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, tegra_clk_vfir), MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1), MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2), MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3), MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4), + MUX8("sdmmc1", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_9), + MUX8("sdmmc2", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2_9), + MUX8("sdmmc3", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_9), + MUX8("sdmmc4", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4_9), MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), + MUX("owr", mux_pllp_pllc_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr_8), MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, tegra_clk_nor), MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, tegra_clk_mipi), MUX("vi_sensor", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor), + MUX("vi_sensor", mux_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_9), MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, tegra_clk_cilab), MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, tegra_clk_cilcd), MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, tegra_clk_cile), @@ -465,10 +706,13 @@ static struct tegra_periph_init_data periph_clks[] = { MUX("ndflash", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash), MUX("ndspeed", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed), MUX("sata_oob", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob), + MUX("sata_oob", mux_pllp_pllc_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob_8), MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata), + MUX("sata", mux_pllp_pllc_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata_8), MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 165, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), + MUX("vi_sensor2", mux_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR2, 165, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2_8), MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_8), MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2_8), MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_8), @@ -479,6 +723,10 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4_8), MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5_8), MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6_8), + MUX("sbc1", mux_pllp_pllc_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_9), + MUX("sbc2", mux_pllp_pllc_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_9), + MUX("sbc3", mux_pllp_pllc_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_9), + MUX("sbc4", mux_pllp_pllc_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4_9), MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), @@ -486,27 +734,59 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), + MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), MUX8("isp", mux_pllm_pllc_pllp_plla_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_8), + MUX8("isp", mux_pllc_pllp_plla1_pllc2_c3_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_9), MUX8("entropy", mux_pllp_clkm1, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy), + MUX8("entropy", mux_pllp_clkm_clk32_plle, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy_8), MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), + MUX8("clk72mhz", mux_pllp_out3_pllp_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz_8), MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), + MUX_FLAGS("csite", mux_pllp_pllre_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite_8, CLK_IGNORE_UNUSED), NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), + NODIV("disp1", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1_8, NULL), NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), + NODIV("disp2", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2_8, NULL), NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 66, tegra_clk_uarte), + UART8("uarta", mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2, CLK_SOURCE_UARTA, 6, tegra_clk_uarta_8), + UART8("uartb", mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2, CLK_SOURCE_UARTB, 7, tegra_clk_uartb_8), + UART8("uartc", mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2, CLK_SOURCE_UARTC, 55, tegra_clk_uartc_8), + UART8("uartd", mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2, CLK_SOURCE_UARTD, 65, tegra_clk_uartd_8), XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), + XUSB("xusb_host_src", mux_clkm_pllp_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src_8), XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), + XUSB("xusb_falcon_src", mux_clkm_pllp_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src_8), XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src), - NODIV("xusb_hs_src", mux_ss_60M, CLK_SOURCE_XUSB_SS_SRC, 25, MASK(1), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_hs_src, NULL), + XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src_8), + NODIV("xusb_hs_src", mux_ss_div2_60M, CLK_SOURCE_XUSB_SS_SRC, 25, MASK(1), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_hs_src, NULL), + NODIV("xusb_hs_src", mux_ss_div2_60M_ss, CLK_SOURCE_XUSB_SS_SRC, 25, MASK(2), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_hs_src_4, NULL), + NODIV("xusb_ssp_src", mux_ss_clkm, CLK_SOURCE_XUSB_SS_SRC, 24, MASK(1), 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ssp_src, NULL), XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), + XUSB("xusb_dev_src", mux_clkm_pllp_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src_8), + MUX8("dbgapb", mux_pllp_clkm_2, CLK_SOURCE_DBGAPB, 185, TEGRA_PERIPH_NO_RESET, tegra_clk_dbgapb), + MUX8("msenc", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVENC, 219, 0, tegra_clk_nvenc), + MUX8("nvdec", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVDEC, 194, 0, tegra_clk_nvdec), + MUX8("nvjpg", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVJPG, 195, 0, tegra_clk_nvjpg), + MUX8("ape", mux_plla_pllc4_out0_pllc_pllc4_out1_pllp_pllc4_out2_clkm, CLK_SOURCE_APE, 198, TEGRA_PERIPH_ON_APB, tegra_clk_ape), + MUX8_NOGATE_LOCK("sor1_src", mux_pllp_plld_plld2_clkm, CLK_SOURCE_SOR1, tegra_clk_sor1_src, &sor1_lock), + NODIV("sor1_brick", mux_plldp_sor1_src, CLK_SOURCE_SOR1, 14, MASK(1), 183, 0, tegra_clk_sor1_brick, &sor1_lock), + NODIV("sor1", mux_clkm_sor1_brick_sor1_src, CLK_SOURCE_SOR1, 15, MASK(1), 183, 0, tegra_clk_sor1, &sor1_lock), + MUX8("sdmmc_legacy", mux_pllp_out3_clkm_pllp_pllc4, CLK_SOURCE_SDMMC_LEGACY, 193, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_sdmmc_legacy), + MUX8("qspi", mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_QSPI, 211, TEGRA_PERIPH_ON_APB, tegra_clk_qspi), + MUX("vii2c", mux_pllp_pllc_clkm, CLK_SOURCE_VI_I2C, 208, TEGRA_PERIPH_ON_APB, tegra_clk_vi_i2c), + MUX("mipibif", mux_pllp_clkm, CLK_SOURCE_MIPIBIF, 173, TEGRA_PERIPH_ON_APB, tegra_clk_mipibif), + MUX("uartape", mux_pllp_pllc_clkm, CLK_SOURCE_UARTAPE, 212, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_uartape), + MUX8("tsecb", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_TSECB, 206, 0, tegra_clk_tsecb), + MUX8("maud", mux_pllp_pllp_out3_clkm_clk32k_plla, CLK_SOURCE_MAUD, 202, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_maud), }; static struct tegra_periph_init_data gate_clks[] = { @@ -543,6 +823,16 @@ static struct tegra_periph_init_data gate_clks[] = { GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), + GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0), + GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0), + GATE("usb2_trk", "usb2_hsic_trk", 210, TEGRA_PERIPH_NO_RESET, tegra_clk_usb2_trk, 0), + GATE("xusb_gate", "osc", 143, 0, tegra_clk_xusb_gate, 0), + GATE("pll_p_out_cpu", "pll_p", 223, 0, tegra_clk_pll_p_out_cpu, 0), + GATE("pll_p_out_adsp", "pll_p", 187, 0, tegra_clk_pll_p_out_adsp, 0), +}; + +static struct tegra_periph_init_data div_clks[] = { + DIV8("usb2_hsic_trk", "osc", CLK_SOURCE_USB2_HSIC_TRK, tegra_clk_usb2_hsic_trk, 0), }; struct pll_out_data { @@ -633,6 +923,33 @@ static void __init gate_clk_init(void __iomem *clk_base, } } +static void __init div_clk_init(void __iomem *clk_base, + struct tegra_clk *tegra_clks) +{ + int i; + struct clk *clk; + struct clk **dt_clk; + + for (i = 0; i < ARRAY_SIZE(div_clks); i++) { + struct tegra_periph_init_data *data; + + data = div_clks + i; + + dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); + if (!dt_clk) + continue; + + clk = tegra_clk_register_divider(data->name, + data->p.parent_name, clk_base + data->offset, + data->flags, data->periph.divider.flags, + data->periph.divider.shift, + data->periph.divider.width, + data->periph.divider.frac_width, + data->periph.divider.lock); + *dt_clk = clk; + } +} + static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *pll_params) @@ -669,6 +986,51 @@ static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base, data->lock); *dt_clk = clk; } + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p_out_cpu, + tegra_clks); + if (dt_clk) { + /* + * Tegra210 has control on enabling/disabling PLLP branches to + * CPU, register a gate clock "pll_p_out_cpu" for this gating + * function and parent "pll_p_out4" to it, so when we are + * re-parenting CPU off from "pll_p_out4" the PLLP branching to + * CPU can be disabled automatically. + */ + clk = tegra_clk_register_divider("pll_p_out4_div", + "pll_p_out_cpu", clk_base + PLLP_OUTB, 0, 0, 24, + 8, 1, &PLLP_OUTB_lock); + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p_out4_cpu, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_pll_out("pll_p_out4", + "pll_p_out4_div", clk_base + PLLP_OUTB, + 17, 16, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, + &PLLP_OUTB_lock); + *dt_clk = clk; + } + } + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p_out_hsio, tegra_clks); + if (dt_clk) { + /* PLLP_OUT_HSIO */ + clk = clk_register_gate(NULL, "pll_p_out_hsio", "pll_p", + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + clk_base + PLLP_MISC1, 29, 0, NULL); + *dt_clk = clk; + } + + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p_out_xusb, tegra_clks); + if (dt_clk) { + /* PLLP_OUT_XUSB */ + clk = clk_register_gate(NULL, "pll_p_out_xusb", + "pll_p_out_hsio", CLK_SET_RATE_PARENT | + CLK_IGNORE_UNUSED, clk_base + PLLP_MISC1, 28, 0, + NULL); + clk_register_clkdev(clk, "pll_p_out_xusb", NULL); + *dt_clk = clk; + } } void __init tegra_periph_clk_init(void __iomem *clk_base, @@ -678,4 +1040,5 @@ void __init tegra_periph_clk_init(void __iomem *clk_base, init_pllp(clk_base, pmc_base, tegra_clks, pll_params); periph_clk_init(clk_base, tegra_clks); gate_clk_init(clk_base, tegra_clks); + div_clk_init(clk_base, tegra_clks); } -- cgit v1.2.3 From 6583a6309e83e89f00e104c4ffd9df01d2e5a9f8 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:19 -0400 Subject: clk: tegra: pll: Add tegra_pll_wait_for_lock to clk header Create a wrapper interface to make use of the existing clk_pll_wait_for_lock. This will be useful for implementations of callbacks in Tegra SoC specific clock drivers. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 5 +++++ drivers/clk/tegra/clk.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index e14d3ae2d74c..d53b226c0277 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -269,6 +269,11 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) return -1; } +int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll) +{ + return clk_pll_wait_for_lock(pll); +} + static int clk_pll_is_enabled(struct clk_hw *hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index bdaec2b01295..ced19e7c68d2 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -674,5 +674,6 @@ void tegra114_clock_deassert_dfll_dvco_reset(void); typedef void (*tegra_clk_apply_init_table_func)(void); extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; +int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); #endif /* TEGRA_CLK_H */ -- cgit v1.2.3 From 7db864c9deb28b1352fdf8d2b72cd54c78ed7d9c Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:20 -0400 Subject: clk: tegra: pll: Simplify clk_enable_path Instead of having multiple similar wrapper functions for _clk_pll_[enable|disable], we can simplify it to single wrappers and use checks to avoid the logic we don't want to use. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 76 +++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index d53b226c0277..6c29ad7e15e7 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -295,6 +295,13 @@ static void _clk_pll_enable(struct clk_hw *hw) struct tegra_clk_pll *pll = to_clk_pll(hw); u32 val; + if (pll->params->iddq_reg) { + val = pll_readl(pll->params->iddq_reg, pll); + val &= ~BIT(pll->params->iddq_bit_idx); + pll_writel(val, pll->params->iddq_reg, pll); + udelay(2); + } + clk_pll_enable_lock(pll); val = pll_readl_base(pll); @@ -326,6 +333,13 @@ static void _clk_pll_disable(struct clk_hw *hw) val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); } + + if (pll->params->iddq_reg) { + val = pll_readl(pll->params->iddq_reg, pll); + val |= BIT(pll->params->iddq_bit_idx); + pll_writel(val, pll->params->iddq_reg, pll); + udelay(2); + } } static int clk_pll_enable(struct clk_hw *hw) @@ -876,52 +890,6 @@ static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, return 0; } -static int clk_pll_iddq_enable(struct clk_hw *hw) -{ - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long flags = 0; - - u32 val; - int ret; - - if (pll->lock) - spin_lock_irqsave(pll->lock, flags); - - val = pll_readl(pll->params->iddq_reg, pll); - val &= ~BIT(pll->params->iddq_bit_idx); - pll_writel(val, pll->params->iddq_reg, pll); - udelay(2); - - _clk_pll_enable(hw); - - ret = clk_pll_wait_for_lock(pll); - - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); - - return 0; -} - -static void clk_pll_iddq_disable(struct clk_hw *hw) -{ - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long flags = 0; - u32 val; - - if (pll->lock) - spin_lock_irqsave(pll->lock, flags); - - _clk_pll_disable(hw); - - val = pll_readl(pll->params->iddq_reg, pll); - val |= BIT(pll->params->iddq_bit_idx); - pll_writel(val, pll->params->iddq_reg, pll); - udelay(2); - - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); -} - static int _calc_dynamic_ramp_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate, unsigned long parent_rate) @@ -1518,8 +1486,8 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, defined(CONFIG_ARCH_TEGRA_132_SOC) static const struct clk_ops tegra_clk_pllxc_ops = { .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_iddq_enable, - .disable = clk_pll_iddq_disable, + .enable = clk_pll_enable, + .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_ramp_round_rate, .set_rate = clk_pllxc_set_rate, @@ -1527,8 +1495,8 @@ static const struct clk_ops tegra_clk_pllxc_ops = { static const struct clk_ops tegra_clk_pllm_ops = { .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_iddq_enable, - .disable = clk_pll_iddq_disable, + .enable = clk_pll_enable, + .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_ramp_round_rate, .set_rate = clk_pllm_set_rate, @@ -1545,8 +1513,8 @@ static const struct clk_ops tegra_clk_pllc_ops = { static const struct clk_ops tegra_clk_pllre_ops = { .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_iddq_enable, - .disable = clk_pll_iddq_disable, + .enable = clk_pll_enable, + .disable = clk_pll_disable, .recalc_rate = clk_pllre_recalc_rate, .round_rate = clk_pllre_round_rate, .set_rate = clk_pllre_set_rate, @@ -1815,8 +1783,8 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) static const struct clk_ops tegra_clk_pllss_ops = { .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_iddq_enable, - .disable = clk_pll_iddq_disable, + .enable = clk_pll_enable, + .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_ramp_round_rate, .set_rate = clk_pllxc_set_rate, -- cgit v1.2.3 From 204c85d124bd51c0b1c70f1d6b0d853389179d38 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:21 -0400 Subject: clk: tegra: pll: Update warning message Swap out the generic WARN_ON with a WARN which gives more information about what is happening. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 6c29ad7e15e7..79f4dc230dee 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -692,7 +692,8 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, pdiv = _hw_to_p_div(hw, cfg.p); if (pdiv < 0) { - WARN_ON(1); + WARN(1, "Clock %s has invalid pdiv value : 0x%x\n", + __clk_get_name(hw->clk), cfg.p); pdiv = 1; } -- cgit v1.2.3 From 56fd27b31f1a216623f285bb77b4bcb6129e84c2 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:22 -0400 Subject: clk: tegra: pll: Change misc_reg count from 3 to 6 New SoC's may have more than 3 MISC registers, so bump up the array size and use a #define to be more informative about the value. Reviewed-by: Benson Leung Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index ced19e7c68d2..488ee677e15b 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -156,6 +156,8 @@ struct div_nmp { u8 override_divp_shift; }; +#define MAX_PLL_MISC_REG_COUNT 6 + /** * struct tegra_clk_pll_params - PLL parameters * @@ -225,7 +227,7 @@ struct tegra_clk_pll_params { u32 iddq_bit_idx; u32 aux_reg; u32 dyn_ramp_reg; - u32 ext_misc_reg[3]; + u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT]; u32 pmc_divnm_reg; u32 pmc_divp_reg; u32 flags; -- cgit v1.2.3 From 3706b43629f5b9fd4efce192da40ffa9412e75ee Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:23 -0400 Subject: clk: tegra: pll: Don't unconditionally set LOCK flags SoC specific drivers should define the appropriate flags for each PLL rather than relying on the registration functions to automatically set flags on their behalf. This will properly allow for changes between SoC generations where flags might be different and allow sharing the same logic functions. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 11 ++--------- drivers/clk/tegra/clk-tegra114.c | 23 +++++++++++++---------- drivers/clk/tegra/clk-tegra124.c | 24 +++++++++++++++--------- drivers/clk/tegra/clk-tegra20.c | 18 ++++++++++-------- drivers/clk/tegra/clk-tegra30.c | 24 +++++++++++++++--------- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 79f4dc230dee..54046266bdfb 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1434,7 +1434,7 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, struct clk *clk; pll_params->flags |= TEGRA_PLL_BYPASS; - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1464,8 +1464,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, struct tegra_clk_pll *pll; struct clk *clk; - pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; + pll_params->flags |= TEGRA_PLL_BYPASS; if (!pll_params->div_nmp) pll_params->div_nmp = &pll_e_nmp; @@ -1569,7 +1568,6 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); } - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1592,8 +1590,6 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, struct tegra_clk_pll *pll; struct clk *clk; - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; - pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); @@ -1653,7 +1649,6 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); pll_params->flags |= TEGRA_PLL_BYPASS; - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; pll_params->flags |= TEGRA_PLLM; pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) @@ -1751,7 +1746,6 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, struct clk *clk; u32 val, val_aux; - pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1813,7 +1807,6 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); } - pll_params->flags = TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_USE_LOCK; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index a373d9f7397d..0b942e0cacc2 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -232,7 +232,7 @@ static struct tegra_clk_pll_params pll_c_params = { .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, .freq_table = pll_c_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct div_nmp pllcx_nmp = { @@ -351,7 +351,7 @@ static struct tegra_clk_pll_params pll_m_params = { .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct div_nmp pllp_nmp = { @@ -386,7 +386,8 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_delay = 300, .div_nmp = &pllp_nmp, .freq_table = pll_p_freq_table, - .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 408000000, }; @@ -415,7 +416,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_delay = 300, .div_nmp = &pllp_nmp, .freq_table = pll_a_freq_table, - .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { @@ -451,7 +453,7 @@ static struct tegra_clk_pll_params pll_d_params = { .div_nmp = &pllp_nmp, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_d2_params = { @@ -469,7 +471,7 @@ static struct tegra_clk_pll_params pll_d2_params = { .div_nmp = &pllp_nmp, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static const struct pdiv_map pllu_p[] = { @@ -512,7 +514,7 @@ static struct tegra_clk_pll_params pll_u_params = { .div_nmp = &pllu_nmp, .freq_table = pll_u_freq_table, .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { @@ -546,7 +548,7 @@ static struct tegra_clk_pll_params pll_x_params = { .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, .freq_table = pll_x_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { @@ -581,7 +583,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_delay = 300, .div_nmp = &plle_nmp, .freq_table = pll_e_freq_table, - .flags = TEGRA_PLL_FIXED, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 100000000, }; @@ -609,7 +611,8 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .iddq_reg = PLLRE_MISC, .iddq_bit_idx = PLLRE_IDDQ_BIT, .div_nmp = &pllre_nmp, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_LOCK_MISC, }; /* possible OSC frequencies in Hz */ diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 156a753e902d..3c93dbf4b9bd 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -218,7 +218,7 @@ static struct tegra_clk_pll_params pll_x_params = { .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, .freq_table = pll_x_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { @@ -252,7 +252,7 @@ static struct tegra_clk_pll_params pll_c_params = { .pdiv_tohw = pllxc_p, .div_nmp = &pllxc_nmp, .freq_table = pll_c_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct div_nmp pllcx_nmp = { @@ -386,6 +386,7 @@ static struct tegra_clk_pll_params pll_c4_params = { .ext_misc_reg[1] = 0x5b0, .ext_misc_reg[2] = 0x5b4, .freq_table = pll_c4_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static const struct pdiv_map pllm_p[] = { @@ -433,7 +434,7 @@ static struct tegra_clk_pll_params pll_m_params = { .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { @@ -469,7 +470,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_delay = 300, .div_nmp = &plle_nmp, .freq_table = pll_e_freq_table, - .flags = TEGRA_PLL_FIXED, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 100000000, }; @@ -507,7 +508,8 @@ static struct tegra_clk_pll_params pll_re_vco_params = { .iddq_reg = PLLRE_MISC, .iddq_bit_idx = PLLRE_IDDQ_BIT, .div_nmp = &pllre_nmp, - .flags = TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_LOCK_MISC, }; static struct div_nmp pllp_nmp = { @@ -543,7 +545,8 @@ static struct tegra_clk_pll_params pll_p_params = { .div_nmp = &pllp_nmp, .freq_table = pll_p_freq_table, .fixed_rate = 408000000, - .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { @@ -570,7 +573,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_delay = 300, .div_nmp = &pllp_nmp, .freq_table = pll_a_freq_table, - .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct div_nmp plld_nmp = { @@ -615,7 +619,7 @@ static struct tegra_clk_pll_params pll_d_params = { .div_nmp = &plld_nmp, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { @@ -648,6 +652,7 @@ static struct tegra_clk_pll_params tegra124_pll_d2_params = { .ext_misc_reg[2] = 0x578, .max_p = 15, .freq_table = tegra124_pll_d2_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { @@ -680,6 +685,7 @@ static struct tegra_clk_pll_params pll_dp_params = { .ext_misc_reg[2] = 0x5a0, .max_p = 5, .freq_table = pll_dp_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static const struct pdiv_map pllu_p[] = { @@ -722,7 +728,7 @@ static struct tegra_clk_pll_params pll_u_params = { .div_nmp = &pllu_nmp, .freq_table = pll_u_freq_table, .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; struct utmi_clk_param { diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index d7da6fd8ca30..b49d94bc0b8f 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -291,7 +291,7 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_c_freq_table, - .flags = TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_m_params = { @@ -307,7 +307,7 @@ static struct tegra_clk_pll_params pll_m_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_p_params = { @@ -323,7 +323,8 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_p_freq_table, - .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | + TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 216000000, }; @@ -340,7 +341,7 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_a_freq_table, - .flags = TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_d_params = { @@ -356,7 +357,7 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, .freq_table = pll_d_freq_table, - .flags = TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static const struct pdiv_map pllu_p[] = { @@ -379,7 +380,7 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_delay = 1000, .pdiv_tohw = pllu_p, .freq_table = pll_u_freq_table, - .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_x_params = { @@ -395,7 +396,7 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_x_freq_table, - .flags = TEGRA_PLL_HAS_CPCON, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_e_params = { @@ -411,7 +412,8 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 0, .freq_table = pll_e_freq_table, - .flags = TEGRA_PLL_FIXED, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_LOCK_MISC | + TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 100000000, }; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 019a7fc5512d..a78f033c57e6 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -420,7 +420,8 @@ static struct tegra_clk_pll_params pll_c_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_c_freq_table, - .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct div_nmp pllm_nmp = { @@ -452,7 +453,8 @@ static struct tegra_clk_pll_params pll_m_params = { .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, .freq_table = pll_m_freq_table, .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | - TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, + TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_p_params = { @@ -468,7 +470,8 @@ static struct tegra_clk_pll_params pll_p_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_p_freq_table, - .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, .fixed_rate = 408000000, }; @@ -485,7 +488,8 @@ static struct tegra_clk_pll_params pll_a_params = { .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_a_freq_table, - .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, + .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_d_params = { @@ -502,7 +506,7 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_delay = 1000, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_d2_params = { @@ -519,7 +523,7 @@ static struct tegra_clk_pll_params pll_d2_params = { .lock_delay = 1000, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_u_params = { @@ -536,7 +540,8 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_delay = 1000, .pdiv_tohw = pllu_p, .freq_table = pll_u_freq_table, - .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON, + .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_x_params = { @@ -553,7 +558,7 @@ static struct tegra_clk_pll_params pll_x_params = { .lock_delay = 300, .freq_table = pll_x_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | - TEGRA_PLL_USE_LOCK, + TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_e_params = { @@ -569,7 +574,8 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, .freq_table = pll_e_freq_table, - .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED, + .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED | + TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC, .fixed_rate = 100000000, }; -- cgit v1.2.3 From d907f4b4a178b7bbc8edc67191f63155d6492b80 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:24 -0400 Subject: clk: tegra: pll: Add logic for handling SDM data This adds logic for taking SDM_DIN (Sigma Delta Modulator) setting into the equation to calculate the effective N value for PLL which supports fractional divider. The effective N = NDIV + 1/2 + SDM_DIN/2^13, where NDIV is the integer feedback divider. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 66 ++++++++++++++++++++++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 15 ++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 54046266bdfb..20fd2d8dbad3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -187,17 +187,23 @@ #define pll_readl_base(p) pll_readl(p->params->base_reg, p) #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) #define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset) +#define pll_readl_sdm_din(p) pll_readl(p->params->sdm_din_reg, p) +#define pll_readl_sdm_ctrl(p) pll_readl(p->params->sdm_ctrl_reg, p) #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) #define pll_override_writel(val, offset, p) writel(val, p->pmc + offset) +#define pll_writel_sdm_din(val, p) pll_writel(val, p->params->sdm_din_reg, p) +#define pll_writel_sdm_ctrl(val, p) pll_writel(val, p->params->sdm_ctrl_reg, p) #define mask(w) ((1 << (w)) - 1) #define divm_mask(p) mask(p->params->div_nmp->divm_width) #define divn_mask(p) mask(p->params->div_nmp->divn_width) #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ mask(p->params->div_nmp->divp_width)) +#define sdm_din_mask(p) p->params->sdm_din_mask +#define sdm_en_mask(p) p->params->sdm_ctrl_en_mask #define divm_shift(p) (p)->params->div_nmp->divm_shift #define divn_shift(p) (p)->params->div_nmp->divn_shift @@ -211,6 +217,9 @@ #define divn_max(p) (divn_mask(p)) #define divp_max(p) (1 << (divp_mask(p))) +#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) +#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) + static struct div_nmp default_nmp = { .divn_shift = PLL_BASE_DIVN_SHIFT, .divn_width = PLL_BASE_DIVN_WIDTH, @@ -429,6 +438,7 @@ static int _get_table_rate(struct clk_hw *hw, cfg->n = sel->n; cfg->p = sel->p; cfg->cpcon = sel->cpcon; + cfg->sdm_data = sel->sdm_data; return 0; } @@ -495,6 +505,42 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, return 0; } +/* + * SDM (Sigma Delta Modulator) divisor is 16-bit 2's complement signed number + * within (-2^12 ... 2^12-1) range. Represented in PLL data structure as + * unsigned 16-bit value, with "0" divisor mapped to 0xFFFF. Data "0" is used + * to indicate that SDM is disabled. + * + * Effective ndiv value when SDM is enabled: ndiv + 1/2 + sdm_din/2^13 + */ +static void clk_pll_set_sdm_data(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + u32 val; + bool enabled; + + if (!pll->params->sdm_din_reg) + return; + + if (cfg->sdm_data) { + val = pll_readl_sdm_din(pll) & (~sdm_din_mask(pll)); + val |= sdin_data_to_din(cfg->sdm_data) & sdm_din_mask(pll); + pll_writel_sdm_din(val, pll); + } + + val = pll_readl_sdm_ctrl(pll); + enabled = (val & sdm_en_mask(pll)); + + if (cfg->sdm_data == 0 && enabled) + val &= ~pll->params->sdm_ctrl_en_mask; + + if (cfg->sdm_data != 0 && !enabled) + val |= pll->params->sdm_ctrl_en_mask; + + pll_writel_sdm_ctrl(val, pll); +} + static void _update_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_freq_table *cfg) { @@ -527,6 +573,8 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, (cfg->p << divp_shift(pll)); pll_writel_base(val, pll); + + clk_pll_set_sdm_data(&pll->hw, cfg); } } @@ -552,6 +600,14 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, cfg->m = (val >> div_nmp->divm_shift) & divm_mask(pll); cfg->n = (val >> div_nmp->divn_shift) & divn_mask(pll); cfg->p = (val >> div_nmp->divp_shift) & divp_mask(pll); + + if (pll->params->sdm_din_reg) { + if (sdm_en_mask(pll) & pll_readl_sdm_ctrl(pll)) { + val = pll_readl_sdm_din(pll); + val &= sdm_din_mask(pll); + cfg->sdm_data = sdin_din_to_data(val); + } + } } } @@ -633,7 +689,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, _get_pll_mnp(pll, &old_cfg); - if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p) + if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p || + old_cfg.sdm_data != cfg.sdm_data) ret = _program_pll(hw, &cfg, rate); if (pll->lock) @@ -697,6 +754,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, pdiv = 1; } + if (pll->params->set_gain) + pll->params->set_gain(&cfg); + cfg.m *= pdiv; rate *= cfg.n; @@ -978,6 +1038,7 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { + struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; int ret, p_div; u64 output_rate = *prate; @@ -990,6 +1051,9 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, if (p_div < 0) return p_div; + if (pll->params->set_gain) + pll->params->set_gain(&cfg); + output_rate *= cfg.n; do_div(output_rate, cfg.m * p_div); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 488ee677e15b..72368e1ed46a 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -110,14 +110,16 @@ struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, * @m: input divider * @p: post divider * @cpcon: charge pump current + * @sdm_data: fraction divider setting (0 = disabled) */ struct tegra_clk_pll_freq_table { unsigned long input_rate; unsigned long output_rate; - u16 n; + u32 n; u16 m; u8 p; u8 cpcon; + u16 sdm_data; }; /** @@ -174,6 +176,10 @@ struct div_nmp { * @lock_enable_bit_idx: Bit index to enable PLL lock * @iddq_reg: PLL IDDQ register offset * @iddq_bit_idx: Bit index to enable PLL IDDQ + * @sdm_din_reg: Register offset where SDM settings are + * @sdm_din_mask: Mask of SDM divider bits + * @sdm_ctrl_reg: Register offset where SDM enable is + * @sdm_ctrl_en_mask: Mask of SDM enable bit * @aux_reg: AUX register offset * @dyn_ramp_reg: Dynamic ramp control register offset * @ext_misc_reg: Miscellaneous control register offsets @@ -188,6 +194,8 @@ struct div_nmp { * @div_nmp: offsets and widths on n, m and p fields * @freq_table: array of frequencies supported by PLL * @fixed_rate: PLL rate if it is fixed + * @set_gain: Callback to adjust N div for SDM enabled + * PLL's based on fractional divider value. * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -225,6 +233,10 @@ struct tegra_clk_pll_params { u32 lock_enable_bit_idx; u32 iddq_reg; u32 iddq_bit_idx; + u32 sdm_din_reg; + u32 sdm_din_mask; + u32 sdm_ctrl_reg; + u32 sdm_ctrl_en_mask; u32 aux_reg; u32 dyn_ramp_reg; u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT]; @@ -239,6 +251,7 @@ struct tegra_clk_pll_params { struct div_nmp *div_nmp; struct tegra_clk_pll_freq_table *freq_table; unsigned long fixed_rate; + void (*set_gain)(struct tegra_clk_pll_freq_table *cfg); }; #define TEGRA_PLL_USE_LOCK BIT(0) -- cgit v1.2.3 From 407254da291c03c32109881ca8cbda5607714a8f Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:25 -0400 Subject: clk: tegra: pll: Add logic for out-of-table rates for T210 For Tegra210, the logic to calculate out-of-table rates is different from previous generations. Add callbacks that can be overridden to allow for different ways of calculating rates. Default to _cal_rate when not specified. This patch also includes a new flag which is used to set which method of fixed_mdiv calculation is used. The new method for calculating the fixed divider value for M can be more accurate especially when fractional dividers are in play. This allows for older chipsets to use the existing logic and new generations to use a newer version which may work better for them. Based on original work by Aleksandr Frid Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 24 ++++++++++++++++++++++-- drivers/clk/tegra/clk.h | 13 +++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 20fd2d8dbad3..fb3e3f67586c 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -678,7 +678,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, } if (_get_table_rate(hw, &cfg, rate, parent_rate) && - _calc_rate(hw, &cfg, rate, parent_rate)) { + pll->params->calc_rate(hw, &cfg, rate, parent_rate)) { pr_err("%s: Failed to set %s rate %lu\n", __func__, clk_hw_get_name(hw), rate); WARN_ON(1); @@ -713,7 +713,7 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clk_hw_get_rate(hw); if (_get_table_rate(hw, &cfg, rate, *prate) && - _calc_rate(hw, &cfg, rate, *prate)) + pll->params->calc_rate(hw, &cfg, rate, *prate)) return -EINVAL; return cfg.output_rate; @@ -903,12 +903,28 @@ const struct clk_ops tegra_clk_plle_ops = { static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate) { + u16 mdiv = parent_rate / pll_params->cf_min; + + if (pll_params->flags & TEGRA_MDIV_NEW) + return (!pll_params->mdiv_default ? mdiv : + min(mdiv, pll_params->mdiv_default)); + + if (pll_params->mdiv_default) + return pll_params->mdiv_default; + if (parent_rate > pll_params->cf_max) return 2; else return 1; } +u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + + return (u16)_pll_fixed_mdiv(pll->params, input_rate); +} + static unsigned long _clip_vco_min(unsigned long vco_min, unsigned long parent_rate) { @@ -1483,6 +1499,10 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); + /* Default to _calc_rate if unspecified */ + if (!pll->params->calc_rate) + pll->params->calc_rate = _calc_rate; + /* Data in .init is copied by clk_register(), so stack variable OK */ pll->hw.init = &init; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 72368e1ed46a..ae09a3139df2 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -194,8 +194,12 @@ struct div_nmp { * @div_nmp: offsets and widths on n, m and p fields * @freq_table: array of frequencies supported by PLL * @fixed_rate: PLL rate if it is fixed + * @mdiv_default: Default value for fixed mdiv for this PLL + * @round_p_to_pdiv: Callback used to round p to the closed pdiv * @set_gain: Callback to adjust N div for SDM enabled * PLL's based on fractional divider value. + * @calc_rate: Callback used to change how out of table + * rates (dividers and multipler) are calculated. * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -217,6 +221,8 @@ struct div_nmp { * base register. * TEGRA_PLL_BYPASS - PLL has bypass bit * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring + * TEGRA_MDIV_NEW - Switch to new method for calculating fixed mdiv + * it may be more accurate (especially if SDM present) */ struct tegra_clk_pll_params { unsigned long input_min; @@ -251,7 +257,12 @@ struct tegra_clk_pll_params { struct div_nmp *div_nmp; struct tegra_clk_pll_freq_table *freq_table; unsigned long fixed_rate; + u16 mdiv_default; + u32 (*round_p_to_pdiv)(u32 p, u32 *pdiv); void (*set_gain)(struct tegra_clk_pll_freq_table *cfg); + int (*calc_rate)(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long parent_rate); }; #define TEGRA_PLL_USE_LOCK BIT(0) @@ -265,6 +276,7 @@ struct tegra_clk_pll_params { #define TEGRA_PLL_LOCK_MISC BIT(8) #define TEGRA_PLL_BYPASS BIT(9) #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) +#define TEGRA_MDIV_NEW BIT(11) /** * struct tegra_clk_pll - Tegra PLL clock @@ -690,5 +702,6 @@ void tegra114_clock_deassert_dfll_dvco_reset(void); typedef void (*tegra_clk_apply_init_table_func)(void); extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); +u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); #endif /* TEGRA_CLK_H */ -- cgit v1.2.3 From fde207eb15115f1081e589267ebdf442aa54cda5 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:26 -0400 Subject: clk: tegra: pll: Add code to handle if resets are supported by PLL If a PLL has a reset_reg specified, properly handle that in the enable/disable logic paths. Reviewed-by: Benson Leung Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 12 ++++++++++++ drivers/clk/tegra/clk.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index fb3e3f67586c..c645a899deba 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -311,6 +311,12 @@ static void _clk_pll_enable(struct clk_hw *hw) udelay(2); } + if (pll->params->reset_reg) { + val = pll_readl(pll->params->reset_reg, pll); + val &= ~BIT(pll->params->reset_bit_idx); + pll_writel(val, pll->params->reset_reg, pll); + } + clk_pll_enable_lock(pll); val = pll_readl_base(pll); @@ -343,6 +349,12 @@ static void _clk_pll_disable(struct clk_hw *hw) writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); } + if (pll->params->reset_reg) { + val = pll_readl(pll->params->reset_reg, pll); + val |= BIT(pll->params->reset_bit_idx); + pll_writel(val, pll->params->reset_reg, pll); + } + if (pll->params->iddq_reg) { val = pll_readl(pll->params->iddq_reg, pll); val |= BIT(pll->params->iddq_bit_idx); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index ae09a3139df2..adf2e8ead335 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -176,6 +176,8 @@ struct div_nmp { * @lock_enable_bit_idx: Bit index to enable PLL lock * @iddq_reg: PLL IDDQ register offset * @iddq_bit_idx: Bit index to enable PLL IDDQ + * @reset_reg: Register offset of where RESET bit is + * @reset_bit_idx: Shift of reset bit in reset_reg * @sdm_din_reg: Register offset where SDM settings are * @sdm_din_mask: Mask of SDM divider bits * @sdm_ctrl_reg: Register offset where SDM enable is @@ -239,6 +241,8 @@ struct tegra_clk_pll_params { u32 lock_enable_bit_idx; u32 iddq_reg; u32 iddq_bit_idx; + u32 reset_reg; + u32 reset_bit_idx; u32 sdm_din_reg; u32 sdm_din_mask; u32 sdm_ctrl_reg; -- cgit v1.2.3 From 86c679a52294d4c4b989903a75e31495c04d688a Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:34 -0400 Subject: clk: tegra: pll: Fix _pll_ramp_calc_pll logic and _calc_dynamic_ramp_rate This removes the conversion from pdiv to hw, which is already taken care of by _get_table_rate before this code is run. This avoids incorrectly converting pdiv to hw twice and getting the wrong hw value. Also set the input_rate in the freq cfg in _calc_dynamic_ramp_rate while setting all the other fields. In order to prevent regressions on earlier SoC generations, all of the frequency tables need to be updated so that they contain the actual divider values. If they contain hardware values these would be converted to hardware values again, yielding the wrong value. Signed-off-by: Rhyland Klein [treding@nvidia.com: fix regressions on earlier SoC generations] Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 91 +++++++++------- drivers/clk/tegra/clk-tegra114.c | 122 ++++++++++++--------- drivers/clk/tegra/clk-tegra124.c | 93 ++++++++++------ drivers/clk/tegra/clk-tegra20.c | 150 +++++++++++++------------- drivers/clk/tegra/clk-tegra30.c | 227 ++++++++++++++++++++------------------- 5 files changed, 379 insertions(+), 304 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index c645a899deba..b8b3fc6dc39b 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -435,6 +435,7 @@ static int _get_table_rate(struct clk_hw *hw, { struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table *sel; + int p; for (sel = pll->params->freq_table; sel->input_rate != 0; sel++) if (sel->input_rate == parent_rate && @@ -444,11 +445,19 @@ static int _get_table_rate(struct clk_hw *hw, if (sel->input_rate == 0) return -EINVAL; + if (pll->params->pdiv_tohw) { + p = _p_div_to_hw(hw, sel->p); + if (p < 0) + return p; + } else { + p = ilog2(sel->p); + } + cfg->input_rate = sel->input_rate; cfg->output_rate = sel->output_rate; cfg->m = sel->m; cfg->n = sel->n; - cfg->p = sel->p; + cfg->p = p; cfg->cpcon = sel->cpcon; cfg->sdm_data = sel->sdm_data; @@ -908,10 +917,6 @@ const struct clk_ops tegra_clk_plle_ops = { .enable = clk_plle_enable, }; -#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ - defined(CONFIG_ARCH_TEGRA_124_SOC) || \ - defined(CONFIG_ARCH_TEGRA_132_SOC) - static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate) { @@ -930,6 +935,39 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, return 1; } +static int _calc_dynamic_ramp_rate(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long parent_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned int p; + int p_div; + + if (!rate) + return -EINVAL; + + p = DIV_ROUND_UP(pll->params->vco_min, rate); + cfg->m = _pll_fixed_mdiv(pll->params, parent_rate); + cfg->output_rate = rate * p; + cfg->n = cfg->output_rate * cfg->m / parent_rate; + cfg->input_rate = parent_rate; + + p_div = _p_div_to_hw(hw, p); + if (p_div < 0) + return p_div; + + cfg->p = p_div; + + if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) + return -EINVAL; + + return 0; +} + +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ + defined(CONFIG_ARCH_TEGRA_132_SOC) + u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate) { struct tegra_clk_pll *pll = to_clk_pll(hw); @@ -979,40 +1017,12 @@ static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, return 0; } -static int _calc_dynamic_ramp_rate(struct clk_hw *hw, - struct tegra_clk_pll_freq_table *cfg, - unsigned long rate, unsigned long parent_rate) -{ - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned int p; - int p_div; - - if (!rate) - return -EINVAL; - - p = DIV_ROUND_UP(pll->params->vco_min, rate); - cfg->m = _pll_fixed_mdiv(pll->params, parent_rate); - cfg->output_rate = rate * p; - cfg->n = cfg->output_rate * cfg->m / parent_rate; - - p_div = _p_div_to_hw(hw, p); - if (p_div < 0) - return p_div; - - cfg->p = p_div; - - if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) - return -EINVAL; - - return 0; -} - static int _pll_ramp_calc_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate, unsigned long parent_rate) { struct tegra_clk_pll *pll = to_clk_pll(hw); - int err = 0, p_div; + int err = 0; err = _get_table_rate(hw, cfg, rate, parent_rate); if (err < 0) @@ -1023,11 +1033,6 @@ static int _pll_ramp_calc_pll(struct clk_hw *hw, err = -EINVAL; goto out; } - p_div = _p_div_to_hw(hw, cfg->p); - if (p_div < 0) - return p_div; - else - cfg->p = p_div; } if (cfg->p > pll->params->max_p) @@ -1512,8 +1517,12 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, init.num_parents = (parent_name ? 1 : 0); /* Default to _calc_rate if unspecified */ - if (!pll->params->calc_rate) - pll->params->calc_rate = _calc_rate; + if (!pll->params->calc_rate) { + if (pll->params->flags & TEGRA_PLLM) + pll->params->calc_rate = _calc_dynamic_ramp_rate; + else + pll->params->calc_rate = _calc_rate; + } /* Data in .init is copied by clk_register(), so stack variable OK */ pll->hw.init = &init; diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 0b942e0cacc2..9411a1577d85 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -202,12 +202,12 @@ static const struct pdiv_map pllxc_p[] = { }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 624000000, 104, 0, 2, 0 }, - { 12000000, 600000000, 100, 0, 2, 0 }, - { 13000000, 600000000, 92, 0, 2, 0 }, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 0, 2, 0 }, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 0, 2, 0 }, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 12000000, 624000000, 104, 1, 2, 0 }, + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -254,11 +254,11 @@ static const struct pdiv_map pllc_p[] = { }; static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { - { 12000000, 600000000, 100, 0, 2, 0 }, - { 13000000, 600000000, 92, 0, 2, 0 }, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 0, 2, 0 }, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 0, 2, 0 }, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -325,11 +325,11 @@ static const struct pdiv_map pllm_p[] = { }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 800000000, 66, 0, 1, 0 }, /* actual: 792.0 MHz */ - { 13000000, 800000000, 61, 0, 1, 0 }, /* actual: 793.0 MHz */ - { 16800000, 800000000, 47, 0, 1, 0 }, /* actual: 789.6 MHz */ - { 19200000, 800000000, 41, 0, 1, 0 }, /* actual: 787.2 MHz */ - { 26000000, 800000000, 61, 1, 1, 0 }, /* actual: 793.0 MHz */ + { 12000000, 800000000, 66, 1, 1, 0 }, /* actual: 792.0 MHz */ + { 13000000, 800000000, 61, 1, 1, 0 }, /* actual: 793.0 MHz */ + { 16800000, 800000000, 47, 1, 1, 0 }, /* actual: 789.6 MHz */ + { 19200000, 800000000, 41, 1, 1, 0 }, /* actual: 787.2 MHz */ + { 26000000, 800000000, 61, 2, 1, 0 }, /* actual: 793.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -364,11 +364,11 @@ static struct div_nmp pllp_nmp = { }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 1, 8 }, - { 13000000, 216000000, 432, 13, 1, 8 }, - { 16800000, 216000000, 360, 14, 1, 8 }, - { 19200000, 216000000, 360, 16, 1, 8 }, - { 26000000, 216000000, 432, 26, 1, 8 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -392,12 +392,12 @@ static struct tegra_clk_pll_params pll_p_params = { }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 9600000, 282240000, 147, 5, 0, 4 }, - { 9600000, 368640000, 192, 5, 0, 4 }, - { 9600000, 240000000, 200, 8, 0, 8 }, - { 28800000, 282240000, 245, 25, 0, 8 }, - { 28800000, 368640000, 320, 25, 0, 8 }, - { 28800000, 240000000, 200, 24, 0, 8 }, + { 9600000, 282240000, 147, 5, 1, 4 }, + { 9600000, 368640000, 192, 5, 1, 4 }, + { 9600000, 240000000, 200, 8, 1, 8 }, + { 28800000, 282240000, 245, 25, 1, 8 }, + { 28800000, 368640000, 320, 25, 1, 8 }, + { 28800000, 240000000, 200, 24, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -421,20 +421,20 @@ static struct tegra_clk_pll_params pll_a_params = { }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 864, 12, 2, 12 }, - { 13000000, 216000000, 864, 13, 2, 12 }, - { 16800000, 216000000, 720, 14, 2, 12 }, - { 19200000, 216000000, 720, 16, 2, 12 }, - { 26000000, 216000000, 864, 26, 2, 12 }, - { 12000000, 594000000, 594, 12, 0, 12 }, - { 13000000, 594000000, 594, 13, 0, 12 }, - { 16800000, 594000000, 495, 14, 0, 12 }, - { 19200000, 594000000, 495, 16, 0, 12 }, - { 26000000, 594000000, 594, 26, 0, 12 }, - { 12000000, 1000000000, 1000, 12, 0, 12 }, - { 13000000, 1000000000, 1000, 13, 0, 12 }, - { 19200000, 1000000000, 625, 12, 0, 12 }, - { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 12000000, 216000000, 864, 12, 4, 12 }, + { 13000000, 216000000, 864, 13, 4, 12 }, + { 16800000, 216000000, 720, 14, 4, 12 }, + { 19200000, 216000000, 720, 16, 4, 12 }, + { 26000000, 216000000, 864, 26, 4, 12 }, + { 12000000, 594000000, 594, 12, 1, 12 }, + { 13000000, 594000000, 594, 13, 1, 12 }, + { 16800000, 594000000, 495, 14, 1, 12 }, + { 19200000, 594000000, 495, 16, 1, 12 }, + { 26000000, 594000000, 594, 26, 1, 12 }, + { 12000000, 1000000000, 1000, 12, 1, 12 }, + { 13000000, 1000000000, 1000, 13, 1, 12 }, + { 19200000, 1000000000, 625, 12, 1, 12 }, + { 26000000, 1000000000, 1000, 26, 1, 12 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -490,11 +490,11 @@ static struct div_nmp pllu_nmp = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 12 }, - { 13000000, 480000000, 960, 13, 0, 12 }, - { 16800000, 480000000, 400, 7, 0, 5 }, - { 19200000, 480000000, 200, 4, 0, 3 }, - { 26000000, 480000000, 960, 26, 0, 12 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -519,11 +519,11 @@ static struct tegra_clk_pll_params pll_u_params = { static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - { 12000000, 1000000000, 83, 0, 1, 0 }, /* actual: 996.0 MHz */ - { 13000000, 1000000000, 76, 0, 1, 0 }, /* actual: 988.0 MHz */ - { 16800000, 1000000000, 59, 0, 1, 0 }, /* actual: 991.2 MHz */ - { 19200000, 1000000000, 52, 0, 1, 0 }, /* actual: 998.4 MHz */ - { 26000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 12000000, 1000000000, 83, 1, 1, 0 }, /* actual: 996.0 MHz */ + { 13000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 16800000, 1000000000, 59, 1, 1, 0 }, /* actual: 991.2 MHz */ + { 19200000, 1000000000, 52, 1, 1, 0 }, /* actual: 998.4 MHz */ + { 26000000, 1000000000, 76, 2, 1, 0 }, /* actual: 988.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -559,6 +559,25 @@ static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { { 0, 0, 0, 0, 0, 0 }, }; +static const struct pdiv_map plle_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 } +}; + static struct div_nmp plle_nmp = { .divm_shift = 0, .divm_width = 8, @@ -581,6 +600,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, + .pdiv_tohw = plle_p, .div_nmp = &plle_nmp, .freq_table = pll_e_freq_table, .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_LOCK_ENABLE, diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 3c93dbf4b9bd..1627258292d2 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -189,11 +189,11 @@ static const struct pdiv_map pllxc_p[] = { static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - { 12000000, 1000000000, 83, 0, 1, 0 }, /* actual: 996.0 MHz */ - { 13000000, 1000000000, 76, 0, 1, 0 }, /* actual: 988.0 MHz */ - { 16800000, 1000000000, 59, 0, 1, 0 }, /* actual: 991.2 MHz */ - { 19200000, 1000000000, 52, 0, 1, 0 }, /* actual: 998.4 MHz */ - { 26000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 12000000, 1000000000, 83, 1, 1, 0 }, /* actual: 996.0 MHz */ + { 13000000, 1000000000, 76, 1, 1, 0 }, /* actual: 988.0 MHz */ + { 16800000, 1000000000, 59, 1, 1, 0 }, /* actual: 991.2 MHz */ + { 19200000, 1000000000, 52, 1, 1, 0 }, /* actual: 998.4 MHz */ + { 26000000, 1000000000, 76, 2, 1, 0 }, /* actual: 988.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -358,11 +358,11 @@ static const struct pdiv_map pll12g_ssd_esd_p[] = { }; static struct tegra_clk_pll_freq_table pll_c4_freq_table[] = { - { 12000000, 600000000, 100, 1, 1, 0 }, - { 13000000, 600000000, 92, 1, 1, 0 }, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 1, 1, 0 }, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 1, 1, 0 }, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 2, 1, 0 }, /* actual: 598.0 MHz */ + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; @@ -390,9 +390,22 @@ static struct tegra_clk_pll_params pll_c4_params = { }; static const struct pdiv_map pllm_p[] = { - { .pdiv = 1, .hw_val = 0 }, - { .pdiv = 2, .hw_val = 1 }, - { .pdiv = 0, .hw_val = 0 }, + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { @@ -428,7 +441,7 @@ static struct tegra_clk_pll_params pll_m_params = { .lock_mask = PLL_BASE_LOCK, .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, .lock_delay = 300, - .max_p = 2, + .max_p = 5, .pdiv_tohw = pllm_p, .div_nmp = &pllm_nmp, .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, @@ -446,6 +459,25 @@ static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { { 0, 0, 0, 0, 0, 0 }, }; +static const struct pdiv_map plle_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 1, .hw_val = 0 }, +}; + static struct div_nmp plle_nmp = { .divm_shift = 0, .divm_width = 8, @@ -468,6 +500,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, + .pdiv_tohw = plle_p, .div_nmp = &plle_nmp, .freq_table = pll_e_freq_table, .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_LOCK_ENABLE, @@ -522,11 +555,11 @@ static struct div_nmp pllp_nmp = { }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 408000000, 408, 12, 0, 8 }, - { 13000000, 408000000, 408, 13, 0, 8 }, - { 16800000, 408000000, 340, 14, 0, 8 }, - { 19200000, 408000000, 340, 16, 0, 8 }, - { 26000000, 408000000, 408, 26, 0, 8 }, + { 12000000, 408000000, 408, 12, 1, 8 }, + { 13000000, 408000000, 408, 13, 1, 8 }, + { 16800000, 408000000, 340, 14, 1, 8 }, + { 19200000, 408000000, 340, 16, 1, 8 }, + { 26000000, 408000000, 408, 26, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -550,12 +583,12 @@ static struct tegra_clk_pll_params pll_p_params = { }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 9600000, 282240000, 147, 5, 0, 4 }, - { 9600000, 368640000, 192, 5, 0, 4 }, - { 9600000, 240000000, 200, 8, 0, 8 }, - { 28800000, 282240000, 245, 25, 0, 8 }, - { 28800000, 368640000, 320, 25, 0, 8 }, - { 28800000, 240000000, 200, 24, 0, 8 }, + { 9600000, 282240000, 147, 5, 1, 4 }, + { 9600000, 368640000, 192, 5, 1, 4 }, + { 9600000, 240000000, 200, 8, 1, 8 }, + { 28800000, 282240000, 245, 25, 1, 8 }, + { 28800000, 368640000, 320, 25, 1, 8 }, + { 28800000, 240000000, 200, 24, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -656,11 +689,11 @@ static struct tegra_clk_pll_params tegra124_pll_d2_params = { }; static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { - { 12000000, 600000000, 100, 1, 1, 0 }, - { 13000000, 600000000, 92, 1, 1, 0 }, /* actual: 598.0 MHz */ - { 16800000, 600000000, 71, 1, 1, 0 }, /* actual: 596.4 MHz */ - { 19200000, 600000000, 62, 1, 1, 0 }, /* actual: 595.2 MHz */ - { 26000000, 600000000, 92, 2, 1, 0 }, /* actual: 598.0 MHz */ + { 12000000, 600000000, 100, 1, 2, 0 }, + { 13000000, 600000000, 92, 1, 2, 0 }, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 1, 2, 0 }, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 1, 2, 0 }, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 2, 2, 0 }, /* actual: 598.0 MHz */ { 0, 0, 0, 0, 0, 0 }, }; diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index b49d94bc0b8f..7a48e986c4c9 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -166,114 +166,119 @@ static DEFINE_SPINLOCK(emc_lock); static struct clk **clks; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 600000000, 600, 12, 0, 8 }, - { 13000000, 600000000, 600, 13, 0, 8 }, - { 19200000, 600000000, 500, 16, 0, 6 }, - { 26000000, 600000000, 600, 26, 0, 8 }, + { 12000000, 600000000, 600, 12, 1, 8 }, + { 13000000, 600000000, 600, 13, 1, 8 }, + { 19200000, 600000000, 500, 16, 1, 6 }, + { 26000000, 600000000, 600, 26, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 0, 8 }, - { 13000000, 666000000, 666, 13, 0, 8 }, - { 19200000, 666000000, 555, 16, 0, 8 }, - { 26000000, 666000000, 666, 26, 0, 8 }, - { 12000000, 600000000, 600, 12, 0, 8 }, - { 13000000, 600000000, 600, 13, 0, 8 }, - { 19200000, 600000000, 375, 12, 0, 6 }, - { 26000000, 600000000, 600, 26, 0, 8 }, + { 12000000, 666000000, 666, 12, 1, 8 }, + { 13000000, 666000000, 666, 13, 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 }, + { 19200000, 600000000, 375, 12, 1, 6 }, + { 26000000, 600000000, 600, 26, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 1, 8 }, - { 13000000, 216000000, 432, 13, 1, 8 }, - { 19200000, 216000000, 90, 4, 1, 1 }, - { 26000000, 216000000, 432, 26, 1, 8 }, - { 12000000, 432000000, 432, 12, 0, 8 }, - { 13000000, 432000000, 432, 13, 0, 8 }, - { 19200000, 432000000, 90, 4, 0, 1 }, - { 26000000, 432000000, 432, 26, 0, 8 }, + { 12000000, 216000000, 432, 12, 2, 8 }, + { 13000000, 216000000, 432, 13, 2, 8 }, + { 19200000, 216000000, 90, 4, 2, 1 }, + { 26000000, 216000000, 432, 26, 2, 8 }, + { 12000000, 432000000, 432, 12, 1, 8 }, + { 13000000, 432000000, 432, 13, 1, 8 }, + { 19200000, 432000000, 90, 4, 1, 1 }, + { 26000000, 432000000, 432, 26, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 28800000, 56448000, 49, 25, 0, 1 }, - { 28800000, 73728000, 64, 25, 0, 1 }, - { 28800000, 24000000, 5, 6, 0, 1 }, + { 28800000, 56448000, 49, 25, 1, 1 }, + { 28800000, 73728000, 64, 25, 1, 1 }, + { 28800000, 24000000, 5, 6, 1, 1 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 0, 4 }, - { 13000000, 216000000, 216, 13, 0, 4 }, - { 19200000, 216000000, 135, 12, 0, 3 }, - { 26000000, 216000000, 216, 26, 0, 4 }, - { 12000000, 594000000, 594, 12, 0, 8 }, - { 13000000, 594000000, 594, 13, 0, 8 }, - { 19200000, 594000000, 495, 16, 0, 8 }, - { 26000000, 594000000, 594, 26, 0, 8 }, - { 12000000, 1000000000, 1000, 12, 0, 12 }, - { 13000000, 1000000000, 1000, 13, 0, 12 }, - { 19200000, 1000000000, 625, 12, 0, 8 }, - { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 12000000, 216000000, 216, 12, 1, 4 }, + { 13000000, 216000000, 216, 13, 1, 4 }, + { 19200000, 216000000, 135, 12, 1, 3 }, + { 26000000, 216000000, 216, 26, 1, 4 }, + { 12000000, 594000000, 594, 12, 1, 8 }, + { 13000000, 594000000, 594, 13, 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 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 0 }, - { 13000000, 480000000, 960, 13, 0, 0 }, - { 19200000, 480000000, 200, 4, 0, 0 }, - { 26000000, 480000000, 960, 26, 0, 0 }, + { 12000000, 480000000, 960, 12, 1, 0 }, + { 13000000, 480000000, 960, 13, 1, 0 }, + { 19200000, 480000000, 200, 4, 1, 0 }, + { 26000000, 480000000, 960, 26, 1, 0 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 0, 12 }, - { 13000000, 1000000000, 1000, 13, 0, 12 }, - { 19200000, 1000000000, 625, 12, 0, 8 }, - { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 12000000, 1000000000, 1000, 12, 1, 12 }, + { 13000000, 1000000000, 1000, 13, 1, 12 }, + { 19200000, 1000000000, 625, 12, 1, 8 }, + { 26000000, 1000000000, 1000, 26, 1, 12 }, /* 912 MHz */ - { 12000000, 912000000, 912, 12, 0, 12 }, - { 13000000, 912000000, 912, 13, 0, 12 }, - { 19200000, 912000000, 760, 16, 0, 8 }, - { 26000000, 912000000, 912, 26, 0, 12 }, + { 12000000, 912000000, 912, 12, 1, 12 }, + { 13000000, 912000000, 912, 13, 1, 12 }, + { 19200000, 912000000, 760, 16, 1, 8 }, + { 26000000, 912000000, 912, 26, 1, 12 }, /* 816 MHz */ - { 12000000, 816000000, 816, 12, 0, 12 }, - { 13000000, 816000000, 816, 13, 0, 12 }, - { 19200000, 816000000, 680, 16, 0, 8 }, - { 26000000, 816000000, 816, 26, 0, 12 }, + { 12000000, 816000000, 816, 12, 1, 12 }, + { 13000000, 816000000, 816, 13, 1, 12 }, + { 19200000, 816000000, 680, 16, 1, 8 }, + { 26000000, 816000000, 816, 26, 1, 12 }, /* 760 MHz */ - { 12000000, 760000000, 760, 12, 0, 12 }, - { 13000000, 760000000, 760, 13, 0, 12 }, - { 19200000, 760000000, 950, 24, 0, 8 }, - { 26000000, 760000000, 760, 26, 0, 12 }, + { 12000000, 760000000, 760, 12, 1, 12 }, + { 13000000, 760000000, 760, 13, 1, 12 }, + { 19200000, 760000000, 950, 24, 1, 8 }, + { 26000000, 760000000, 760, 26, 1, 12 }, /* 750 MHz */ - { 12000000, 750000000, 750, 12, 0, 12 }, - { 13000000, 750000000, 750, 13, 0, 12 }, - { 19200000, 750000000, 625, 16, 0, 8 }, - { 26000000, 750000000, 750, 26, 0, 12 }, + { 12000000, 750000000, 750, 12, 1, 12 }, + { 13000000, 750000000, 750, 13, 1, 12 }, + { 19200000, 750000000, 625, 16, 1, 8 }, + { 26000000, 750000000, 750, 26, 1, 12 }, /* 608 MHz */ - { 12000000, 608000000, 608, 12, 0, 12 }, - { 13000000, 608000000, 608, 13, 0, 12 }, - { 19200000, 608000000, 380, 12, 0, 8 }, - { 26000000, 608000000, 608, 26, 0, 12 }, + { 12000000, 608000000, 608, 12, 1, 12 }, + { 13000000, 608000000, 608, 13, 1, 12 }, + { 19200000, 608000000, 380, 12, 1, 8 }, + { 26000000, 608000000, 608, 26, 1, 12 }, /* 456 MHz */ - { 12000000, 456000000, 456, 12, 0, 12 }, - { 13000000, 456000000, 456, 13, 0, 12 }, - { 19200000, 456000000, 380, 16, 0, 8 }, - { 26000000, 456000000, 456, 26, 0, 12 }, + { 12000000, 456000000, 456, 12, 1, 12 }, + { 13000000, 456000000, 456, 13, 1, 12 }, + { 19200000, 456000000, 380, 16, 1, 8 }, + { 26000000, 456000000, 456, 26, 1, 12 }, /* 312 MHz */ - { 12000000, 312000000, 312, 12, 0, 12 }, - { 13000000, 312000000, 312, 13, 0, 12 }, - { 19200000, 312000000, 260, 16, 0, 8 }, - { 26000000, 312000000, 312, 26, 0, 12 }, + { 12000000, 312000000, 312, 12, 1, 12 }, + { 13000000, 312000000, 312, 13, 1, 12 }, + { 19200000, 312000000, 260, 16, 1, 8 }, + { 26000000, 312000000, 312, 26, 1, 12 }, { 0, 0, 0, 0, 0, 0 }, }; +static const struct pdiv_map plle_p[] = { + { .pdiv = 1, .hw_val = 1 }, + { .pdiv = 0, .hw_val = 0 }, +}; + static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { - { 12000000, 100000000, 200, 24, 0, 0 }, + { 12000000, 100000000, 200, 24, 1, 0 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -411,6 +416,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 0, + .pdiv_tohw = plle_p, .freq_table = pll_e_freq_table, .flags = TEGRA_PLL_FIXED | TEGRA_PLL_LOCK_MISC | TEGRA_PLL_HAS_LOCK_ENABLE, diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index a78f033c57e6..8493dd90f685 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -248,87 +248,87 @@ static const struct utmi_clk_param utmi_parameters[] = { }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 1040000000, 520, 6, 0, 8 }, - { 13000000, 1040000000, 480, 6, 0, 8 }, - { 16800000, 1040000000, 495, 8, 0, 8 }, /* actual: 1039.5 MHz */ - { 19200000, 1040000000, 325, 6, 0, 6 }, - { 26000000, 1040000000, 520, 13, 0, 8 }, - { 12000000, 832000000, 416, 6, 0, 8 }, - { 13000000, 832000000, 832, 13, 0, 8 }, - { 16800000, 832000000, 396, 8, 0, 8 }, /* actual: 831.6 MHz */ - { 19200000, 832000000, 260, 6, 0, 8 }, - { 26000000, 832000000, 416, 13, 0, 8 }, - { 12000000, 624000000, 624, 12, 0, 8 }, - { 13000000, 624000000, 624, 13, 0, 8 }, - { 16800000, 600000000, 520, 14, 0, 8 }, - { 19200000, 624000000, 520, 16, 0, 8 }, - { 26000000, 624000000, 624, 26, 0, 8 }, - { 12000000, 600000000, 600, 12, 0, 8 }, - { 13000000, 600000000, 600, 13, 0, 8 }, - { 16800000, 600000000, 500, 14, 0, 8 }, - { 19200000, 600000000, 375, 12, 0, 6 }, - { 26000000, 600000000, 600, 26, 0, 8 }, - { 12000000, 520000000, 520, 12, 0, 8 }, - { 13000000, 520000000, 520, 13, 0, 8 }, - { 16800000, 520000000, 495, 16, 0, 8 }, /* actual: 519.75 MHz */ - { 19200000, 520000000, 325, 12, 0, 6 }, - { 26000000, 520000000, 520, 26, 0, 8 }, - { 12000000, 416000000, 416, 12, 0, 8 }, - { 13000000, 416000000, 416, 13, 0, 8 }, - { 16800000, 416000000, 396, 16, 0, 8 }, /* actual: 415.8 MHz */ - { 19200000, 416000000, 260, 12, 0, 6 }, - { 26000000, 416000000, 416, 26, 0, 8 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 0, 8 }, - { 13000000, 666000000, 666, 13, 0, 8 }, - { 16800000, 666000000, 555, 14, 0, 8 }, - { 19200000, 666000000, 555, 16, 0, 8 }, - { 26000000, 666000000, 666, 26, 0, 8 }, - { 12000000, 600000000, 600, 12, 0, 8 }, - { 13000000, 600000000, 600, 13, 0, 8 }, - { 16800000, 600000000, 500, 14, 0, 8 }, - { 19200000, 600000000, 375, 12, 0, 6 }, - { 26000000, 600000000, 600, 26, 0, 8 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 1, 8 }, - { 13000000, 216000000, 432, 13, 1, 8 }, - { 16800000, 216000000, 360, 14, 1, 8 }, - { 19200000, 216000000, 360, 16, 1, 8 }, - { 26000000, 216000000, 432, 26, 1, 8 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 9600000, 564480000, 294, 5, 0, 4 }, - { 9600000, 552960000, 288, 5, 0, 4 }, - { 9600000, 24000000, 5, 2, 0, 1 }, - { 28800000, 56448000, 49, 25, 0, 1 }, - { 28800000, 73728000, 64, 25, 0, 1 }, - { 28800000, 24000000, 5, 6, 0, 1 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 0, 4 }, - { 13000000, 216000000, 216, 13, 0, 4 }, - { 16800000, 216000000, 180, 14, 0, 4 }, - { 19200000, 216000000, 180, 16, 0, 4 }, - { 26000000, 216000000, 216, 26, 0, 4 }, - { 12000000, 594000000, 594, 12, 0, 8 }, - { 13000000, 594000000, 594, 13, 0, 8 }, - { 16800000, 594000000, 495, 14, 0, 8 }, - { 19200000, 594000000, 495, 16, 0, 8 }, - { 26000000, 594000000, 594, 26, 0, 8 }, - { 12000000, 1000000000, 1000, 12, 0, 12 }, - { 13000000, 1000000000, 1000, 13, 0, 12 }, - { 19200000, 1000000000, 625, 12, 0, 8 }, - { 26000000, 1000000000, 1000, 26, 0, 12 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -339,66 +339,72 @@ static const struct pdiv_map pllu_p[] = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 12 }, - { 13000000, 480000000, 960, 13, 0, 12 }, - { 16800000, 480000000, 400, 7, 0, 5 }, - { 19200000, 480000000, 200, 4, 0, 3 }, - { 26000000, 480000000, 960, 26, 0, 12 }, + { 12000000, 480000000, 960, 12, 1, 12 }, + { 13000000, 480000000, 960, 13, 1, 12 }, + { 16800000, 480000000, 400, 7, 1, 5 }, + { 19200000, 480000000, 200, 4, 1, 3 }, + { 26000000, 480000000, 960, 26, 1, 12 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1.7 GHz */ - { 12000000, 1700000000, 850, 6, 0, 8 }, - { 13000000, 1700000000, 915, 7, 0, 8 }, /* actual: 1699.2 MHz */ - { 16800000, 1700000000, 708, 7, 0, 8 }, /* actual: 1699.2 MHz */ - { 19200000, 1700000000, 885, 10, 0, 8 }, /* actual: 1699.2 MHz */ - { 26000000, 1700000000, 850, 13, 0, 8 }, + { 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 }, /* 1.6 GHz */ - { 12000000, 1600000000, 800, 6, 0, 8 }, - { 13000000, 1600000000, 738, 6, 0, 8 }, /* actual: 1599.0 MHz */ - { 16800000, 1600000000, 857, 9, 0, 8 }, /* actual: 1599.7 MHz */ - { 19200000, 1600000000, 500, 6, 0, 8 }, - { 26000000, 1600000000, 800, 13, 0, 8 }, + { 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 }, /* 1.5 GHz */ - { 12000000, 1500000000, 750, 6, 0, 8 }, - { 13000000, 1500000000, 923, 8, 0, 8 }, /* actual: 1499.8 MHz */ - { 16800000, 1500000000, 625, 7, 0, 8 }, - { 19200000, 1500000000, 625, 8, 0, 8 }, - { 26000000, 1500000000, 750, 13, 0, 8 }, + { 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 }, /* 1.4 GHz */ - { 12000000, 1400000000, 700, 6, 0, 8 }, - { 13000000, 1400000000, 969, 9, 0, 8 }, /* actual: 1399.7 MHz */ - { 16800000, 1400000000, 1000, 12, 0, 8 }, - { 19200000, 1400000000, 875, 12, 0, 8 }, - { 26000000, 1400000000, 700, 13, 0, 8 }, + { 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 }, /* 1.3 GHz */ - { 12000000, 1300000000, 975, 9, 0, 8 }, - { 13000000, 1300000000, 1000, 10, 0, 8 }, - { 16800000, 1300000000, 928, 12, 0, 8 }, /* actual: 1299.2 MHz */ - { 19200000, 1300000000, 812, 12, 0, 8 }, /* actual: 1299.2 MHz */ - { 26000000, 1300000000, 650, 13, 0, 8 }, + { 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 }, /* 1.2 GHz */ - { 12000000, 1200000000, 1000, 10, 0, 8 }, - { 13000000, 1200000000, 923, 10, 0, 8 }, /* actual: 1199.9 MHz */ - { 16800000, 1200000000, 1000, 14, 0, 8 }, - { 19200000, 1200000000, 1000, 16, 0, 8 }, - { 26000000, 1200000000, 600, 13, 0, 8 }, + { 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 }, /* 1.1 GHz */ - { 12000000, 1100000000, 825, 9, 0, 8 }, - { 13000000, 1100000000, 846, 10, 0, 8 }, /* actual: 1099.8 MHz */ - { 16800000, 1100000000, 982, 15, 0, 8 }, /* actual: 1099.8 MHz */ - { 19200000, 1100000000, 859, 15, 0, 8 }, /* actual: 1099.5 MHz */ - { 26000000, 1100000000, 550, 13, 0, 8 }, + { 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 }, /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 0, 8 }, - { 13000000, 1000000000, 1000, 13, 0, 8 }, - { 16800000, 1000000000, 833, 14, 0, 8 }, /* actual: 999.6 MHz */ - { 19200000, 1000000000, 625, 12, 0, 8 }, - { 26000000, 1000000000, 1000, 26, 0, 8 }, + { 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 }, { 0, 0, 0, 0, 0, 0 }, }; +static const struct pdiv_map plle_p[] = { + { .pdiv = 18, .hw_val = 18 }, + { .pdiv = 24, .hw_val = 24 }, + { .pdiv = 0, .hw_val = 0 }, +}; + static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { /* PLLE special case: use cpcon field to store cml divider value */ { 12000000, 100000000, 150, 1, 18, 11 }, @@ -573,6 +579,7 @@ static struct tegra_clk_pll_params pll_e_params = { .lock_mask = PLLE_MISC_LOCK, .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, .lock_delay = 300, + .pdiv_tohw = plle_p, .freq_table = pll_e_freq_table, .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED | TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC, -- cgit v1.2.3 From 267b62a969511236e91121cd27f4cc1558385855 Mon Sep 17 00:00:00 2001 From: Danny Huang Date: Thu, 18 Jun 2015 17:28:27 -0400 Subject: clk: tegra: pll: Update PLLM handling PLLM is fixed for Tegra30 up through Tegra114. Starting with Tegra124 PLLM can change rate. Mark PLLM as TEGRA_PLL_FIXED for the generations where it should be. Modify the check in clk_pll_round_rate() and clk_pll_recalc_rate() to allow for the non-fixed version to return the correct rate. Note that there is no change for Tegra20. This is because PLLM is not distinguished in that driver, and adding either the PLLM or FIXED_RATE flags will cause potential problems. PLLM never supported dynamic ramping. On Tegra20 and Tegra30, there is no dynamic ramping at all, and on Tegra114, Tegra124 and Tegra132, only PLLX and PLLC support dynamic ramping, so we can go ahead and remove the specialized pllm_ops. Signed-off-by: Danny Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 56 +++++----------------------------------- drivers/clk/tegra/clk-tegra114.c | 3 ++- drivers/clk/tegra/clk-tegra30.c | 2 +- 3 files changed, 10 insertions(+), 51 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index b8b3fc6dc39b..7319de770e3a 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -726,12 +726,12 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; - if (pll->params->flags & TEGRA_PLL_FIXED) + if (pll->params->flags & TEGRA_PLL_FIXED) { + /* PLLM are used for memory; we do not change rate */ + if (pll->params->flags & TEGRA_PLLM) + return clk_hw_get_rate(hw); return pll->params->fixed_rate; - - /* PLLM is used for memory; we do not change rate */ - if (pll->params->flags & TEGRA_PLLM) - return clk_hw_get_rate(hw); + } if (_get_table_rate(hw, &cfg, rate, *prate) && pll->params->calc_rate(hw, &cfg, rate, *prate)) @@ -755,6 +755,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, return parent_rate; if ((pll->params->flags & TEGRA_PLL_FIXED) && + !(pll->params->flags & TEGRA_PLLM) && !(val & PLL_BASE_OVERRIDE)) { struct tegra_clk_pll_freq_table sel; if (_get_table_rate(hw, &sel, pll->params->fixed_rate, @@ -1093,40 +1094,6 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, return output_rate; } -static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct tegra_clk_pll_freq_table cfg; - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long flags = 0; - int state, ret = 0; - - if (pll->lock) - spin_lock_irqsave(pll->lock, flags); - - state = clk_pll_is_enabled(hw); - if (state) { - if (rate != clk_get_rate(hw->clk)) { - pr_err("%s: Cannot change active PLLM\n", __func__); - ret = -EINVAL; - goto out; - } - goto out; - } - - ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); - if (ret < 0) - goto out; - - _update_pll_mnp(pll, &cfg); - -out: - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); - - return ret; -} - static void _pllcx_strobe(struct tegra_clk_pll *pll) { u32 val; @@ -1598,15 +1565,6 @@ static const struct clk_ops tegra_clk_pllxc_ops = { .set_rate = clk_pllxc_set_rate, }; -static const struct clk_ops tegra_clk_pllm_ops = { - .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_enable, - .disable = clk_pll_disable, - .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_ramp_round_rate, - .set_rate = clk_pllm_set_rate, -}; - static const struct clk_ops tegra_clk_pllc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pllc_enable, @@ -1760,7 +1718,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, return ERR_CAST(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, - &tegra_clk_pllm_ops); + &tegra_clk_pll_ops); if (IS_ERR(clk)) kfree(pll); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9411a1577d85..4a24aa4bbdea 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -351,7 +351,8 @@ static struct tegra_clk_pll_params pll_m_params = { .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_FIXED, }; static struct div_nmp pllp_nmp = { diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 8493dd90f685..0478565cf292 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -460,7 +460,7 @@ static struct tegra_clk_pll_params pll_m_params = { .freq_table = pll_m_freq_table, .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK | - TEGRA_PLL_HAS_LOCK_ENABLE, + TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_FIXED, }; static struct tegra_clk_pll_params pll_p_params = { -- cgit v1.2.3 From dd322f047d226a1134775c77c1c6088271d5d1de Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:28 -0400 Subject: clk: tegra: pll: Add specialized logic for Tegra210 On Tegra210 SoC's, the logic to enable several of the plls is different from previous generations. Therefore, add registration functions specific to Tegra210 which will handle them appropriately. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 324 +++++++++++++++++++++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 24 ++++ 2 files changed, 346 insertions(+), 2 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 7319de770e3a..25a89ac28d2c 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -65,6 +65,7 @@ #define PLLE_BASE_DIVN_WIDTH 8 #define PLLE_BASE_DIVM_SHIFT 0 #define PLLE_BASE_DIVM_WIDTH 8 +#define PLLE_BASE_ENABLE BIT(31) #define PLLE_MISC_SETUP_BASE_SHIFT 16 #define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT) @@ -102,6 +103,7 @@ #define PLLE_AUX_SEQ_ENABLE BIT(24) #define PLLE_AUX_SEQ_START_STATE BIT(25) #define PLLE_AUX_PLLRE_SEL BIT(28) +#define PLLE_AUX_SS_SEQ_INCLUDE BIT(31) #define XUSBIO_PLL_CFG0 0x51c #define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0) @@ -967,7 +969,8 @@ static int _calc_dynamic_ramp_rate(struct clk_hw *hw, #if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ defined(CONFIG_ARCH_TEGRA_124_SOC) || \ - defined(CONFIG_ARCH_TEGRA_132_SOC) + defined(CONFIG_ARCH_TEGRA_132_SOC) || \ + defined(CONFIG_ARCH_TEGRA_210_SOC) u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate) { @@ -1555,7 +1558,8 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, #if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ defined(CONFIG_ARCH_TEGRA_124_SOC) || \ - defined(CONFIG_ARCH_TEGRA_132_SOC) + defined(CONFIG_ARCH_TEGRA_132_SOC) || \ + defined(CONFIG_ARCH_TEGRA_210_SOC) static const struct clk_ops tegra_clk_pllxc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_enable, @@ -1925,3 +1929,319 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, return clk; } #endif + +#if defined(CONFIG_ARCH_TEGRA_210_SOC) +static int clk_plle_tegra210_enable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct tegra_clk_pll_freq_table sel; + u32 val; + int ret; + unsigned long flags = 0; + unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); + + if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) + return -EINVAL; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + val = pll_readl_base(pll); + val &= ~BIT(30); /* Disable lock override */ + pll_writel_base(val, pll); + + val = pll_readl(pll->params->aux_reg, pll); + val |= PLLE_AUX_ENABLE_SWCTL; + val &= ~PLLE_AUX_SEQ_ENABLE; + pll_writel(val, pll->params->aux_reg, pll); + udelay(1); + + val = pll_readl_misc(pll); + val |= PLLE_MISC_LOCK_ENABLE; + val |= PLLE_MISC_IDDQ_SW_CTRL; + val &= ~PLLE_MISC_IDDQ_SW_VALUE; + val |= PLLE_MISC_PLLE_PTS; + val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK; + pll_writel_misc(val, pll); + udelay(5); + + val = pll_readl(PLLE_SS_CTRL, pll); + val |= PLLE_SS_DISABLE; + pll_writel(val, PLLE_SS_CTRL, pll); + + val = pll_readl_base(pll); + val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) | + divm_mask_shifted(pll)); + val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT); + val |= sel.m << divm_shift(pll); + val |= sel.n << divn_shift(pll); + val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; + pll_writel_base(val, pll); + udelay(1); + + val = pll_readl_base(pll); + val |= PLLE_BASE_ENABLE; + pll_writel_base(val, pll); + + ret = clk_pll_wait_for_lock(pll); + + if (ret < 0) + goto out; + + val = pll_readl(PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); + val &= ~PLLE_SS_COEFFICIENTS_MASK; + val |= PLLE_SS_COEFFICIENTS_VAL; + pll_writel(val, PLLE_SS_CTRL, pll); + val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + val &= ~PLLE_SS_CNTL_INTERP_RESET; + pll_writel(val, PLLE_SS_CTRL, pll); + udelay(1); + + val = pll_readl_misc(pll); + val &= ~PLLE_MISC_IDDQ_SW_CTRL; + pll_writel_misc(val, pll); + + val = pll_readl(pll->params->aux_reg, pll); + val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SS_SEQ_INCLUDE); + val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL); + pll_writel(val, pll->params->aux_reg, pll); + udelay(1); + val |= PLLE_AUX_SEQ_ENABLE; + pll_writel(val, pll->params->aux_reg, pll); + +out: + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static void clk_plle_tegra210_disable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + u32 val; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + val = pll_readl_base(pll); + val &= ~PLLE_BASE_ENABLE; + pll_writel_base(val, pll); + + val = pll_readl_misc(pll); + val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE; + pll_writel_misc(val, pll); + udelay(1); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + +static int clk_plle_tegra210_is_enabled(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + u32 val; + + val = pll_readl_base(pll); + + return val & PLLE_BASE_ENABLE ? 1 : 0; +} + +static const struct clk_ops tegra_clk_plle_tegra210_ops = { + .is_enabled = clk_plle_tegra210_is_enabled, + .enable = clk_plle_tegra210_enable, + .disable = clk_plle_tegra210_disable, + .recalc_rate = clk_pll_recalc_rate, +}; + +struct clk *tegra_clk_register_plle_tegra210(const char *name, + const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk; + u32 val, val_aux; + + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + /* ensure parent is set to pll_re_vco */ + + val = pll_readl_base(pll); + val_aux = pll_readl(pll_params->aux_reg, pll); + + if (val & PLLE_BASE_ENABLE) { + if ((val_aux & PLLE_AUX_PLLRE_SEL) || + (val_aux & PLLE_AUX_PLLP_SEL)) + WARN(1, "pll_e enabled with unsupported parent %s\n", + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : + "pll_re_vco"); + } else { + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); + pll_writel(val_aux, pll_params->aux_reg, pll); + } + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_plle_tegra210_ops); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} + +struct clk *tegra_clk_register_pllc_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + void __iomem *pmc, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct clk *parent, *clk; + const struct pdiv_map *p_tohw = pll_params->pdiv_tohw; + struct tegra_clk_pll *pll; + unsigned long parent_rate; + + if (!p_tohw) + return ERR_PTR(-EINVAL); + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + parent_rate = clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll_params->flags |= TEGRA_PLL_BYPASS; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pll_ops); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} + +struct clk *tegra_clk_register_pllxc_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + void __iomem *pmc, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk, *parent; + unsigned long parent_rate; + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + if (!pll_params->pdiv_tohw) + return ERR_PTR(-EINVAL); + + parent_rate = clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pll_ops); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} + +struct clk *tegra_clk_register_pllss_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk, *parent; + struct tegra_clk_pll_freq_table cfg; + unsigned long parent_rate; + u32 val; + int i; + + if (!pll_params->div_nmp) + return ERR_PTR(-EINVAL); + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + name, parent_name); + return ERR_PTR(-EINVAL); + } + + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + val = pll_readl_base(pll); + val &= ~PLLSS_REF_SRC_SEL_MASK; + pll_writel_base(val, pll); + + parent_rate = clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + /* initialize PLL to minimum rate */ + + cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); + cfg.n = cfg.m * pll_params->vco_min / parent_rate; + + for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) + ; + if (!i) { + kfree(pll); + return ERR_PTR(-EINVAL); + } + + cfg.p = pll_params->pdiv_tohw[i-1].hw_val; + + _update_pll_mnp(pll, &cfg); + + pll_writel_misc(PLLSS_MISC_DEFAULT, pll); + + val = pll_readl_base(pll); + if (val & PLL_BASE_ENABLE) { + if (val & BIT(pll_params->iddq_bit_idx)) { + WARN(1, "%s is on but IDDQ set\n", name); + kfree(pll); + return ERR_PTR(-EINVAL); + } + } else + val |= BIT(pll_params->iddq_bit_idx); + + val &= ~PLLSS_LOCK_OVERRIDE; + pll_writel_base(val, pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pll_ops); + + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} +#endif diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index adf2e8ead335..97a5d712fe41 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -334,6 +334,12 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, struct tegra_clk_pll_params *pll_params, spinlock_t *lock); +struct clk *tegra_clk_register_pllxc_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + void __iomem *pmc, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, @@ -358,6 +364,24 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, struct tegra_clk_pll_params *pll_params, spinlock_t *lock); +struct clk *tegra_clk_register_plle_tegra210(const char *name, + const char *parent_name, + void __iomem *clk_base, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + +struct clk *tegra_clk_register_pllc_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + void __iomem *pmc, unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + +struct clk *tegra_clk_register_pllss_tegra210(const char *name, + const char *parent_name, void __iomem *clk_base, + unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, void __iomem *clk_base, unsigned long flags, struct tegra_clk_pll_params *pll_params, -- cgit v1.2.3 From 6929715cf6b944d8f88beb2aa25658084de106ab Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:29 -0400 Subject: clk: tegra: pll: Add support for PLLMB for Tegra210 Tegra210 SoC's have 2 PLLs for memory usage. Add plumbing to register and handle PLLMB. PLLMB is used to allow switching between 2 PLLM's without having to use and intermediate backup PLL, as we need to lock the PLL before we can switch to it. Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 48 ++++++++++++++++++++++++++++++++++++++++----- drivers/clk/tegra/clk.h | 9 +++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 25a89ac28d2c..420ca8284a1d 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -571,7 +571,7 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((params->flags & TEGRA_PLLM) && + if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -608,7 +608,7 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, struct tegra_clk_pll_params *params = pll->params; struct div_nmp *div_nmp = params->div_nmp; - if ((params->flags & TEGRA_PLLM) && + if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { val = pll_override_readl(params->pmc_divp_reg, pll); @@ -729,8 +729,8 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct tegra_clk_pll_freq_table cfg; if (pll->params->flags & TEGRA_PLL_FIXED) { - /* PLLM are used for memory; we do not change rate */ - if (pll->params->flags & TEGRA_PLLM) + /* PLLM/MB are used for memory; we do not change rate */ + if (pll->params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) return clk_hw_get_rate(hw); return pll->params->fixed_rate; } @@ -757,7 +757,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, return parent_rate; if ((pll->params->flags & TEGRA_PLL_FIXED) && - !(pll->params->flags & TEGRA_PLLM) && + !(pll->params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && !(val & PLL_BASE_OVERRIDE)) { struct tegra_clk_pll_freq_table sel; if (_get_table_rate(hw, &sel, pll->params->fixed_rate, @@ -2244,4 +2244,42 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, return clk; } + +struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock) +{ + struct tegra_clk_pll *pll; + struct clk *clk, *parent; + unsigned long parent_rate; + + if (!pll_params->pdiv_tohw) + return ERR_PTR(-EINVAL); + + parent = __clk_lookup(parent_name); + if (!parent) { + WARN(1, "parent clk %s of %s must be registered first\n", + parent_name, name); + return ERR_PTR(-EINVAL); + } + + parent_rate = clk_get_rate(parent); + + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + + pll_params->flags |= TEGRA_PLL_BYPASS; + pll_params->flags |= TEGRA_PLLMB; + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); + if (IS_ERR(pll)) + return ERR_CAST(pll); + + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, + &tegra_clk_pll_ops); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} #endif diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 97a5d712fe41..8724dc245f68 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -225,6 +225,8 @@ struct div_nmp { * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring * TEGRA_MDIV_NEW - Switch to new method for calculating fixed mdiv * it may be more accurate (especially if SDM present) + * TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This + * flag indicated that it is PLLMB. */ struct tegra_clk_pll_params { unsigned long input_min; @@ -281,6 +283,7 @@ struct tegra_clk_pll_params { #define TEGRA_PLL_BYPASS BIT(9) #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) #define TEGRA_MDIV_NEW BIT(11) +#define TEGRA_PLLMB BIT(12) /** * struct tegra_clk_pll - Tegra PLL clock @@ -387,6 +390,12 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, struct tegra_clk_pll_params *pll_params, spinlock_t *lock); +struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, + struct tegra_clk_pll_params *pll_params, + spinlock_t *lock); + /** * struct tegra_clk_pll_out - PLL divider down clock * -- cgit v1.2.3 From b5512b45d5ed699de328e17cd7c7027d89461920 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:30 -0400 Subject: clk: tegra: pll: Adjust vco_min if SDM present This code makes use of the SDM fractional divider if present to constrain the allowable programming range of the PLL divider register bitfields to take advantage of higher frequency granularity that can be induced by the SDM divider. Based on original work by Aleksandr Frid Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 28 ++++++++++++++++++++++++++++ drivers/clk/tegra/clk.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 420ca8284a1d..66da418c8528 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1621,6 +1621,10 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); if (err) return ERR_PTR(err); @@ -1659,6 +1663,10 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -1715,6 +1723,10 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + pll_params->flags |= TEGRA_PLL_BYPASS; pll_params->flags |= TEGRA_PLLM; pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); @@ -2121,6 +2133,10 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + pll_params->flags |= TEGRA_PLL_BYPASS; pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) @@ -2158,6 +2174,10 @@ struct clk *tegra_clk_register_pllxc_tegra210(const char *name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); @@ -2205,6 +2225,10 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + /* initialize PLL to minimum rate */ cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); @@ -2269,6 +2293,10 @@ struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name, pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); + if (pll_params->adjust_vco) + pll_params->vco_min = pll_params->adjust_vco(pll_params, + parent_rate); + pll_params->flags |= TEGRA_PLL_BYPASS; pll_params->flags |= TEGRA_PLLMB; pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 8724dc245f68..f94b1789c333 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -202,6 +202,8 @@ struct div_nmp { * PLL's based on fractional divider value. * @calc_rate: Callback used to change how out of table * rates (dividers and multipler) are calculated. + * @adjust_vco: Callback to adjust the programming range of the + * divider range (if SDM is present) * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -269,6 +271,8 @@ struct tegra_clk_pll_params { int (*calc_rate)(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate, unsigned long parent_rate); + unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params, + unsigned long parent_rate); }; #define TEGRA_PLL_USE_LOCK BIT(0) -- cgit v1.2.3 From b985114e2f946de069b00002bd46a4efba5334eb Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:31 -0400 Subject: clk: tegra: pll: Add Set_default logic Add logic which (if specified for a pll) can verify that a PLL is set to the proper default value and if not can set it. This can be specified per PLL as each will have different default values. Based on original work by Aleksandr Frid Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 39 ++++++++++++++++++++++++++++----------- drivers/clk/tegra/clk.h | 11 +++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 66da418c8528..1decca98008f 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -662,13 +662,19 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate) { struct tegra_clk_pll *pll = to_clk_pll(hw); + struct tegra_clk_pll_freq_table old_cfg; int state, ret = 0; state = clk_pll_is_enabled(hw); + _get_pll_mnp(pll, &old_cfg); + if (state) _clk_pll_disable(hw); + if (!pll->params->defaults_set && pll->params->set_defaults) + pll->params->set_defaults(pll); + _update_pll_mnp(pll, cfg); if (pll->params->flags & TEGRA_PLL_HAS_CPCON) @@ -1494,6 +1500,9 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, pll->params->calc_rate = _calc_rate; } + if (pll->params->set_defaults) + pll->params->set_defaults(pll); + /* Data in .init is copied by clk_register(), so stack variable OK */ pll->hw.init = &init; @@ -1604,7 +1613,6 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, struct tegra_clk_pll *pll; struct clk *clk, *parent; unsigned long parent_rate; - int err; u32 val, val_iddq; parent = __clk_lookup(parent_name); @@ -1625,18 +1633,27 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, pll_params->vco_min = pll_params->adjust_vco(pll_params, parent_rate); - err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); - if (err) - return ERR_PTR(err); + /* + * If the pll has a set_defaults callback, it will take care of + * configuring dynamic ramping and setting IDDQ in that path. + */ + if (!pll_params->set_defaults) { + int err; + + err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); + if (err) + return ERR_PTR(err); - val = readl_relaxed(clk_base + pll_params->base_reg); - val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); + val = readl_relaxed(clk_base + pll_params->base_reg); + val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); - if (val & PLL_BASE_ENABLE) - WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); - else { - val_iddq |= BIT(pll_params->iddq_bit_idx); - writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); + if (val & PLL_BASE_ENABLE) + WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); + else { + val_iddq |= BIT(pll_params->iddq_bit_idx); + writel_relaxed(val_iddq, + clk_base + pll_params->iddq_reg); + } } pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index f94b1789c333..c78d9d088a6d 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -160,6 +160,8 @@ struct div_nmp { #define MAX_PLL_MISC_REG_COUNT 6 +struct tegra_clk_pll; + /** * struct tegra_clk_pll_params - PLL parameters * @@ -192,6 +194,7 @@ struct div_nmp { * @stepb_shift: Dynamic ramp step B field shift * @lock_delay: Delay in us if PLL lock is not used * @max_p: maximum value for the p divider + * @defaults_set: Boolean signaling all reg defaults for PLL set. * @pdiv_tohw: mapping of p divider to register values * @div_nmp: offsets and widths on n, m and p fields * @freq_table: array of frequencies supported by PLL @@ -204,6 +207,12 @@ struct div_nmp { * rates (dividers and multipler) are calculated. * @adjust_vco: Callback to adjust the programming range of the * divider range (if SDM is present) + * @set_defaults: Callback which will try to initialize PLL + * registers to sane default values. This is first + * tried during PLL registration, but if the PLL + * is already enabled, it will be done the first + * time the rate is changed while the PLL is + * disabled. * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -261,6 +270,7 @@ struct tegra_clk_pll_params { int stepb_shift; int lock_delay; int max_p; + bool defaults_set; const struct pdiv_map *pdiv_tohw; struct div_nmp *div_nmp; struct tegra_clk_pll_freq_table *freq_table; @@ -273,6 +283,7 @@ struct tegra_clk_pll_params { unsigned long rate, unsigned long parent_rate); unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate); + void (*set_defaults)(struct tegra_clk_pll *pll); }; #define TEGRA_PLL_USE_LOCK BIT(0) -- cgit v1.2.3 From 17e9273a9e00a1fc8a64d6de3c7bb9e5020b1b73 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:32 -0400 Subject: clk: tegra: pll: Add dyn_ramp callback Add a callback to the pll_params for custom dynamic ramping functions which can be specified per PLL. Reviewed-by: Benson Leung Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 7 +++++++ drivers/clk/tegra/clk.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 1decca98008f..8901004025e7 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -669,6 +669,13 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, _get_pll_mnp(pll, &old_cfg); + if (state && pll->params->defaults_set && pll->params->dyn_ramp && + (cfg->m == old_cfg.m) && (cfg->p == old_cfg.p)) { + ret = pll->params->dyn_ramp(pll, cfg); + if (!ret) + return 0; + } + if (state) _clk_pll_disable(hw); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index c78d9d088a6d..8dac213fa672 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -213,6 +213,8 @@ struct tegra_clk_pll; * is already enabled, it will be done the first * time the rate is changed while the PLL is * disabled. + * @dyn_ramp: Callback which can be used to define a custom + * dynamic ramp function for a given PLL. * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -284,6 +286,8 @@ struct tegra_clk_pll_params { unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params, unsigned long parent_rate); void (*set_defaults)(struct tegra_clk_pll *pll); + int (*dyn_ramp)(struct tegra_clk_pll *pll, + struct tegra_clk_pll_freq_table *cfg); }; #define TEGRA_PLL_USE_LOCK BIT(0) -- cgit v1.2.3 From 0ef9db6cf24dbb58118818e64198d9a030e4697e Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:33 -0400 Subject: clk: tegra: pll: Add logic for SS Add some logic for Spread Spectrum control. It is used in conjuncture with SDM fractional dividers. SSC has to be disabled when we configure the divider settings. Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 25 ++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 4 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 8901004025e7..7ef08861c35d 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -658,6 +658,26 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, pll_writel_misc(val, pll); } +static void pll_clk_start_ss(struct tegra_clk_pll *pll) +{ + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); + + val |= pll->params->ssc_ctrl_en_mask; + pll_writel(val, pll->params->ssc_ctrl_reg, pll); + } +} + +static void pll_clk_stop_ss(struct tegra_clk_pll *pll) +{ + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); + + val &= ~pll->params->ssc_ctrl_en_mask; + pll_writel(val, pll->params->ssc_ctrl_reg, pll); + } +} + static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate) { @@ -676,8 +696,10 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, return 0; } - if (state) + if (state) { + pll_clk_stop_ss(pll); _clk_pll_disable(hw); + } if (!pll->params->defaults_set && pll->params->set_defaults) pll->params->set_defaults(pll); @@ -690,6 +712,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, if (state) { _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); + pll_clk_start_ss(pll); } return ret; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 8dac213fa672..4883507c59dc 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -184,6 +184,8 @@ struct tegra_clk_pll; * @sdm_din_mask: Mask of SDM divider bits * @sdm_ctrl_reg: Register offset where SDM enable is * @sdm_ctrl_en_mask: Mask of SDM enable bit + * @ssc_ctrl_reg: Register offset where SSC settings are + * @ssc_ctrl_en_mask: Mask of SSC enable bit * @aux_reg: AUX register offset * @dyn_ramp_reg: Dynamic ramp control register offset * @ext_misc_reg: Miscellaneous control register offsets @@ -262,6 +264,8 @@ struct tegra_clk_pll_params { u32 sdm_din_mask; u32 sdm_ctrl_reg; u32 sdm_ctrl_en_mask; + u32 ssc_ctrl_reg; + u32 ssc_ctrl_en_mask; u32 aux_reg; u32 dyn_ramp_reg; u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT]; -- cgit v1.2.3 From 139fd30943c3c8ed76d0ce08ff711cfff3b118ec Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:35 -0400 Subject: clk: tegra: Add Super Gen5 Logic Super clock divider control and clock source mux of Tegra210 has changed a little against prior SoCs, this patch adds Gen5 logic to address those differences. Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra-super-gen4.c | 142 ++++++++++++++++++++++++++++--- drivers/clk/tegra/clk.h | 3 + 2 files changed, 132 insertions(+), 13 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index 5b1d723932c5..4559a20e3af6 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -34,9 +34,25 @@ #define CCLKLP_BURST_POLICY 0x370 #define SCLK_BURST_POLICY 0x028 #define SYSTEM_CLK_RATE 0x030 +#define SCLK_DIVIDER 0x2c static DEFINE_SPINLOCK(sysrate_lock); +enum tegra_super_gen { + gen4 = 4, + gen5, +}; + +struct tegra_super_gen_info { + enum tegra_super_gen gen; + const char **sclk_parents; + const char **cclk_g_parents; + const char **cclk_lp_parents; + int num_sclk_parents; + int num_cclk_g_parents; + int num_cclk_lp_parents; +}; + static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", "pll_p", "pll_p_out2", "unused", "clk_32k", "pll_m_out1" }; @@ -51,21 +67,81 @@ static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", "pll_p", "pll_p_out4", "unused", "unused", "pll_x", "pll_x_out0" }; +const struct tegra_super_gen_info tegra_super_gen_info_gen4 = { + .gen = gen4, + .sclk_parents = sclk_parents, + .cclk_g_parents = cclk_g_parents, + .cclk_lp_parents = cclk_lp_parents, + .num_sclk_parents = ARRAY_SIZE(sclk_parents), + .num_cclk_g_parents = ARRAY_SIZE(cclk_g_parents), + .num_cclk_lp_parents = ARRAY_SIZE(cclk_lp_parents), +}; + +static const char *sclk_parents_gen5[] = { "clk_m", "pll_c_out1", "pll_c4_out3", + "pll_p", "pll_p_out2", "pll_c4_out1", + "clk_32k", "pll_c4_out2" }; + +static const char *cclk_g_parents_gen5[] = { "clk_m", "unused", "clk_32k", "unused", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x", "unused", "unused", + "unused", "unused", "unused", "unused", + "dfllCPU_out" }; + +static const char *cclk_lp_parents_gen5[] = { "clk_m", "unused", "clk_32k", "unused", + "pll_p", "pll_p_out4", "unused", + "unused", "pll_x", "unused", "unused", + "unused", "unused", "unused", "unused", + "dfllCPU_out" }; + +const struct tegra_super_gen_info tegra_super_gen_info_gen5 = { + .gen = gen5, + .sclk_parents = sclk_parents_gen5, + .cclk_g_parents = cclk_g_parents_gen5, + .cclk_lp_parents = cclk_lp_parents_gen5, + .num_sclk_parents = ARRAY_SIZE(sclk_parents_gen5), + .num_cclk_g_parents = ARRAY_SIZE(cclk_g_parents_gen5), + .num_cclk_lp_parents = ARRAY_SIZE(cclk_lp_parents_gen5), +}; + static void __init tegra_sclk_init(void __iomem *clk_base, - struct tegra_clk *tegra_clks) + struct tegra_clk *tegra_clks, + const struct tegra_super_gen_info *gen_info) { struct clk *clk; struct clk **dt_clk; - /* SCLK */ - dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); + /* SCLK_MUX */ + dt_clk = tegra_lookup_dt_id(tegra_clk_sclk_mux, tegra_clks); if (dt_clk) { - clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), + clk = tegra_clk_register_super_mux("sclk_mux", + gen_info->sclk_parents, + gen_info->num_sclk_parents, CLK_SET_RATE_PARENT, clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); *dt_clk = clk; + + + /* SCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); + if (dt_clk) { + clk = clk_register_divider(NULL, "sclk", "sclk_mux", 0, + clk_base + SCLK_DIVIDER, 0, 8, + 0, &sysrate_lock); + *dt_clk = clk; + } + } else { + /* SCLK */ + dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); + if (dt_clk) { + clk = tegra_clk_register_super_mux("sclk", + gen_info->sclk_parents, + gen_info->num_sclk_parents, + CLK_SET_RATE_PARENT, + clk_base + SCLK_BURST_POLICY, + 0, 4, 0, 0, NULL); + *dt_clk = clk; + } } /* HCLK */ @@ -95,10 +171,11 @@ static void __init tegra_sclk_init(void __iomem *clk_base, *dt_clk = clk; } -void __init tegra_super_clk_gen4_init(void __iomem *clk_base, +void __init tegra_super_clk_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, - struct tegra_clk_pll_params *params) + struct tegra_clk_pll_params *params, + const struct tegra_super_gen_info *gen_info) { struct clk *clk; struct clk **dt_clk; @@ -106,28 +183,50 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base, /* CCLKG */ dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks); if (dt_clk) { - clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, - ARRAY_SIZE(cclk_g_parents), + if (gen_info->gen == gen5) { + clk = tegra_clk_register_super_mux("cclk_g", + gen_info->cclk_g_parents, + gen_info->num_cclk_g_parents, + CLK_SET_RATE_PARENT, + clk_base + CCLKG_BURST_POLICY, + 0, 4, 8, 0, NULL); + } else { + clk = tegra_clk_register_super_mux("cclk_g", + gen_info->cclk_g_parents, + gen_info->num_cclk_g_parents, CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, 0, 4, 0, 0, NULL); + } *dt_clk = clk; } /* CCLKLP */ dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); if (dt_clk) { - clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, - ARRAY_SIZE(cclk_lp_parents), + if (gen_info->gen == gen5) { + clk = tegra_clk_register_super_mux("cclk_lp", + gen_info->cclk_lp_parents, + gen_info->num_cclk_lp_parents, + CLK_SET_RATE_PARENT, + clk_base + CCLKLP_BURST_POLICY, + 0, 4, 8, 0, NULL); + } else { + clk = tegra_clk_register_super_mux("cclk_lp", + gen_info->cclk_lp_parents, + gen_info->num_cclk_lp_parents, CLK_SET_RATE_PARENT, clk_base + CCLKLP_BURST_POLICY, TEGRA_DIVIDER_2, 4, 8, 9, NULL); + } *dt_clk = clk; } - tegra_sclk_init(clk_base, tegra_clks); + tegra_sclk_init(clk_base, tegra_clks, gen_info); -#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) +#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ + defined(CONFIG_ARCH_TEGRA_210_SOC) /* PLLX */ dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks); if (!dt_clk) @@ -148,3 +247,20 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base, #endif } +void __init tegra_super_clk_gen4_init(void __iomem *clk_base, + void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *params) +{ + tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params, + &tegra_super_gen_info_gen4); +} + +void __init tegra_super_clk_gen5_init(void __iomem *clk_base, + void __iomem *pmc_base, + struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *params) +{ + tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params, + &tegra_super_gen_info_gen5); +} diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 4883507c59dc..cb9670ee22a6 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -740,6 +740,9 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, void tegra_super_clk_gen4_init(void __iomem *clk_base, void __iomem *pmc_base, struct tegra_clk *tegra_clks, struct tegra_clk_pll_params *pll_params); +void tegra_super_clk_gen5_init(void __iomem *clk_base, + void __iomem *pmc_base, struct tegra_clk *tegra_clks, + struct tegra_clk_pll_params *pll_params); #ifdef CONFIG_TEGRA_CLK_EMC struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, -- cgit v1.2.3 From 6b301a059eb2ebed1b12a900e3b21a38e48dd410 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Thu, 18 Jun 2015 17:28:36 -0400 Subject: clk: tegra: Add support for Tegra210 clocks Implement clock support for Tegra210. Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-id.h | 7 + drivers/clk/tegra/clk-pll.c | 5 + drivers/clk/tegra/clk-tegra210.c | 2852 ++++++++++++++++++++++++++++++++++++++ drivers/clk/tegra/clk.h | 3 + 5 files changed, 2868 insertions(+) create mode 100644 drivers/clk/tegra/clk-tegra210.c diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 826c325dc2e8..97984c503bbb 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124-dfll-fcpu.o obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o obj-y += cvb.o +obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index e0ea78792983..19ce0738ee76 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -152,6 +152,10 @@ enum clk_id { tegra_clk_pll_c2, tegra_clk_pll_c3, tegra_clk_pll_c4, + tegra_clk_pll_c4_out0, + tegra_clk_pll_c4_out1, + tegra_clk_pll_c4_out2, + tegra_clk_pll_c4_out3, tegra_clk_pll_c_out1, tegra_clk_pll_d, tegra_clk_pll_d2, @@ -179,6 +183,9 @@ enum clk_id { tegra_clk_pll_re_out, tegra_clk_pll_re_vco, tegra_clk_pll_u, + tegra_clk_pll_u_out, + tegra_clk_pll_u_out1, + tegra_clk_pll_u_out2, tegra_clk_pll_u_12m, tegra_clk_pll_u_480m, tegra_clk_pll_u_48m, diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 7ef08861c35d..d00e3289eb79 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -414,6 +414,11 @@ static int _p_div_to_hw(struct clk_hw *hw, u8 p_div) return -EINVAL; } +int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div) +{ + return _p_div_to_hw(&pll->hw, p_div); +} + static int _hw_to_p_div(struct clk_hw *hw, u8 p_div_hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c new file mode 100644 index 000000000000..58514c44ea83 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra210.c @@ -0,0 +1,2852 @@ +/* + * Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-id.h" + +/* + * TEGRA210_CAR_BANK_COUNT: the number of peripheral clock register + * banks present in the Tegra210 CAR IP block. The banks are + * identified by single letters, e.g.: L, H, U, V, W, X, Y. See + * periph_regs[] in drivers/clk/tegra/clk.c + */ +#define TEGRA210_CAR_BANK_COUNT 7 + +#define CLK_SOURCE_CSITE 0x1d4 +#define CLK_SOURCE_EMC 0x19c + +#define PLLC_BASE 0x80 +#define PLLC_OUT 0x84 +#define PLLC_MISC0 0x88 +#define PLLC_MISC1 0x8c +#define PLLC_MISC2 0x5d0 +#define PLLC_MISC3 0x5d4 + +#define PLLC2_BASE 0x4e8 +#define PLLC2_MISC0 0x4ec +#define PLLC2_MISC1 0x4f0 +#define PLLC2_MISC2 0x4f4 +#define PLLC2_MISC3 0x4f8 + +#define PLLC3_BASE 0x4fc +#define PLLC3_MISC0 0x500 +#define PLLC3_MISC1 0x504 +#define PLLC3_MISC2 0x508 +#define PLLC3_MISC3 0x50c + +#define PLLM_BASE 0x90 +#define PLLM_MISC0 0x9c +#define PLLM_MISC1 0x98 +#define PLLP_BASE 0xa0 +#define PLLP_MISC0 0xac +#define PLLP_MISC1 0x680 +#define PLLA_BASE 0xb0 +#define PLLA_MISC0 0xbc +#define PLLA_MISC1 0xb8 +#define PLLA_MISC2 0x5d8 +#define PLLD_BASE 0xd0 +#define PLLD_MISC0 0xdc +#define PLLD_MISC1 0xd8 +#define PLLU_BASE 0xc0 +#define PLLU_OUTA 0xc4 +#define PLLU_MISC0 0xcc +#define PLLU_MISC1 0xc8 +#define PLLX_BASE 0xe0 +#define PLLX_MISC0 0xe4 +#define PLLX_MISC1 0x510 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 +#define PLLX_MISC4 0x5f0 +#define PLLX_MISC5 0x5f4 +#define PLLE_BASE 0xe8 +#define PLLE_MISC0 0xec +#define PLLD2_BASE 0x4b8 +#define PLLD2_MISC0 0x4bc +#define PLLD2_MISC1 0x570 +#define PLLD2_MISC2 0x574 +#define PLLD2_MISC3 0x578 +#define PLLE_AUX 0x48c +#define PLLRE_BASE 0x4c4 +#define PLLRE_MISC0 0x4c8 +#define PLLDP_BASE 0x590 +#define PLLDP_MISC 0x594 + +#define PLLC4_BASE 0x5a4 +#define PLLC4_MISC0 0x5a8 +#define PLLC4_OUT 0x5e4 +#define PLLMB_BASE 0x5e8 +#define PLLMB_MISC0 0x5ec +#define PLLA1_BASE 0x6a4 +#define PLLA1_MISC0 0x6a8 +#define PLLA1_MISC1 0x6ac +#define PLLA1_MISC2 0x6b0 +#define PLLA1_MISC3 0x6b4 + +#define PLLU_IDDQ_BIT 31 +#define PLLCX_IDDQ_BIT 27 +#define PLLRE_IDDQ_BIT 24 +#define PLLA_IDDQ_BIT 25 +#define PLLD_IDDQ_BIT 20 +#define PLLSS_IDDQ_BIT 18 +#define PLLM_IDDQ_BIT 5 +#define PLLMB_IDDQ_BIT 17 +#define PLLXP_IDDQ_BIT 3 + +#define PLLCX_RESET_BIT 30 + +#define PLL_BASE_LOCK BIT(27) +#define PLLCX_BASE_LOCK BIT(26) +#define PLLE_MISC_LOCK BIT(11) +#define PLLRE_MISC_LOCK BIT(27) + +#define PLL_MISC_LOCK_ENABLE 18 +#define PLLC_MISC_LOCK_ENABLE 24 +#define PLLDU_MISC_LOCK_ENABLE 22 +#define PLLU_MISC_LOCK_ENABLE 29 +#define PLLE_MISC_LOCK_ENABLE 9 +#define PLLRE_MISC_LOCK_ENABLE 30 +#define PLLSS_MISC_LOCK_ENABLE 30 +#define PLLP_MISC_LOCK_ENABLE 18 +#define PLLM_MISC_LOCK_ENABLE 4 +#define PLLMB_MISC_LOCK_ENABLE 16 +#define PLLA_MISC_LOCK_ENABLE 28 +#define PLLU_MISC_LOCK_ENABLE 29 +#define PLLD_MISC_LOCK_ENABLE 18 + +#define PLLA_SDM_DIN_MASK 0xffff +#define PLLA_SDM_EN_MASK BIT(26) + +#define PLLD_SDM_EN_MASK BIT(16) + +#define PLLD2_SDM_EN_MASK BIT(31) +#define PLLD2_SSC_EN_MASK BIT(30) + +#define PLLDP_SS_CFG 0x598 +#define PLLDP_SDM_EN_MASK BIT(31) +#define PLLDP_SSC_EN_MASK BIT(30) +#define PLLDP_SS_CTRL1 0x59c +#define PLLDP_SS_CTRL2 0x5a0 + +#define PMC_PLLM_WB0_OVERRIDE 0x1dc +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 + +#define UTMIP_PLL_CFG2 0x488 +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6) +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERUP BIT(1) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERUP BIT(3) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERUP BIT(5) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERDOWN BIT(24) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERUP BIT(25) + +#define UTMIP_PLL_CFG1 0x484 +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) + +#define UTMIPLL_HW_PWRDN_CFG0 0x52c +#define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE BIT(7) +#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4) +#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) + +#define PLLU_HW_PWRDN_CFG0 0x530 +#define PLLU_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE BIT(28) +#define PLLU_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) +#define PLLU_HW_PWRDN_CFG0_USE_SWITCH_DETECT BIT(7) +#define PLLU_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) +#define PLLU_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) +#define PLLU_HW_PWRDN_CFG0_CLK_SWITCH_SWCTL BIT(0) + +#define XUSB_PLL_CFG0 0x534 +#define XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY 0x3ff +#define XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK (0x3ff << 14) + +#define SPARE_REG0 0x55c +#define CLK_M_DIVISOR_SHIFT 2 +#define CLK_M_DIVISOR_MASK 0x3 + +/* + * SDM fractional divisor is 16-bit 2's complement signed number within + * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned + * 16-bit value, with "0" divisor mapped to 0xFFFF. Data "0" is used to + * indicate that SDM is disabled. + * + * Effective ndiv value when SDM is enabled: ndiv + 1/2 + sdm_din/2^13 + */ +#define PLL_SDM_COEFF BIT(13) +#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) +#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) + +/* Tegra CPU clock and reset control regs */ +#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 + +#ifdef CONFIG_PM_SLEEP +static struct cpu_clk_suspend_context { + u32 clk_csite_src; +} tegra210_cpu_clk_sctx; +#endif + +static void __iomem *clk_base; +static void __iomem *pmc_base; + +static unsigned long osc_freq; +static unsigned long pll_ref_freq; + +static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_e_lock); +static DEFINE_SPINLOCK(pll_re_lock); +static DEFINE_SPINLOCK(pll_u_lock); +static DEFINE_SPINLOCK(emc_lock); + +/* possible OSC frequencies in Hz */ +static unsigned long tegra210_input_freq[] = { + [5] = 38400000, + [8] = 12000000, +}; + +static const char *mux_pllmcp_clkm[] = { + "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3", +}; +#define mux_pllmcp_clkm_idx NULL + +#define PLL_ENABLE (1 << 30) + +#define PLLCX_MISC1_IDDQ (1 << 27) +#define PLLCX_MISC0_RESET (1 << 30) + +#define PLLCX_MISC0_DEFAULT_VALUE 0x40080000 +#define PLLCX_MISC0_WRITE_MASK 0x400ffffb +#define PLLCX_MISC1_DEFAULT_VALUE 0x08000000 +#define PLLCX_MISC1_WRITE_MASK 0x08003cff +#define PLLCX_MISC2_DEFAULT_VALUE 0x1f720f05 +#define PLLCX_MISC2_WRITE_MASK 0xffffff17 +#define PLLCX_MISC3_DEFAULT_VALUE 0x000000c4 +#define PLLCX_MISC3_WRITE_MASK 0x00ffffff + +/* PLLA */ +#define PLLA_BASE_IDDQ (1 << 25) +#define PLLA_BASE_LOCK (1 << 27) + +#define PLLA_MISC0_LOCK_ENABLE (1 << 28) +#define PLLA_MISC0_LOCK_OVERRIDE (1 << 27) + +#define PLLA_MISC2_EN_SDM (1 << 26) +#define PLLA_MISC2_EN_DYNRAMP (1 << 25) + +#define PLLA_MISC0_DEFAULT_VALUE 0x12000020 +#define PLLA_MISC0_WRITE_MASK 0x7fffffff +#define PLLA_MISC2_DEFAULT_VALUE 0x0 +#define PLLA_MISC2_WRITE_MASK 0x06ffffff + +/* PLLD */ +#define PLLD_MISC0_EN_SDM (1 << 16) +#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) +#define PLLD_MISC0_LOCK_ENABLE (1 << 18) +#define PLLD_MISC0_IDDQ (1 << 20) +#define PLLD_MISC0_DSI_CLKENABLE (1 << 21) + +#define PLLD_MISC0_DEFAULT_VALUE 0x00140000 +#define PLLD_MISC0_WRITE_MASK 0x3ff7ffff +#define PLLD_MISC1_DEFAULT_VALUE 0x20 +#define PLLD_MISC1_WRITE_MASK 0x00ffffff + +/* PLLD2 and PLLDP and PLLC4 */ +#define PLLDSS_BASE_LOCK (1 << 27) +#define PLLDSS_BASE_LOCK_OVERRIDE (1 << 24) +#define PLLDSS_BASE_IDDQ (1 << 18) +#define PLLDSS_BASE_REF_SEL_SHIFT 25 +#define PLLDSS_BASE_REF_SEL_MASK (0x3 << PLLDSS_BASE_REF_SEL_SHIFT) + +#define PLLDSS_MISC0_LOCK_ENABLE (1 << 30) + +#define PLLDSS_MISC1_CFG_EN_SDM (1 << 31) +#define PLLDSS_MISC1_CFG_EN_SSC (1 << 30) + +#define PLLD2_MISC0_DEFAULT_VALUE 0x40000020 +#define PLLD2_MISC1_CFG_DEFAULT_VALUE 0x10000000 +#define PLLD2_MISC2_CTRL1_DEFAULT_VALUE 0x0 +#define PLLD2_MISC3_CTRL2_DEFAULT_VALUE 0x0 + +#define PLLDP_MISC0_DEFAULT_VALUE 0x40000020 +#define PLLDP_MISC1_CFG_DEFAULT_VALUE 0xc0000000 +#define PLLDP_MISC2_CTRL1_DEFAULT_VALUE 0xf400f0da +#define PLLDP_MISC3_CTRL2_DEFAULT_VALUE 0x2004f400 + +#define PLLDSS_MISC0_WRITE_MASK 0x47ffffff +#define PLLDSS_MISC1_CFG_WRITE_MASK 0xf8000000 +#define PLLDSS_MISC2_CTRL1_WRITE_MASK 0xffffffff +#define PLLDSS_MISC3_CTRL2_WRITE_MASK 0xffffffff + +#define PLLC4_MISC0_DEFAULT_VALUE 0x40000000 + +/* PLLRE */ +#define PLLRE_MISC0_LOCK_ENABLE (1 << 30) +#define PLLRE_MISC0_LOCK_OVERRIDE (1 << 29) +#define PLLRE_MISC0_LOCK (1 << 27) +#define PLLRE_MISC0_IDDQ (1 << 24) + +#define PLLRE_BASE_DEFAULT_VALUE 0x0 +#define PLLRE_MISC0_DEFAULT_VALUE 0x41000000 + +#define PLLRE_BASE_DEFAULT_MASK 0x1c000000 +#define PLLRE_MISC0_WRITE_MASK 0x67ffffff + +/* PLLX */ +#define PLLX_USE_DYN_RAMP 1 +#define PLLX_BASE_LOCK (1 << 27) + +#define PLLX_MISC0_FO_G_DISABLE (0x1 << 28) +#define PLLX_MISC0_LOCK_ENABLE (0x1 << 18) + +#define PLLX_MISC2_DYNRAMP_STEPB_SHIFT 24 +#define PLLX_MISC2_DYNRAMP_STEPB_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPB_SHIFT) +#define PLLX_MISC2_DYNRAMP_STEPA_SHIFT 16 +#define PLLX_MISC2_DYNRAMP_STEPA_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPA_SHIFT) +#define PLLX_MISC2_NDIV_NEW_SHIFT 8 +#define PLLX_MISC2_NDIV_NEW_MASK (0xFF << PLLX_MISC2_NDIV_NEW_SHIFT) +#define PLLX_MISC2_LOCK_OVERRIDE (0x1 << 4) +#define PLLX_MISC2_DYNRAMP_DONE (0x1 << 2) +#define PLLX_MISC2_EN_DYNRAMP (0x1 << 0) + +#define PLLX_MISC3_IDDQ (0x1 << 3) + +#define PLLX_MISC0_DEFAULT_VALUE PLLX_MISC0_LOCK_ENABLE +#define PLLX_MISC0_WRITE_MASK 0x10c40000 +#define PLLX_MISC1_DEFAULT_VALUE 0x20 +#define PLLX_MISC1_WRITE_MASK 0x00ffffff +#define PLLX_MISC2_DEFAULT_VALUE 0x0 +#define PLLX_MISC2_WRITE_MASK 0xffffff11 +#define PLLX_MISC3_DEFAULT_VALUE PLLX_MISC3_IDDQ +#define PLLX_MISC3_WRITE_MASK 0x01ff0f0f +#define PLLX_MISC4_DEFAULT_VALUE 0x0 +#define PLLX_MISC4_WRITE_MASK 0x8000ffff +#define PLLX_MISC5_DEFAULT_VALUE 0x0 +#define PLLX_MISC5_WRITE_MASK 0x0000ffff + +#define PLLX_HW_CTRL_CFG 0x548 +#define PLLX_HW_CTRL_CFG_SWCTRL (0x1 << 0) + +/* PLLMB */ +#define PLLMB_BASE_LOCK (1 << 27) + +#define PLLMB_MISC0_LOCK_OVERRIDE (1 << 18) +#define PLLMB_MISC0_IDDQ (1 << 17) +#define PLLMB_MISC0_LOCK_ENABLE (1 << 16) + +#define PLLMB_MISC0_DEFAULT_VALUE 0x00030000 +#define PLLMB_MISC0_WRITE_MASK 0x0007ffff + +/* PLLP */ +#define PLLP_BASE_OVERRIDE (1 << 28) +#define PLLP_BASE_LOCK (1 << 27) + +#define PLLP_MISC0_LOCK_ENABLE (1 << 18) +#define PLLP_MISC0_LOCK_OVERRIDE (1 << 17) +#define PLLP_MISC0_IDDQ (1 << 3) + +#define PLLP_MISC1_HSIO_EN_SHIFT 29 +#define PLLP_MISC1_HSIO_EN (1 << PLLP_MISC1_HSIO_EN_SHIFT) +#define PLLP_MISC1_XUSB_EN_SHIFT 28 +#define PLLP_MISC1_XUSB_EN (1 << PLLP_MISC1_XUSB_EN_SHIFT) + +#define PLLP_MISC0_DEFAULT_VALUE 0x00040008 +#define PLLP_MISC1_DEFAULT_VALUE 0x0 + +#define PLLP_MISC0_WRITE_MASK 0xdc6000f +#define PLLP_MISC1_WRITE_MASK 0x70ffffff + +/* PLLU */ +#define PLLU_BASE_LOCK (1 << 27) +#define PLLU_BASE_OVERRIDE (1 << 24) +#define PLLU_BASE_CLKENABLE_USB (1 << 21) +#define PLLU_BASE_CLKENABLE_HSIC (1 << 22) +#define PLLU_BASE_CLKENABLE_ICUSB (1 << 23) +#define PLLU_BASE_CLKENABLE_48M (1 << 25) +#define PLLU_BASE_CLKENABLE_ALL (PLLU_BASE_CLKENABLE_USB |\ + PLLU_BASE_CLKENABLE_HSIC |\ + PLLU_BASE_CLKENABLE_ICUSB |\ + PLLU_BASE_CLKENABLE_48M) + +#define PLLU_MISC0_IDDQ (1 << 31) +#define PLLU_MISC0_LOCK_ENABLE (1 << 29) +#define PLLU_MISC1_LOCK_OVERRIDE (1 << 0) + +#define PLLU_MISC0_DEFAULT_VALUE 0xa0000000 +#define PLLU_MISC1_DEFAULT_VALUE 0x0 + +#define PLLU_MISC0_WRITE_MASK 0xbfffffff +#define PLLU_MISC1_WRITE_MASK 0x00000007 + +static inline void _pll_misc_chk_default(void __iomem *base, + struct tegra_clk_pll_params *params, + u8 misc_num, u32 default_val, u32 mask) +{ + u32 boot_val = readl_relaxed(base + params->ext_misc_reg[misc_num]); + + boot_val &= mask; + default_val &= mask; + if (boot_val != default_val) { + pr_warn("boot misc%d 0x%x: expected 0x%x\n", + misc_num, boot_val, default_val); + pr_warn(" (comparison mask = 0x%x)\n", mask); + params->defaults_set = false; + } +} + +/* + * PLLCX: PLLC, PLLC2, PLLC3, PLLA1 + * Hybrid PLLs with dynamic ramp. Dynamic ramp is allowed for any transition + * that changes NDIV only, while PLL is already locked. + */ +static void pllcx_check_defaults(struct tegra_clk_pll_params *params) +{ + u32 default_val; + + default_val = PLLCX_MISC0_DEFAULT_VALUE & (~PLLCX_MISC0_RESET); + _pll_misc_chk_default(clk_base, params, 0, default_val, + PLLCX_MISC0_WRITE_MASK); + + default_val = PLLCX_MISC1_DEFAULT_VALUE & (~PLLCX_MISC1_IDDQ); + _pll_misc_chk_default(clk_base, params, 1, default_val, + PLLCX_MISC1_WRITE_MASK); + + default_val = PLLCX_MISC2_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, params, 2, default_val, + PLLCX_MISC2_WRITE_MASK); + + default_val = PLLCX_MISC3_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, params, 3, default_val, + PLLCX_MISC3_WRITE_MASK); +} + +void tegra210_pllcx_set_defaults(const char *name, struct tegra_clk_pll *pllcx) +{ + pllcx->params->defaults_set = true; + + if (readl_relaxed(clk_base + pllcx->params->base_reg) & + PLL_ENABLE) { + /* PLL is ON: only check if defaults already set */ + pllcx_check_defaults(pllcx->params); + pr_warn("%s already enabled. Postponing set full defaults\n", + name); + return; + } + + /* Defaults assert PLL reset, and set IDDQ */ + writel_relaxed(PLLCX_MISC0_DEFAULT_VALUE, + clk_base + pllcx->params->ext_misc_reg[0]); + writel_relaxed(PLLCX_MISC1_DEFAULT_VALUE, + clk_base + pllcx->params->ext_misc_reg[1]); + writel_relaxed(PLLCX_MISC2_DEFAULT_VALUE, + clk_base + pllcx->params->ext_misc_reg[2]); + writel_relaxed(PLLCX_MISC3_DEFAULT_VALUE, + clk_base + pllcx->params->ext_misc_reg[3]); + udelay(1); +} + +void _pllc_set_defaults(struct tegra_clk_pll *pllcx) +{ + tegra210_pllcx_set_defaults("PLL_C", pllcx); +} + +void _pllc2_set_defaults(struct tegra_clk_pll *pllcx) +{ + tegra210_pllcx_set_defaults("PLL_C2", pllcx); +} + +void _pllc3_set_defaults(struct tegra_clk_pll *pllcx) +{ + tegra210_pllcx_set_defaults("PLL_C3", pllcx); +} + +void _plla1_set_defaults(struct tegra_clk_pll *pllcx) +{ + tegra210_pllcx_set_defaults("PLL_A1", pllcx); +} + +/* + * PLLA + * PLL with dynamic ramp and fractional SDM. Dynamic ramp is not used. + * Fractional SDM is allowed to provide exact audio rates. + */ +void tegra210_plla_set_defaults(struct tegra_clk_pll *plla) +{ + u32 mask; + u32 val = readl_relaxed(clk_base + plla->params->base_reg); + + plla->params->defaults_set = true; + + if (val & PLL_ENABLE) { + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + if (val & PLLA_BASE_IDDQ) { + pr_warn("PLL_A boot enabled with IDDQ set\n"); + plla->params->defaults_set = false; + } + + pr_warn("PLL_A already enabled. Postponing set full defaults\n"); + + val = PLLA_MISC0_DEFAULT_VALUE; /* ignore lock enable */ + mask = PLLA_MISC0_LOCK_ENABLE | PLLA_MISC0_LOCK_OVERRIDE; + _pll_misc_chk_default(clk_base, plla->params, 0, val, + ~mask & PLLA_MISC0_WRITE_MASK); + + val = PLLA_MISC2_DEFAULT_VALUE; /* ignore all but control bit */ + _pll_misc_chk_default(clk_base, plla->params, 2, val, + PLLA_MISC2_EN_DYNRAMP); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + plla->params->ext_misc_reg[0]); + val &= ~mask; + val |= PLLA_MISC0_DEFAULT_VALUE & mask; + writel_relaxed(val, clk_base + plla->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect, disable dynamic ramp and SDM */ + val |= PLLA_BASE_IDDQ; + writel_relaxed(val, clk_base + plla->params->base_reg); + writel_relaxed(PLLA_MISC0_DEFAULT_VALUE, + clk_base + plla->params->ext_misc_reg[0]); + writel_relaxed(PLLA_MISC2_DEFAULT_VALUE, + clk_base + plla->params->ext_misc_reg[2]); + udelay(1); +} + +/* + * PLLD + * PLL with fractional SDM. + */ +void tegra210_plld_set_defaults(struct tegra_clk_pll *plld) +{ + u32 val; + u32 mask = 0xffff; + + plld->params->defaults_set = true; + + if (readl_relaxed(clk_base + plld->params->base_reg) & + PLL_ENABLE) { + pr_warn("PLL_D already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + val = PLLD_MISC1_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, plld->params, 1, + val, PLLD_MISC1_WRITE_MASK); + + /* ignore lock, DSI and SDM controls, make sure IDDQ not set */ + val = PLLD_MISC0_DEFAULT_VALUE & (~PLLD_MISC0_IDDQ); + mask |= PLLD_MISC0_DSI_CLKENABLE | PLLD_MISC0_LOCK_ENABLE | + PLLD_MISC0_LOCK_OVERRIDE | PLLD_MISC0_EN_SDM; + _pll_misc_chk_default(clk_base, plld->params, 0, val, + ~mask & PLLD_MISC0_WRITE_MASK); + + /* Enable lock detect */ + mask = PLLD_MISC0_LOCK_ENABLE | PLLD_MISC0_LOCK_OVERRIDE; + val = readl_relaxed(clk_base + plld->params->ext_misc_reg[0]); + val &= ~mask; + val |= PLLD_MISC0_DEFAULT_VALUE & mask; + writel_relaxed(val, clk_base + plld->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + val = readl_relaxed(clk_base + plld->params->ext_misc_reg[0]); + val &= PLLD_MISC0_DSI_CLKENABLE; + val |= PLLD_MISC0_DEFAULT_VALUE; + /* set IDDQ, enable lock detect, disable SDM */ + writel_relaxed(val, clk_base + plld->params->ext_misc_reg[0]); + writel_relaxed(PLLD_MISC1_DEFAULT_VALUE, clk_base + + plld->params->ext_misc_reg[1]); + udelay(1); +} + +/* + * PLLD2, PLLDP + * PLL with fractional SDM and Spread Spectrum (SDM is a must if SSC is used). + */ +static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss, + u32 misc0_val, u32 misc1_val, u32 misc2_val, u32 misc3_val) +{ + u32 default_val; + u32 val = readl_relaxed(clk_base + plldss->params->base_reg); + + plldss->params->defaults_set = true; + + if (val & PLL_ENABLE) { + pr_warn("%s already enabled. Postponing set full defaults\n", + pll_name); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + if (val & PLLDSS_BASE_IDDQ) { + pr_warn("plldss boot enabled with IDDQ set\n"); + plldss->params->defaults_set = false; + } + + /* ignore lock enable */ + default_val = misc0_val; + _pll_misc_chk_default(clk_base, plldss->params, 0, default_val, + PLLDSS_MISC0_WRITE_MASK & + (~PLLDSS_MISC0_LOCK_ENABLE)); + + /* + * If SSC is used, check all settings, otherwise just confirm + * that SSC is not used on boot as well. Do nothing when using + * this function for PLLC4 that has only MISC0. + */ + if (plldss->params->ssc_ctrl_en_mask) { + default_val = misc1_val; + _pll_misc_chk_default(clk_base, plldss->params, 1, + default_val, PLLDSS_MISC1_CFG_WRITE_MASK); + default_val = misc2_val; + _pll_misc_chk_default(clk_base, plldss->params, 2, + default_val, PLLDSS_MISC2_CTRL1_WRITE_MASK); + default_val = misc3_val; + _pll_misc_chk_default(clk_base, plldss->params, 3, + default_val, PLLDSS_MISC3_CTRL2_WRITE_MASK); + } else if (plldss->params->ext_misc_reg[1]) { + default_val = misc1_val; + _pll_misc_chk_default(clk_base, plldss->params, 1, + default_val, PLLDSS_MISC1_CFG_WRITE_MASK & + (~PLLDSS_MISC1_CFG_EN_SDM)); + } + + /* Enable lock detect */ + if (val & PLLDSS_BASE_LOCK_OVERRIDE) { + val &= ~PLLDSS_BASE_LOCK_OVERRIDE; + writel_relaxed(val, clk_base + + plldss->params->base_reg); + } + + val = readl_relaxed(clk_base + plldss->params->ext_misc_reg[0]); + val &= ~PLLDSS_MISC0_LOCK_ENABLE; + val |= misc0_val & PLLDSS_MISC0_LOCK_ENABLE; + writel_relaxed(val, clk_base + plldss->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect, configure SDM/SSC */ + val |= PLLDSS_BASE_IDDQ; + val &= ~PLLDSS_BASE_LOCK_OVERRIDE; + writel_relaxed(val, clk_base + plldss->params->base_reg); + + /* When using this function for PLLC4 exit here */ + if (!plldss->params->ext_misc_reg[1]) { + writel_relaxed(misc0_val, clk_base + + plldss->params->ext_misc_reg[0]); + udelay(1); + return; + } + + writel_relaxed(misc0_val, clk_base + + plldss->params->ext_misc_reg[0]); + /* if SSC used set by 1st enable */ + writel_relaxed(misc1_val & (~PLLDSS_MISC1_CFG_EN_SSC), + clk_base + plldss->params->ext_misc_reg[1]); + writel_relaxed(misc2_val, clk_base + plldss->params->ext_misc_reg[2]); + writel_relaxed(misc3_val, clk_base + plldss->params->ext_misc_reg[3]); + udelay(1); +} + +void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2) +{ + plldss_defaults("PLL_D2", plld2, PLLD2_MISC0_DEFAULT_VALUE, + PLLD2_MISC1_CFG_DEFAULT_VALUE, + PLLD2_MISC2_CTRL1_DEFAULT_VALUE, + PLLD2_MISC3_CTRL2_DEFAULT_VALUE); +} + +void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp) +{ + plldss_defaults("PLL_DP", plldp, PLLDP_MISC0_DEFAULT_VALUE, + PLLDP_MISC1_CFG_DEFAULT_VALUE, + PLLDP_MISC2_CTRL1_DEFAULT_VALUE, + PLLDP_MISC3_CTRL2_DEFAULT_VALUE); +} + +/* + * PLLC4 + * Base and misc0 layout is the same as PLLD2/PLLDP, but no SDM/SSC support. + * VCO is exposed to the clock tree via fixed 1/3 and 1/5 dividers. + */ +void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4) +{ + plldss_defaults("PLL_C4", pllc4, PLLC4_MISC0_DEFAULT_VALUE, 0, 0, 0); +} + +/* + * PLLRE + * VCO is exposed to the clock tree directly along with post-divider output + */ +void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre) +{ + u32 mask; + u32 val = readl_relaxed(clk_base + pllre->params->base_reg); + + pllre->params->defaults_set = true; + + if (val & PLL_ENABLE) { + pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + val &= PLLRE_BASE_DEFAULT_MASK; + if (val != PLLRE_BASE_DEFAULT_VALUE) { + pr_warn("pllre boot base 0x%x : expected 0x%x\n", + val, PLLRE_BASE_DEFAULT_VALUE); + pr_warn("(comparison mask = 0x%x)\n", + PLLRE_BASE_DEFAULT_MASK); + pllre->params->defaults_set = false; + } + + /* Ignore lock enable */ + val = PLLRE_MISC0_DEFAULT_VALUE & (~PLLRE_MISC0_IDDQ); + mask = PLLRE_MISC0_LOCK_ENABLE | PLLRE_MISC0_LOCK_OVERRIDE; + _pll_misc_chk_default(clk_base, pllre->params, 0, val, + ~mask & PLLRE_MISC0_WRITE_MASK); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]); + val &= ~mask; + val |= PLLRE_MISC0_DEFAULT_VALUE & mask; + writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect */ + val &= ~PLLRE_BASE_DEFAULT_MASK; + val |= PLLRE_BASE_DEFAULT_VALUE & PLLRE_BASE_DEFAULT_MASK; + writel_relaxed(val, clk_base + pllre->params->base_reg); + writel_relaxed(PLLRE_MISC0_DEFAULT_VALUE, + clk_base + pllre->params->ext_misc_reg[0]); + udelay(1); +} + +static void pllx_get_dyn_steps(struct clk_hw *hw, u32 *step_a, u32 *step_b) +{ + unsigned long input_rate; + + if (!IS_ERR_OR_NULL(hw->clk)) { + input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); + /* cf rate */ + input_rate /= tegra_pll_get_fixed_mdiv(hw, input_rate); + } else { + input_rate = 38400000; + } + + switch (input_rate) { + case 12000000: + case 12800000: + case 13000000: + *step_a = 0x2B; + *step_b = 0x0B; + return; + case 19200000: + *step_a = 0x12; + *step_b = 0x08; + return; + case 38400000: + *step_a = 0x04; + *step_b = 0x05; + return; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, input_rate); + BUG(); + } +} + +static void pllx_check_defaults(struct tegra_clk_pll *pll) +{ + u32 default_val; + + default_val = PLLX_MISC0_DEFAULT_VALUE; + /* ignore lock enable */ + _pll_misc_chk_default(clk_base, pll->params, 0, default_val, + PLLX_MISC0_WRITE_MASK & (~PLLX_MISC0_LOCK_ENABLE)); + + default_val = PLLX_MISC1_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, pll->params, 1, default_val, + PLLX_MISC1_WRITE_MASK); + + /* ignore all but control bit */ + default_val = PLLX_MISC2_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, pll->params, 2, + default_val, PLLX_MISC2_EN_DYNRAMP); + + default_val = PLLX_MISC3_DEFAULT_VALUE & (~PLLX_MISC3_IDDQ); + _pll_misc_chk_default(clk_base, pll->params, 3, default_val, + PLLX_MISC3_WRITE_MASK); + + default_val = PLLX_MISC4_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, pll->params, 4, default_val, + PLLX_MISC4_WRITE_MASK); + + default_val = PLLX_MISC5_DEFAULT_VALUE; + _pll_misc_chk_default(clk_base, pll->params, 5, default_val, + PLLX_MISC5_WRITE_MASK); +} + +void tegra210_pllx_set_defaults(struct tegra_clk_pll *pllx) +{ + u32 val; + u32 step_a, step_b; + + pllx->params->defaults_set = true; + + /* Get ready dyn ramp state machine settings */ + pllx_get_dyn_steps(&pllx->hw, &step_a, &step_b); + val = PLLX_MISC2_DEFAULT_VALUE & (~PLLX_MISC2_DYNRAMP_STEPA_MASK) & + (~PLLX_MISC2_DYNRAMP_STEPB_MASK); + val |= step_a << PLLX_MISC2_DYNRAMP_STEPA_SHIFT; + val |= step_b << PLLX_MISC2_DYNRAMP_STEPB_SHIFT; + + if (readl_relaxed(clk_base + pllx->params->base_reg) & PLL_ENABLE) { + pr_warn("PLL_X already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + pllx_check_defaults(pllx); + + /* Configure dyn ramp, disable lock override */ + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[0]); + val &= ~PLLX_MISC0_LOCK_ENABLE; + val |= PLLX_MISC0_DEFAULT_VALUE & PLLX_MISC0_LOCK_ENABLE; + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* Enable lock detect and CPU output */ + writel_relaxed(PLLX_MISC0_DEFAULT_VALUE, clk_base + + pllx->params->ext_misc_reg[0]); + + /* Setup */ + writel_relaxed(PLLX_MISC1_DEFAULT_VALUE, clk_base + + pllx->params->ext_misc_reg[1]); + + /* Configure dyn ramp state machine, disable lock override */ + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]); + + /* Set IDDQ */ + writel_relaxed(PLLX_MISC3_DEFAULT_VALUE, clk_base + + pllx->params->ext_misc_reg[3]); + + /* Disable SDM */ + writel_relaxed(PLLX_MISC4_DEFAULT_VALUE, clk_base + + pllx->params->ext_misc_reg[4]); + writel_relaxed(PLLX_MISC5_DEFAULT_VALUE, clk_base + + pllx->params->ext_misc_reg[5]); + udelay(1); +} + +/* PLLMB */ +void tegra210_pllmb_set_defaults(struct tegra_clk_pll *pllmb) +{ + u32 mask, val = readl_relaxed(clk_base + pllmb->params->base_reg); + + pllmb->params->defaults_set = true; + + if (val & PLL_ENABLE) { + pr_warn("PLL_MB already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + val = PLLMB_MISC0_DEFAULT_VALUE & (~PLLMB_MISC0_IDDQ); + mask = PLLMB_MISC0_LOCK_ENABLE | PLLMB_MISC0_LOCK_OVERRIDE; + _pll_misc_chk_default(clk_base, pllmb->params, 0, val, + ~mask & PLLMB_MISC0_WRITE_MASK); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + pllmb->params->ext_misc_reg[0]); + val &= ~mask; + val |= PLLMB_MISC0_DEFAULT_VALUE & mask; + writel_relaxed(val, clk_base + pllmb->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect */ + writel_relaxed(PLLMB_MISC0_DEFAULT_VALUE, + clk_base + pllmb->params->ext_misc_reg[0]); + udelay(1); +} + +/* + * PLLP + * VCO is exposed to the clock tree directly along with post-divider output. + * Both VCO and post-divider output rates are fixed at 408MHz and 204MHz, + * respectively. + */ +static void pllp_check_defaults(struct tegra_clk_pll *pll, bool enabled) +{ + u32 val, mask; + + /* Ignore lock enable (will be set), make sure not in IDDQ if enabled */ + val = PLLP_MISC0_DEFAULT_VALUE & (~PLLP_MISC0_IDDQ); + mask = PLLP_MISC0_LOCK_ENABLE | PLLP_MISC0_LOCK_OVERRIDE; + if (!enabled) + mask |= PLLP_MISC0_IDDQ; + _pll_misc_chk_default(clk_base, pll->params, 0, val, + ~mask & PLLP_MISC0_WRITE_MASK); + + /* Ignore branch controls */ + val = PLLP_MISC1_DEFAULT_VALUE; + mask = PLLP_MISC1_HSIO_EN | PLLP_MISC1_XUSB_EN; + _pll_misc_chk_default(clk_base, pll->params, 1, val, + ~mask & PLLP_MISC1_WRITE_MASK); +} + +void tegra210_pllp_set_defaults(struct tegra_clk_pll *pllp) +{ + u32 mask; + u32 val = readl_relaxed(clk_base + pllp->params->base_reg); + + pllp->params->defaults_set = true; + + if (val & PLL_ENABLE) { + pr_warn("PLL_P already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + pllp_check_defaults(pllp, true); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + pllp->params->ext_misc_reg[0]); + mask = PLLP_MISC0_LOCK_ENABLE | PLLP_MISC0_LOCK_OVERRIDE; + val &= ~mask; + val |= PLLP_MISC0_DEFAULT_VALUE & mask; + writel_relaxed(val, clk_base + pllp->params->ext_misc_reg[0]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect */ + writel_relaxed(PLLP_MISC0_DEFAULT_VALUE, + clk_base + pllp->params->ext_misc_reg[0]); + + /* Preserve branch control */ + val = readl_relaxed(clk_base + pllp->params->ext_misc_reg[1]); + mask = PLLP_MISC1_HSIO_EN | PLLP_MISC1_XUSB_EN; + val &= mask; + val |= ~mask & PLLP_MISC1_DEFAULT_VALUE; + writel_relaxed(val, clk_base + pllp->params->ext_misc_reg[1]); + udelay(1); +} + +/* + * PLLU + * VCO is exposed to the clock tree directly along with post-divider output. + * Both VCO and post-divider output rates are fixed at 480MHz and 240MHz, + * respectively. + */ +static void pllu_check_defaults(struct tegra_clk_pll *pll, bool hw_control) +{ + u32 val, mask; + + /* Ignore lock enable (will be set) and IDDQ if under h/w control */ + val = PLLU_MISC0_DEFAULT_VALUE & (~PLLU_MISC0_IDDQ); + mask = PLLU_MISC0_LOCK_ENABLE | (hw_control ? PLLU_MISC0_IDDQ : 0); + _pll_misc_chk_default(clk_base, pll->params, 0, val, + ~mask & PLLU_MISC0_WRITE_MASK); + + val = PLLU_MISC1_DEFAULT_VALUE; + mask = PLLU_MISC1_LOCK_OVERRIDE; + _pll_misc_chk_default(clk_base, pll->params, 1, val, + ~mask & PLLU_MISC1_WRITE_MASK); +} + +void tegra210_pllu_set_defaults(struct tegra_clk_pll *pllu) +{ + u32 val = readl_relaxed(clk_base + pllu->params->base_reg); + + pllu->params->defaults_set = true; + + if (val & PLL_ENABLE) { + pr_warn("PLL_U already enabled. Postponing set full defaults\n"); + + /* + * PLL is ON: check if defaults already set, then set those + * that can be updated in flight. + */ + pllu_check_defaults(pllu, false); + + /* Enable lock detect */ + val = readl_relaxed(clk_base + pllu->params->ext_misc_reg[0]); + val &= ~PLLU_MISC0_LOCK_ENABLE; + val |= PLLU_MISC0_DEFAULT_VALUE & PLLU_MISC0_LOCK_ENABLE; + writel_relaxed(val, clk_base + pllu->params->ext_misc_reg[0]); + + val = readl_relaxed(clk_base + pllu->params->ext_misc_reg[1]); + val &= ~PLLU_MISC1_LOCK_OVERRIDE; + val |= PLLU_MISC1_DEFAULT_VALUE & PLLU_MISC1_LOCK_OVERRIDE; + writel_relaxed(val, clk_base + pllu->params->ext_misc_reg[1]); + udelay(1); + + return; + } + + /* set IDDQ, enable lock detect */ + writel_relaxed(PLLU_MISC0_DEFAULT_VALUE, + clk_base + pllu->params->ext_misc_reg[0]); + writel_relaxed(PLLU_MISC1_DEFAULT_VALUE, + clk_base + pllu->params->ext_misc_reg[1]); + udelay(1); +} + +#define mask(w) ((1 << (w)) - 1) +#define divm_mask(p) mask(p->params->div_nmp->divm_width) +#define divn_mask(p) mask(p->params->div_nmp->divn_width) +#define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ + mask(p->params->div_nmp->divp_width)) + +#define divm_shift(p) ((p)->params->div_nmp->divm_shift) +#define divn_shift(p) ((p)->params->div_nmp->divn_shift) +#define divp_shift(p) ((p)->params->div_nmp->divp_shift) + +#define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p)) +#define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p)) +#define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p)) + +#define PLL_LOCKDET_DELAY 2 /* Lock detection safety delays */ +static int tegra210_wait_for_mask(struct tegra_clk_pll *pll, + u32 reg, u32 mask) +{ + int i; + u32 val = 0; + + for (i = 0; i < pll->params->lock_delay / PLL_LOCKDET_DELAY + 1; i++) { + udelay(PLL_LOCKDET_DELAY); + val = readl_relaxed(clk_base + reg); + if ((val & mask) == mask) { + udelay(PLL_LOCKDET_DELAY); + return 0; + } + } + return -ETIMEDOUT; +} + +static int tegra210_pllx_dyn_ramp(struct tegra_clk_pll *pllx, + struct tegra_clk_pll_freq_table *cfg) +{ + u32 val, base, ndiv_new_mask; + + ndiv_new_mask = (divn_mask(pllx) >> pllx->params->div_nmp->divn_shift) + << PLLX_MISC2_NDIV_NEW_SHIFT; + + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[2]); + val &= (~ndiv_new_mask); + val |= cfg->n << PLLX_MISC2_NDIV_NEW_SHIFT; + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]); + udelay(1); + + val = readl_relaxed(clk_base + pllx->params->ext_misc_reg[2]); + val |= PLLX_MISC2_EN_DYNRAMP; + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]); + udelay(1); + + tegra210_wait_for_mask(pllx, pllx->params->ext_misc_reg[2], + PLLX_MISC2_DYNRAMP_DONE); + + base = readl_relaxed(clk_base + pllx->params->base_reg) & + (~divn_mask_shifted(pllx)); + base |= cfg->n << pllx->params->div_nmp->divn_shift; + writel_relaxed(base, clk_base + pllx->params->base_reg); + udelay(1); + + val &= ~PLLX_MISC2_EN_DYNRAMP; + writel_relaxed(val, clk_base + pllx->params->ext_misc_reg[2]); + udelay(1); + + pr_debug("%s: dynamic ramp to m = %u n = %u p = %u, Fout = %lu kHz\n", + __clk_get_name(pllx->hw.clk), cfg->m, cfg->n, cfg->p, + cfg->input_rate / cfg->m * cfg->n / + pllx->params->pdiv_tohw[cfg->p].pdiv / 1000); + + return 0; +} + +/* + * Common configuration for PLLs with fixed input divider policy: + * - always set fixed M-value based on the reference rate + * - always set P-value value 1:1 for output rates above VCO minimum, and + * choose minimum necessary P-value for output rates below VCO maximum + * - calculate N-value based on selected M and P + * - calculate SDM_DIN fractional part + */ +static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long input_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct tegra_clk_pll_params *params = pll->params; + int p; + unsigned long cf, p_rate; + u32 pdiv; + + if (!rate) + return -EINVAL; + + if (!(params->flags & TEGRA_PLL_VCO_OUT)) { + p = DIV_ROUND_UP(params->vco_min, rate); + p = params->round_p_to_pdiv(p, &pdiv); + } else { + p = rate >= params->vco_min ? 1 : -EINVAL; + } + + if (IS_ERR_VALUE(p)) + return -EINVAL; + + cfg->m = tegra_pll_get_fixed_mdiv(hw, input_rate); + cfg->p = p; + + /* Store P as HW value, as that is what is expected */ + cfg->p = tegra_pll_p_div_to_hw(pll, cfg->p); + + p_rate = rate * p; + if (p_rate > params->vco_max) + p_rate = params->vco_max; + cf = input_rate / cfg->m; + cfg->n = p_rate / cf; + + cfg->sdm_data = 0; + if (params->sdm_ctrl_reg) { + unsigned long rem = p_rate - cf * cfg->n; + /* If ssc is enabled SDM enabled as well, even for integer n */ + if (rem || params->ssc_ctrl_reg) { + u64 s = rem * PLL_SDM_COEFF; + + do_div(s, cf); + s -= PLL_SDM_COEFF / 2; + cfg->sdm_data = sdin_din_to_data(s); + } + } + + cfg->input_rate = input_rate; + cfg->output_rate = rate; + + return 0; +} + +/* + * clk_pll_set_gain - set gain to m, n to calculate correct VCO rate + * + * @cfg: struct tegra_clk_pll_freq_table * cfg + * + * For Normal mode: + * Fvco = Fref * NDIV / MDIV + * + * For fractional mode: + * Fvco = Fref * (NDIV + 0.5 + SDM_DIN / PLL_SDM_COEFF) / MDIV + */ +static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) +{ + cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + + sdin_data_to_din(cfg->sdm_data); + cfg->m *= PLL_SDM_COEFF; +} + +unsigned long tegra210_clk_adjust_vco_min(struct tegra_clk_pll_params *params, + unsigned long parent_rate) +{ + unsigned long vco_min = params->vco_min; + + params->vco_min += DIV_ROUND_UP(parent_rate, PLL_SDM_COEFF); + vco_min = min(vco_min, params->vco_min); + + return vco_min; +} + +static struct div_nmp pllx_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 5, +}; +/* + * PLL post divider maps - two types: quasi-linear and exponential + * post divider. + */ +#define PLL_QLIN_PDIV_MAX 16 +static const struct pdiv_map pll_qlin_pdiv_to_hw[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 9, .hw_val = 7 }, + { .pdiv = 10, .hw_val = 8 }, + { .pdiv = 12, .hw_val = 9 }, + { .pdiv = 15, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 18, .hw_val = 12 }, + { .pdiv = 20, .hw_val = 13 }, + { .pdiv = 24, .hw_val = 14 }, + { .pdiv = 30, .hw_val = 15 }, + { .pdiv = 32, .hw_val = 16 }, +}; + +static u32 pll_qlin_p_to_pdiv(u32 p, u32 *pdiv) +{ + int i; + + if (p) { + for (i = 0; i <= PLL_QLIN_PDIV_MAX; i++) { + if (p <= pll_qlin_pdiv_to_hw[i].pdiv) { + if (pdiv) + *pdiv = i; + return pll_qlin_pdiv_to_hw[i].pdiv; + } + } + } + + return -EINVAL; +} + +#define PLL_EXPO_PDIV_MAX 7 +static const struct pdiv_map pll_expo_pdiv_to_hw[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 4, .hw_val = 2 }, + { .pdiv = 8, .hw_val = 3 }, + { .pdiv = 16, .hw_val = 4 }, + { .pdiv = 32, .hw_val = 5 }, + { .pdiv = 64, .hw_val = 6 }, + { .pdiv = 128, .hw_val = 7 }, +}; + +static u32 pll_expo_p_to_pdiv(u32 p, u32 *pdiv) +{ + if (p) { + u32 i = fls(p); + + if (i == ffs(p)) + i--; + + if (i <= PLL_EXPO_PDIV_MAX) { + if (pdiv) + *pdiv = i; + return 1 << i; + } + } + return -EINVAL; +} + +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { + /* 1 GHz */ + { 12000000, 1000000000, 166, 1, 1, 0 }, /* actual: 996.0 MHz */ + { 13000000, 1000000000, 153, 1, 1, 0 }, /* actual: 994.0 MHz */ + { 38400000, 1000000000, 156, 3, 1, 0 }, /* actual: 998.4 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_x_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 38400000, + .vco_min = 1350000000, + .vco_max = 3000000000UL, + .base_reg = PLLX_BASE, + .misc_reg = PLLX_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .ext_misc_reg[0] = PLLX_MISC0, + .ext_misc_reg[1] = PLLX_MISC1, + .ext_misc_reg[2] = PLLX_MISC2, + .ext_misc_reg[3] = PLLX_MISC3, + .ext_misc_reg[4] = PLLX_MISC4, + .ext_misc_reg[5] = PLLX_MISC5, + .iddq_reg = PLLX_MISC3, + .iddq_bit_idx = PLLXP_IDDQ_BIT, + .max_p = PLL_QLIN_PDIV_MAX, + .mdiv_default = 2, + .dyn_ramp_reg = PLLX_MISC2, + .stepa_shift = 16, + .stepb_shift = 24, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllx_nmp, + .freq_table = pll_x_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .dyn_ramp = tegra210_pllx_dyn_ramp, + .set_defaults = tegra210_pllx_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct div_nmp pllc_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 10, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 5, +}; + +static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { + { 12000000, 510000000, 85, 1, 1, 0 }, + { 13000000, 510000000, 78, 1, 1, 0 }, /* actual: 507.0 MHz */ + { 38400000, 510000000, 79, 3, 1, 0 }, /* actual: 505.6 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c_params = { + .input_min = 12000000, + .input_max = 700000000, + .cf_min = 12000000, + .cf_max = 50000000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC_BASE, + .misc_reg = PLLC_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_delay = 300, + .iddq_reg = PLLC_MISC1, + .iddq_bit_idx = PLLCX_IDDQ_BIT, + .reset_reg = PLLC_MISC0, + .reset_bit_idx = PLLCX_RESET_BIT, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLC_MISC0, + .ext_misc_reg[1] = PLLC_MISC1, + .ext_misc_reg[2] = PLLC_MISC2, + .ext_misc_reg[3] = PLLC_MISC3, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .mdiv_default = 3, + .div_nmp = &pllc_nmp, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = _pllc_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct div_nmp pllcx_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 10, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 5, +}; + +static struct tegra_clk_pll_params pll_c2_params = { + .input_min = 12000000, + .input_max = 700000000, + .cf_min = 12000000, + .cf_max = 50000000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC2_BASE, + .misc_reg = PLLC2_MISC0, + .iddq_reg = PLLC2_MISC1, + .iddq_bit_idx = PLLCX_IDDQ_BIT, + .reset_reg = PLLC2_MISC0, + .reset_bit_idx = PLLCX_RESET_BIT, + .lock_mask = PLLCX_BASE_LOCK, + .lock_delay = 300, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .mdiv_default = 3, + .div_nmp = &pllcx_nmp, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLC2_MISC0, + .ext_misc_reg[1] = PLLC2_MISC1, + .ext_misc_reg[2] = PLLC2_MISC2, + .ext_misc_reg[3] = PLLC2_MISC3, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = _pllc2_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct tegra_clk_pll_params pll_c3_params = { + .input_min = 12000000, + .input_max = 700000000, + .cf_min = 12000000, + .cf_max = 50000000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC3_BASE, + .misc_reg = PLLC3_MISC0, + .lock_mask = PLLCX_BASE_LOCK, + .lock_delay = 300, + .iddq_reg = PLLC3_MISC1, + .iddq_bit_idx = PLLCX_IDDQ_BIT, + .reset_reg = PLLC3_MISC0, + .reset_bit_idx = PLLCX_RESET_BIT, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .mdiv_default = 3, + .div_nmp = &pllcx_nmp, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLC3_MISC0, + .ext_misc_reg[1] = PLLC3_MISC1, + .ext_misc_reg[2] = PLLC3_MISC2, + .ext_misc_reg[3] = PLLC3_MISC3, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = _pllc3_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct div_nmp pllss_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 19, + .divp_width = 5, +}; + +static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = { + { 12000000, 600000000, 50, 1, 0, 0 }, + { 13000000, 600000000, 46, 1, 0, 0 }, /* actual: 598.0 MHz */ + { 38400000, 600000000, 62, 4, 0, 0 }, /* actual: 595.2 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static const struct clk_div_table pll_vco_post_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 3 }, + { .val = 3, .div = 4 }, + { .val = 4, .div = 5 }, + { .val = 5, .div = 6 }, + { .val = 6, .div = 8 }, + { .val = 7, .div = 10 }, + { .val = 8, .div = 12 }, + { .val = 9, .div = 16 }, + { .val = 10, .div = 12 }, + { .val = 11, .div = 16 }, + { .val = 12, .div = 20 }, + { .val = 13, .div = 24 }, + { .val = 14, .div = 32 }, + { .val = 0, .div = 0 }, +}; + +static struct tegra_clk_pll_params pll_c4_vco_params = { + .input_min = 9600000, + .input_max = 800000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 500000000, + .vco_max = 1080000000, + .base_reg = PLLC4_BASE, + .misc_reg = PLLC4_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLC4_MISC0, + .iddq_reg = PLLC4_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .mdiv_default = 3, + .div_nmp = &pllss_nmp, + .freq_table = pll_c4_vco_freq_table, + .set_defaults = tegra210_pllc4_set_defaults, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_VCO_OUT, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { + { 12000000, 800000000, 66, 1, 0, 0 }, /* actual: 792.0 MHz */ + { 13000000, 800000000, 61, 1, 0, 0 }, /* actual: 793.0 MHz */ + { 38400000, 297600000, 93, 4, 2, 0 }, + { 38400000, 400000000, 125, 4, 2, 0 }, + { 38400000, 532800000, 111, 4, 1, 0 }, + { 38400000, 665600000, 104, 3, 1, 0 }, + { 38400000, 800000000, 125, 3, 1, 0 }, + { 38400000, 931200000, 97, 4, 0, 0 }, + { 38400000, 1065600000, 111, 4, 0, 0 }, + { 38400000, 1200000000, 125, 4, 0, 0 }, + { 38400000, 1331200000, 104, 3, 0, 0 }, + { 38400000, 1459200000, 76, 2, 0, 0 }, + { 38400000, 1600000000, 125, 3, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct div_nmp pllm_nmp = { + .divm_shift = 0, + .divm_width = 8, + .override_divm_shift = 0, + .divn_shift = 8, + .divn_width = 8, + .override_divn_shift = 8, + .divp_shift = 20, + .divp_width = 5, + .override_divp_shift = 27, +}; + +static struct tegra_clk_pll_params pll_m_params = { + .input_min = 9600000, + .input_max = 500000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 800000000, + .vco_max = 1866000000, + .base_reg = PLLM_BASE, + .misc_reg = PLLM_MISC1, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLM_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLM_MISC0, + .iddq_bit_idx = PLLM_IDDQ_BIT, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLM_MISC0, + .ext_misc_reg[0] = PLLM_MISC1, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllm_nmp, + .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, + .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct tegra_clk_pll_params pll_mb_params = { + .input_min = 9600000, + .input_max = 500000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 800000000, + .vco_max = 1866000000, + .base_reg = PLLMB_BASE, + .misc_reg = PLLMB_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLMB_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLMB_MISC0, + .iddq_bit_idx = PLLMB_IDDQ_BIT, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLMB_MISC0, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllm_nmp, + .freq_table = pll_m_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = tegra210_pllmb_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + + +static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { + /* PLLE special case: use cpcon field to store cml divider value */ + { 672000000, 100000000, 125, 42, 0, 13 }, + { 624000000, 100000000, 125, 39, 0, 13 }, + { 336000000, 100000000, 125, 21, 0, 13 }, + { 312000000, 100000000, 200, 26, 0, 14 }, + { 38400000, 100000000, 125, 2, 0, 14 }, + { 12000000, 100000000, 200, 1, 0, 14 }, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct div_nmp plle_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 24, + .divp_width = 5, +}; + +static struct tegra_clk_pll_params pll_e_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 38400000, + .vco_min = 1600000000, + .vco_max = 2500000000U, + .base_reg = PLLE_BASE, + .misc_reg = PLLE_MISC0, + .aux_reg = PLLE_AUX, + .lock_mask = PLLE_MISC_LOCK, + .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .div_nmp = &plle_nmp, + .freq_table = pll_e_freq_table, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_LOCK_MISC | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE, + .fixed_rate = 100000000, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct tegra_clk_pll_freq_table pll_re_vco_freq_table[] = { + { 12000000, 672000000, 56, 1, 0, 0 }, + { 13000000, 672000000, 51, 1, 0, 0 }, /* actual: 663.0 MHz */ + { 38400000, 672000000, 70, 4, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct div_nmp pllre_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 16, + .divp_width = 5, +}; + +static struct tegra_clk_pll_params pll_re_vco_params = { + .input_min = 9600000, + .input_max = 800000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 350000000, + .vco_max = 700000000, + .base_reg = PLLRE_BASE, + .misc_reg = PLLRE_MISC0, + .lock_mask = PLLRE_MISC_LOCK, + .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .max_p = PLL_QLIN_PDIV_MAX, + .ext_misc_reg[0] = PLLRE_MISC0, + .iddq_reg = PLLRE_MISC0, + .iddq_bit_idx = PLLRE_IDDQ_BIT, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllre_nmp, + .freq_table = pll_re_vco_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_LOCK_MISC | + TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_VCO_OUT, + .set_defaults = tegra210_pllre_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct div_nmp pllp_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 10, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 5, +}; + +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { + { 12000000, 408000000, 34, 1, 0, 0 }, + { 38400000, 408000000, 85, 8, 0, 0 }, /* cf = 4.8MHz, allowed exception */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_p_params = { + .input_min = 9600000, + .input_max = 800000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 350000000, + .vco_max = 700000000, + .base_reg = PLLP_BASE, + .misc_reg = PLLP_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLP_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLP_MISC0, + .iddq_bit_idx = PLLXP_IDDQ_BIT, + .ext_misc_reg[0] = PLLP_MISC0, + .ext_misc_reg[1] = PLLP_MISC1, + .div_nmp = &pllp_nmp, + .freq_table = pll_p_freq_table, + .fixed_rate = 408000000, + .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK | + TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_VCO_OUT, + .set_defaults = tegra210_pllp_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct tegra_clk_pll_params pll_a1_params = { + .input_min = 12000000, + .input_max = 700000000, + .cf_min = 12000000, + .cf_max = 50000000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLA1_BASE, + .misc_reg = PLLA1_MISC0, + .lock_mask = PLLCX_BASE_LOCK, + .lock_delay = 300, + .iddq_reg = PLLA1_MISC0, + .iddq_bit_idx = PLLCX_IDDQ_BIT, + .reset_reg = PLLA1_MISC0, + .reset_bit_idx = PLLCX_RESET_BIT, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllc_nmp, + .ext_misc_reg[0] = PLLA1_MISC0, + .ext_misc_reg[1] = PLLA1_MISC1, + .ext_misc_reg[2] = PLLA1_MISC2, + .ext_misc_reg[3] = PLLA1_MISC3, + .freq_table = pll_cx_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = _plla1_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +static struct div_nmp plla_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 5, +}; + +static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { + { 12000000, 282240000, 47, 1, 1, 1, 0xf148 }, /* actual: 282240234 */ + { 12000000, 368640000, 61, 1, 1, 1, 0xfe15 }, /* actual: 368640381 */ + { 12000000, 240000000, 60, 1, 2, 1, 0 }, + { 13000000, 282240000, 43, 1, 1, 1, 0xfd7d }, /* actual: 282239807 */ + { 13000000, 368640000, 56, 1, 1, 1, 0x06d8 }, /* actual: 368640137 */ + { 13000000, 240000000, 55, 1, 2, 1, 0 }, /* actual: 238.3 MHz */ + { 38400000, 282240000, 44, 3, 1, 1, 0xf333 }, /* actual: 282239844 */ + { 38400000, 368640000, 57, 3, 1, 1, 0x0333 }, /* actual: 368639844 */ + { 38400000, 240000000, 75, 3, 3, 1, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_a_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 500000000, + .vco_max = 1000000000, + .base_reg = PLLA_BASE, + .misc_reg = PLLA_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLA_MISC_LOCK_ENABLE, + .lock_delay = 300, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .iddq_reg = PLLA_BASE, + .iddq_bit_idx = PLLA_IDDQ_BIT, + .div_nmp = &plla_nmp, + .sdm_din_reg = PLLA_MISC1, + .sdm_din_mask = PLLA_SDM_DIN_MASK, + .sdm_ctrl_reg = PLLA_MISC2, + .sdm_ctrl_en_mask = PLLA_SDM_EN_MASK, + .ext_misc_reg[0] = PLLA_MISC0, + .ext_misc_reg[1] = PLLA_MISC1, + .ext_misc_reg[2] = PLLA_MISC2, + .freq_table = pll_a_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_MDIV_NEW | + TEGRA_PLL_HAS_LOCK_ENABLE, + .set_defaults = tegra210_plla_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, + .set_gain = tegra210_clk_pll_set_gain, + .adjust_vco = tegra210_clk_adjust_vco_min, +}; + +static struct div_nmp plld_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 11, + .divn_width = 8, + .divp_shift = 20, + .divp_width = 3, +}; + +static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { + { 12000000, 594000000, 99, 1, 1, 0, 0 }, + { 13000000, 594000000, 91, 1, 1, 0, 0xfc4f }, /* actual: 594000183 */ + { 38400000, 594000000, 30, 1, 1, 0, 0x0e00 }, + { 0, 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_d_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 38400000, + .vco_min = 750000000, + .vco_max = 1500000000, + .base_reg = PLLD_BASE, + .misc_reg = PLLD_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLD_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .iddq_reg = PLLD_MISC0, + .iddq_bit_idx = PLLD_IDDQ_BIT, + .round_p_to_pdiv = pll_expo_p_to_pdiv, + .pdiv_tohw = pll_expo_pdiv_to_hw, + .div_nmp = &plld_nmp, + .sdm_din_reg = PLLD_MISC0, + .sdm_din_mask = PLLA_SDM_DIN_MASK, + .sdm_ctrl_reg = PLLD_MISC0, + .sdm_ctrl_en_mask = PLLD_SDM_EN_MASK, + .ext_misc_reg[0] = PLLD_MISC0, + .ext_misc_reg[1] = PLLD_MISC1, + .freq_table = pll_d_freq_table, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .mdiv_default = 1, + .set_defaults = tegra210_plld_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, + .set_gain = tegra210_clk_pll_set_gain, + .adjust_vco = tegra210_clk_adjust_vco_min, +}; + +static struct tegra_clk_pll_freq_table tegra210_pll_d2_freq_table[] = { + { 12000000, 594000000, 99, 1, 1, 0, 0xf000 }, + { 13000000, 594000000, 91, 1, 1, 0, 0xfc4f }, /* actual: 594000183 */ + { 38400000, 594000000, 30, 1, 1, 0, 0x0e00 }, + { 0, 0, 0, 0, 0, 0, 0 }, +}; + +/* s/w policy, always tegra_pll_ref */ +static struct tegra_clk_pll_params pll_d2_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 38400000, + .vco_min = 750000000, + .vco_max = 1500000000, + .base_reg = PLLD2_BASE, + .misc_reg = PLLD2_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLD2_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .sdm_din_reg = PLLD2_MISC3, + .sdm_din_mask = PLLA_SDM_DIN_MASK, + .sdm_ctrl_reg = PLLD2_MISC1, + .sdm_ctrl_en_mask = PLLD2_SDM_EN_MASK, + .ssc_ctrl_reg = PLLD2_MISC1, + .ssc_ctrl_en_mask = PLLD2_SSC_EN_MASK, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = PLLD2_MISC0, + .ext_misc_reg[1] = PLLD2_MISC1, + .ext_misc_reg[2] = PLLD2_MISC2, + .ext_misc_reg[3] = PLLD2_MISC3, + .max_p = PLL_QLIN_PDIV_MAX, + .mdiv_default = 1, + .freq_table = tegra210_pll_d2_freq_table, + .set_defaults = tegra210_plld2_set_defaults, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, + .set_gain = tegra210_clk_pll_set_gain, + .adjust_vco = tegra210_clk_adjust_vco_min, +}; + +static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { + { 12000000, 270000000, 90, 1, 3, 0, 0xf000 }, + { 13000000, 270000000, 83, 1, 3, 0, 0xf000 }, /* actual: 269.8 MHz */ + { 38400000, 270000000, 28, 1, 3, 0, 0xf400 }, + { 0, 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_dp_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 38400000, + .vco_min = 750000000, + .vco_max = 1500000000, + .base_reg = PLLDP_BASE, + .misc_reg = PLLDP_MISC, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLDP_BASE, + .iddq_bit_idx = PLLSS_IDDQ_BIT, + .sdm_din_reg = PLLDP_SS_CTRL2, + .sdm_din_mask = PLLA_SDM_DIN_MASK, + .sdm_ctrl_reg = PLLDP_SS_CFG, + .sdm_ctrl_en_mask = PLLDP_SDM_EN_MASK, + .ssc_ctrl_reg = PLLDP_SS_CFG, + .ssc_ctrl_en_mask = PLLDP_SSC_EN_MASK, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllss_nmp, + .ext_misc_reg[0] = PLLDP_MISC, + .ext_misc_reg[1] = PLLDP_SS_CFG, + .ext_misc_reg[2] = PLLDP_SS_CTRL1, + .ext_misc_reg[3] = PLLDP_SS_CTRL2, + .max_p = PLL_QLIN_PDIV_MAX, + .mdiv_default = 1, + .freq_table = pll_dp_freq_table, + .set_defaults = tegra210_plldp_set_defaults, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, + .set_gain = tegra210_clk_pll_set_gain, + .adjust_vco = tegra210_clk_adjust_vco_min, +}; + +static struct div_nmp pllu_nmp = { + .divm_shift = 0, + .divm_width = 8, + .divn_shift = 8, + .divn_width = 8, + .divp_shift = 16, + .divp_width = 5, +}; + +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { + { 12000000, 480000000, 40, 1, 0, 0 }, + { 13000000, 480000000, 36, 1, 0, 0 }, /* actual: 468.0 MHz */ + { 38400000, 480000000, 25, 2, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_u_vco_params = { + .input_min = 9600000, + .input_max = 800000000, + .cf_min = 9600000, + .cf_max = 19200000, + .vco_min = 350000000, + .vco_max = 700000000, + .base_reg = PLLU_BASE, + .misc_reg = PLLU_MISC0, + .lock_mask = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLU_MISC_LOCK_ENABLE, + .lock_delay = 1000, + .iddq_reg = PLLU_MISC0, + .iddq_bit_idx = PLLU_IDDQ_BIT, + .ext_misc_reg[0] = PLLU_MISC0, + .ext_misc_reg[1] = PLLU_MISC1, + .round_p_to_pdiv = pll_qlin_p_to_pdiv, + .pdiv_tohw = pll_qlin_pdiv_to_hw, + .div_nmp = &pllu_nmp, + .freq_table = pll_u_freq_table, + .flags = TEGRA_PLLU | TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_VCO_OUT, + .set_defaults = tegra210_pllu_set_defaults, + .calc_rate = tegra210_pll_fixed_mdiv_cfg, +}; + +struct utmi_clk_param { + /* Oscillator Frequency in KHz */ + u32 osc_frequency; + /* UTMIP PLL Enable Delay Count */ + u8 enable_delay_count; + /* UTMIP PLL Stable count */ + u16 stable_count; + /* UTMIP PLL Active delay count */ + u8 active_delay_count; + /* UTMIP PLL Xtal frequency count */ + u16 xtal_freq_count; +}; + +static const struct utmi_clk_param utmi_parameters[] = { + { + .osc_frequency = 38400000, .enable_delay_count = 0x0, + .stable_count = 0x0, .active_delay_count = 0x6, + .xtal_freq_count = 0x80 + }, { + .osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7f + }, { + .osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4b, .active_delay_count = 0x06, + .xtal_freq_count = 0xbb + }, { + .osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2f, .active_delay_count = 0x08, + .xtal_freq_count = 0x76 + }, { + .osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xfe + }, { + .osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0a, + .xtal_freq_count = 0xa4 + }, +}; + +static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { + [tegra_clk_ispb] = { .dt_id = TEGRA210_CLK_ISPB, .present = true }, + [tegra_clk_rtc] = { .dt_id = TEGRA210_CLK_RTC, .present = true }, + [tegra_clk_timer] = { .dt_id = TEGRA210_CLK_TIMER, .present = true }, + [tegra_clk_uarta_8] = { .dt_id = TEGRA210_CLK_UARTA, .present = true }, + [tegra_clk_sdmmc2_9] = { .dt_id = TEGRA210_CLK_SDMMC2, .present = true }, + [tegra_clk_i2s1] = { .dt_id = TEGRA210_CLK_I2S1, .present = true }, + [tegra_clk_i2c1] = { .dt_id = TEGRA210_CLK_I2C1, .present = true }, + [tegra_clk_sdmmc1_9] = { .dt_id = TEGRA210_CLK_SDMMC1, .present = true }, + [tegra_clk_sdmmc4_9] = { .dt_id = TEGRA210_CLK_SDMMC4, .present = true }, + [tegra_clk_pwm] = { .dt_id = TEGRA210_CLK_PWM, .present = true }, + [tegra_clk_i2s2] = { .dt_id = TEGRA210_CLK_I2S2, .present = true }, + [tegra_clk_usbd] = { .dt_id = TEGRA210_CLK_USBD, .present = true }, + [tegra_clk_isp_9] = { .dt_id = TEGRA210_CLK_ISP, .present = true }, + [tegra_clk_disp2_8] = { .dt_id = TEGRA210_CLK_DISP2, .present = true }, + [tegra_clk_disp1_8] = { .dt_id = TEGRA210_CLK_DISP1, .present = true }, + [tegra_clk_host1x_9] = { .dt_id = TEGRA210_CLK_HOST1X, .present = true }, + [tegra_clk_i2s0] = { .dt_id = TEGRA210_CLK_I2S0, .present = true }, + [tegra_clk_apbdma] = { .dt_id = TEGRA210_CLK_APBDMA, .present = true }, + [tegra_clk_kfuse] = { .dt_id = TEGRA210_CLK_KFUSE, .present = true }, + [tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .present = true }, + [tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .present = true }, + [tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .present = true }, + [tegra_clk_i2c5] = { .dt_id = TEGRA210_CLK_I2C5, .present = true }, + [tegra_clk_csi] = { .dt_id = TEGRA210_CLK_CSI, .present = true }, + [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true }, + [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true }, + [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true }, + [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true }, + [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true }, + [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true }, + [tegra_clk_i2c3] = { .dt_id = TEGRA210_CLK_I2C3, .present = true }, + [tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .present = true }, + [tegra_clk_sdmmc3_9] = { .dt_id = TEGRA210_CLK_SDMMC3, .present = true }, + [tegra_clk_pcie] = { .dt_id = TEGRA210_CLK_PCIE, .present = true }, + [tegra_clk_owr_8] = { .dt_id = TEGRA210_CLK_OWR, .present = true }, + [tegra_clk_afi] = { .dt_id = TEGRA210_CLK_AFI, .present = true }, + [tegra_clk_csite_8] = { .dt_id = TEGRA210_CLK_CSITE, .present = true }, + [tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .present = true }, + [tegra_clk_dtv] = { .dt_id = TEGRA210_CLK_DTV, .present = true }, + [tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .present = true }, + [tegra_clk_tsec_8] = { .dt_id = TEGRA210_CLK_TSEC, .present = true }, + [tegra_clk_xusb_host] = { .dt_id = TEGRA210_CLK_XUSB_HOST, .present = true }, + [tegra_clk_csus] = { .dt_id = TEGRA210_CLK_CSUS, .present = true }, + [tegra_clk_mselect] = { .dt_id = TEGRA210_CLK_MSELECT, .present = true }, + [tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .present = true }, + [tegra_clk_i2s3] = { .dt_id = TEGRA210_CLK_I2S3, .present = true }, + [tegra_clk_i2s4] = { .dt_id = TEGRA210_CLK_I2S4, .present = true }, + [tegra_clk_i2c4] = { .dt_id = TEGRA210_CLK_I2C4, .present = true }, + [tegra_clk_d_audio] = { .dt_id = TEGRA210_CLK_D_AUDIO, .present = true }, + [tegra_clk_hda2codec_2x_8] = { .dt_id = TEGRA210_CLK_HDA2CODEC_2X, .present = true }, + [tegra_clk_spdif_2x] = { .dt_id = TEGRA210_CLK_SPDIF_2X, .present = true }, + [tegra_clk_actmon] = { .dt_id = TEGRA210_CLK_ACTMON, .present = true }, + [tegra_clk_extern1] = { .dt_id = TEGRA210_CLK_EXTERN1, .present = true }, + [tegra_clk_extern2] = { .dt_id = TEGRA210_CLK_EXTERN2, .present = true }, + [tegra_clk_extern3] = { .dt_id = TEGRA210_CLK_EXTERN3, .present = true }, + [tegra_clk_sata_oob_8] = { .dt_id = TEGRA210_CLK_SATA_OOB, .present = true }, + [tegra_clk_sata_8] = { .dt_id = TEGRA210_CLK_SATA, .present = true }, + [tegra_clk_hda_8] = { .dt_id = TEGRA210_CLK_HDA, .present = true }, + [tegra_clk_hda2hdmi] = { .dt_id = TEGRA210_CLK_HDA2HDMI, .present = true }, + [tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .present = true }, + [tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .present = true }, + [tegra_clk_cile] = { .dt_id = TEGRA210_CLK_CILE, .present = true }, + [tegra_clk_dsialp] = { .dt_id = TEGRA210_CLK_DSIALP, .present = true }, + [tegra_clk_dsiblp] = { .dt_id = TEGRA210_CLK_DSIBLP, .present = true }, + [tegra_clk_entropy_8] = { .dt_id = TEGRA210_CLK_ENTROPY, .present = true }, + [tegra_clk_xusb_ss] = { .dt_id = TEGRA210_CLK_XUSB_SS, .present = true }, + [tegra_clk_i2c6] = { .dt_id = TEGRA210_CLK_I2C6, .present = true }, + [tegra_clk_vim2_clk] = { .dt_id = TEGRA210_CLK_VIM2_CLK, .present = true }, + [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true }, + [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true }, + [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, + [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, + [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, + [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, + [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, + [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true }, + [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, + [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, + [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, + [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR, .present = true }, + [tegra_clk_fuse] = { .dt_id = TEGRA210_CLK_FUSE, .present = true }, + [tegra_clk_fuse_burn] = { .dt_id = TEGRA210_CLK_FUSE_BURN, .present = true }, + [tegra_clk_clk_32k] = { .dt_id = TEGRA210_CLK_CLK_32K, .present = true }, + [tegra_clk_clk_m] = { .dt_id = TEGRA210_CLK_CLK_M, .present = true }, + [tegra_clk_clk_m_div2] = { .dt_id = TEGRA210_CLK_CLK_M_DIV2, .present = true }, + [tegra_clk_clk_m_div4] = { .dt_id = TEGRA210_CLK_CLK_M_DIV4, .present = true }, + [tegra_clk_pll_ref] = { .dt_id = TEGRA210_CLK_PLL_REF, .present = true }, + [tegra_clk_pll_c] = { .dt_id = TEGRA210_CLK_PLL_C, .present = true }, + [tegra_clk_pll_c_out1] = { .dt_id = TEGRA210_CLK_PLL_C_OUT1, .present = true }, + [tegra_clk_pll_c2] = { .dt_id = TEGRA210_CLK_PLL_C2, .present = true }, + [tegra_clk_pll_c3] = { .dt_id = TEGRA210_CLK_PLL_C3, .present = true }, + [tegra_clk_pll_m] = { .dt_id = TEGRA210_CLK_PLL_M, .present = true }, + [tegra_clk_pll_m_out1] = { .dt_id = TEGRA210_CLK_PLL_M_OUT1, .present = true }, + [tegra_clk_pll_p] = { .dt_id = TEGRA210_CLK_PLL_P, .present = true }, + [tegra_clk_pll_p_out1] = { .dt_id = TEGRA210_CLK_PLL_P_OUT1, .present = true }, + [tegra_clk_pll_p_out3] = { .dt_id = TEGRA210_CLK_PLL_P_OUT3, .present = true }, + [tegra_clk_pll_p_out4_cpu] = { .dt_id = TEGRA210_CLK_PLL_P_OUT4, .present = true }, + [tegra_clk_pll_p_out_hsio] = { .dt_id = TEGRA210_CLK_PLL_P_OUT_HSIO, .present = true }, + [tegra_clk_pll_p_out_xusb] = { .dt_id = TEGRA210_CLK_PLL_P_OUT_XUSB, .present = true }, + [tegra_clk_pll_p_out_cpu] = { .dt_id = TEGRA210_CLK_PLL_P_OUT_CPU, .present = true }, + [tegra_clk_pll_p_out_adsp] = { .dt_id = TEGRA210_CLK_PLL_P_OUT_ADSP, .present = true }, + [tegra_clk_pll_a] = { .dt_id = TEGRA210_CLK_PLL_A, .present = true }, + [tegra_clk_pll_a_out0] = { .dt_id = TEGRA210_CLK_PLL_A_OUT0, .present = true }, + [tegra_clk_pll_d] = { .dt_id = TEGRA210_CLK_PLL_D, .present = true }, + [tegra_clk_pll_d_out0] = { .dt_id = TEGRA210_CLK_PLL_D_OUT0, .present = true }, + [tegra_clk_pll_d2] = { .dt_id = TEGRA210_CLK_PLL_D2, .present = true }, + [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA210_CLK_PLL_D2_OUT0, .present = true }, + [tegra_clk_pll_u] = { .dt_id = TEGRA210_CLK_PLL_U, .present = true }, + [tegra_clk_pll_u_out] = { .dt_id = TEGRA210_CLK_PLL_U_OUT, .present = true }, + [tegra_clk_pll_u_out1] = { .dt_id = TEGRA210_CLK_PLL_U_OUT1, .present = true }, + [tegra_clk_pll_u_out2] = { .dt_id = TEGRA210_CLK_PLL_U_OUT2, .present = true }, + [tegra_clk_pll_u_480m] = { .dt_id = TEGRA210_CLK_PLL_U_480M, .present = true }, + [tegra_clk_pll_u_60m] = { .dt_id = TEGRA210_CLK_PLL_U_60M, .present = true }, + [tegra_clk_pll_u_48m] = { .dt_id = TEGRA210_CLK_PLL_U_48M, .present = true }, + [tegra_clk_pll_x] = { .dt_id = TEGRA210_CLK_PLL_X, .present = true }, + [tegra_clk_pll_x_out0] = { .dt_id = TEGRA210_CLK_PLL_X_OUT0, .present = true }, + [tegra_clk_pll_re_vco] = { .dt_id = TEGRA210_CLK_PLL_RE_VCO, .present = true }, + [tegra_clk_pll_re_out] = { .dt_id = TEGRA210_CLK_PLL_RE_OUT, .present = true }, + [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC, .present = true }, + [tegra_clk_i2s0_sync] = { .dt_id = TEGRA210_CLK_I2S0_SYNC, .present = true }, + [tegra_clk_i2s1_sync] = { .dt_id = TEGRA210_CLK_I2S1_SYNC, .present = true }, + [tegra_clk_i2s2_sync] = { .dt_id = TEGRA210_CLK_I2S2_SYNC, .present = true }, + [tegra_clk_i2s3_sync] = { .dt_id = TEGRA210_CLK_I2S3_SYNC, .present = true }, + [tegra_clk_i2s4_sync] = { .dt_id = TEGRA210_CLK_I2S4_SYNC, .present = true }, + [tegra_clk_vimclk_sync] = { .dt_id = TEGRA210_CLK_VIMCLK_SYNC, .present = true }, + [tegra_clk_audio0] = { .dt_id = TEGRA210_CLK_AUDIO0, .present = true }, + [tegra_clk_audio1] = { .dt_id = TEGRA210_CLK_AUDIO1, .present = true }, + [tegra_clk_audio2] = { .dt_id = TEGRA210_CLK_AUDIO2, .present = true }, + [tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true }, + [tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true }, + [tegra_clk_spdif] = { .dt_id = TEGRA210_CLK_SPDIF, .present = true }, + [tegra_clk_clk_out_1] = { .dt_id = TEGRA210_CLK_CLK_OUT_1, .present = true }, + [tegra_clk_clk_out_2] = { .dt_id = TEGRA210_CLK_CLK_OUT_2, .present = true }, + [tegra_clk_clk_out_3] = { .dt_id = TEGRA210_CLK_CLK_OUT_3, .present = true }, + [tegra_clk_blink] = { .dt_id = TEGRA210_CLK_BLINK, .present = true }, + [tegra_clk_xusb_gate] = { .dt_id = TEGRA210_CLK_XUSB_GATE, .present = true }, + [tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true }, + [tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true }, + [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA210_CLK_XUSB_FS_SRC, .present = true }, + [tegra_clk_xusb_ss_src_8] = { .dt_id = TEGRA210_CLK_XUSB_SS_SRC, .present = true }, + [tegra_clk_xusb_ss_div2] = { .dt_id = TEGRA210_CLK_XUSB_SS_DIV2, .present = true }, + [tegra_clk_xusb_dev_src_8] = { .dt_id = TEGRA210_CLK_XUSB_DEV_SRC, .present = true }, + [tegra_clk_xusb_dev] = { .dt_id = TEGRA210_CLK_XUSB_DEV, .present = true }, + [tegra_clk_xusb_hs_src_4] = { .dt_id = TEGRA210_CLK_XUSB_HS_SRC, .present = true }, + [tegra_clk_xusb_ssp_src] = { .dt_id = TEGRA210_CLK_XUSB_SSP_SRC, .present = true }, + [tegra_clk_usb2_hsic_trk] = { .dt_id = TEGRA210_CLK_USB2_HSIC_TRK, .present = true }, + [tegra_clk_hsic_trk] = { .dt_id = TEGRA210_CLK_HSIC_TRK, .present = true }, + [tegra_clk_usb2_trk] = { .dt_id = TEGRA210_CLK_USB2_TRK, .present = true }, + [tegra_clk_sclk] = { .dt_id = TEGRA210_CLK_SCLK, .present = true }, + [tegra_clk_sclk_mux] = { .dt_id = TEGRA210_CLK_SCLK_MUX, .present = true }, + [tegra_clk_hclk] = { .dt_id = TEGRA210_CLK_HCLK, .present = true }, + [tegra_clk_pclk] = { .dt_id = TEGRA210_CLK_PCLK, .present = true }, + [tegra_clk_cclk_g] = { .dt_id = TEGRA210_CLK_CCLK_G, .present = true }, + [tegra_clk_cclk_lp] = { .dt_id = TEGRA210_CLK_CCLK_LP, .present = true }, + [tegra_clk_dfll_ref] = { .dt_id = TEGRA210_CLK_DFLL_REF, .present = true }, + [tegra_clk_dfll_soc] = { .dt_id = TEGRA210_CLK_DFLL_SOC, .present = true }, + [tegra_clk_vi_sensor2_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR2, .present = true }, + [tegra_clk_pll_p_out5] = { .dt_id = TEGRA210_CLK_PLL_P_OUT5, .present = true }, + [tegra_clk_pll_c4] = { .dt_id = TEGRA210_CLK_PLL_C4, .present = true }, + [tegra_clk_pll_dp] = { .dt_id = TEGRA210_CLK_PLL_DP, .present = true }, + [tegra_clk_audio0_mux] = { .dt_id = TEGRA210_CLK_AUDIO0_MUX, .present = true }, + [tegra_clk_audio1_mux] = { .dt_id = TEGRA210_CLK_AUDIO1_MUX, .present = true }, + [tegra_clk_audio2_mux] = { .dt_id = TEGRA210_CLK_AUDIO2_MUX, .present = true }, + [tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true }, + [tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true }, + [tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true }, + [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_1_MUX, .present = true }, + [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_2_MUX, .present = true }, + [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_3_MUX, .present = true }, + [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true }, + [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true }, + [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true }, + [tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .present = true }, + [tegra_clk_tsecb] = { .dt_id = TEGRA210_CLK_TSECB, .present = true }, + [tegra_clk_uartape] = { .dt_id = TEGRA210_CLK_UARTAPE, .present = true }, + [tegra_clk_vi_i2c] = { .dt_id = TEGRA210_CLK_VI_I2C, .present = true }, + [tegra_clk_ape] = { .dt_id = TEGRA210_CLK_APE, .present = true }, + [tegra_clk_dbgapb] = { .dt_id = TEGRA210_CLK_DBGAPB, .present = true }, + [tegra_clk_nvdec] = { .dt_id = TEGRA210_CLK_NVDEC, .present = true }, + [tegra_clk_nvenc] = { .dt_id = TEGRA210_CLK_NVENC, .present = true }, + [tegra_clk_nvjpg] = { .dt_id = TEGRA210_CLK_NVJPG, .present = true }, + [tegra_clk_pll_c4_out0] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT0, .present = true }, + [tegra_clk_pll_c4_out1] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT1, .present = true }, + [tegra_clk_pll_c4_out2] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT2, .present = true }, + [tegra_clk_pll_c4_out3] = { .dt_id = TEGRA210_CLK_PLL_C4_OUT3, .present = true }, +}; + +static struct tegra_devclk devclks[] __initdata = { + { .con_id = "clk_m", .dt_id = TEGRA210_CLK_CLK_M }, + { .con_id = "pll_ref", .dt_id = TEGRA210_CLK_PLL_REF }, + { .con_id = "clk_32k", .dt_id = TEGRA210_CLK_CLK_32K }, + { .con_id = "clk_m_div2", .dt_id = TEGRA210_CLK_CLK_M_DIV2 }, + { .con_id = "clk_m_div4", .dt_id = TEGRA210_CLK_CLK_M_DIV4 }, + { .con_id = "pll_c", .dt_id = TEGRA210_CLK_PLL_C }, + { .con_id = "pll_c_out1", .dt_id = TEGRA210_CLK_PLL_C_OUT1 }, + { .con_id = "pll_c2", .dt_id = TEGRA210_CLK_PLL_C2 }, + { .con_id = "pll_c3", .dt_id = TEGRA210_CLK_PLL_C3 }, + { .con_id = "pll_p", .dt_id = TEGRA210_CLK_PLL_P }, + { .con_id = "pll_p_out1", .dt_id = TEGRA210_CLK_PLL_P_OUT1 }, + { .con_id = "pll_p_out2", .dt_id = TEGRA210_CLK_PLL_P_OUT2 }, + { .con_id = "pll_p_out3", .dt_id = TEGRA210_CLK_PLL_P_OUT3 }, + { .con_id = "pll_p_out4", .dt_id = TEGRA210_CLK_PLL_P_OUT4 }, + { .con_id = "pll_m", .dt_id = TEGRA210_CLK_PLL_M }, + { .con_id = "pll_m_out1", .dt_id = TEGRA210_CLK_PLL_M_OUT1 }, + { .con_id = "pll_x", .dt_id = TEGRA210_CLK_PLL_X }, + { .con_id = "pll_x_out0", .dt_id = TEGRA210_CLK_PLL_X_OUT0 }, + { .con_id = "pll_u", .dt_id = TEGRA210_CLK_PLL_U }, + { .con_id = "pll_u_out", .dt_id = TEGRA210_CLK_PLL_U_OUT }, + { .con_id = "pll_u_out1", .dt_id = TEGRA210_CLK_PLL_U_OUT1 }, + { .con_id = "pll_u_out2", .dt_id = TEGRA210_CLK_PLL_U_OUT2 }, + { .con_id = "pll_u_480M", .dt_id = TEGRA210_CLK_PLL_U_480M }, + { .con_id = "pll_u_60M", .dt_id = TEGRA210_CLK_PLL_U_60M }, + { .con_id = "pll_u_48M", .dt_id = TEGRA210_CLK_PLL_U_48M }, + { .con_id = "pll_d", .dt_id = TEGRA210_CLK_PLL_D }, + { .con_id = "pll_d_out0", .dt_id = TEGRA210_CLK_PLL_D_OUT0 }, + { .con_id = "pll_d2", .dt_id = TEGRA210_CLK_PLL_D2 }, + { .con_id = "pll_d2_out0", .dt_id = TEGRA210_CLK_PLL_D2_OUT0 }, + { .con_id = "pll_a", .dt_id = TEGRA210_CLK_PLL_A }, + { .con_id = "pll_a_out0", .dt_id = TEGRA210_CLK_PLL_A_OUT0 }, + { .con_id = "pll_re_vco", .dt_id = TEGRA210_CLK_PLL_RE_VCO }, + { .con_id = "pll_re_out", .dt_id = TEGRA210_CLK_PLL_RE_OUT }, + { .con_id = "spdif_in_sync", .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC }, + { .con_id = "i2s0_sync", .dt_id = TEGRA210_CLK_I2S0_SYNC }, + { .con_id = "i2s1_sync", .dt_id = TEGRA210_CLK_I2S1_SYNC }, + { .con_id = "i2s2_sync", .dt_id = TEGRA210_CLK_I2S2_SYNC }, + { .con_id = "i2s3_sync", .dt_id = TEGRA210_CLK_I2S3_SYNC }, + { .con_id = "i2s4_sync", .dt_id = TEGRA210_CLK_I2S4_SYNC }, + { .con_id = "vimclk_sync", .dt_id = TEGRA210_CLK_VIMCLK_SYNC }, + { .con_id = "audio0", .dt_id = TEGRA210_CLK_AUDIO0 }, + { .con_id = "audio1", .dt_id = TEGRA210_CLK_AUDIO1 }, + { .con_id = "audio2", .dt_id = TEGRA210_CLK_AUDIO2 }, + { .con_id = "audio3", .dt_id = TEGRA210_CLK_AUDIO3 }, + { .con_id = "audio4", .dt_id = TEGRA210_CLK_AUDIO4 }, + { .con_id = "spdif", .dt_id = TEGRA210_CLK_SPDIF }, + { .con_id = "spdif_2x", .dt_id = TEGRA210_CLK_SPDIF_2X }, + { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA210_CLK_EXTERN1 }, + { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA210_CLK_EXTERN2 }, + { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA210_CLK_EXTERN3 }, + { .con_id = "blink", .dt_id = TEGRA210_CLK_BLINK }, + { .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G }, + { .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP }, + { .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK }, + { .con_id = "hclk", .dt_id = TEGRA210_CLK_HCLK }, + { .con_id = "pclk", .dt_id = TEGRA210_CLK_PCLK }, + { .con_id = "fuse", .dt_id = TEGRA210_CLK_FUSE }, + { .dev_id = "rtc-tegra", .dt_id = TEGRA210_CLK_RTC }, + { .dev_id = "timer", .dt_id = TEGRA210_CLK_TIMER }, + { .con_id = "pll_c4_out0", .dt_id = TEGRA210_CLK_PLL_C4_OUT0 }, + { .con_id = "pll_c4_out1", .dt_id = TEGRA210_CLK_PLL_C4_OUT1 }, + { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 }, + { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 }, + { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX }, + { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 }, +}; + +static struct tegra_audio_clk_info tegra210_audio_plls[] = { + { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_ref" }, + { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, +}; + +static struct clk **clks; + +static void tegra210_utmi_param_configure(void __iomem *clk_base) +{ + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { + if (osc_freq == utmi_parameters[i].osc_frequency) + break; + } + + if (i >= ARRAY_SIZE(utmi_parameters)) { + pr_err("%s: Unexpected oscillator freq %lu\n", __func__, + osc_freq); + return; + } + + reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0); + reg |= PLLU_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE | + PLLU_HW_PWRDN_CFG0_USE_SWITCH_DETECT | + PLLU_HW_PWRDN_CFG0_USE_LOCKDET; + reg &= ~(PLLU_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL | + PLLU_HW_PWRDN_CFG0_CLK_SWITCH_SWCTL); + writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0); + + reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0); + reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE; + writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0); + udelay(1); + + reg = readl_relaxed(clk_base + PLLU_BASE); + reg &= ~PLLU_BASE_CLKENABLE_USB; + writel_relaxed(reg, clk_base + PLLU_BASE); + + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + udelay(10); + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL stable and active counts */ + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); + reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); + + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i]. + active_delay_count); + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL delay and oscillator frequency counts */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i]. + enable_delay_count); + + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i]. + xtal_freq_count); + + reg |= UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + /* Remove power downs from UTMIP PLL control bits */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + udelay(1); + + /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); + reg |= UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERUP; + reg |= UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERUP; + reg |= UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERUP; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); + + /* Setup HW control of UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + udelay(1); + + reg = readl_relaxed(clk_base + XUSB_PLL_CFG0); + reg &= ~XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY; + writel_relaxed(reg, clk_base + XUSB_PLL_CFG0); + + udelay(1); + + /* Enable HW control UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); +} + +static __init void tegra210_periph_clk_init(void __iomem *clk_base, + void __iomem *pmc_base) +{ + struct clk *clk; + + /* xusb_ss_div2 */ + clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, + 1, 2); + clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk; + + /* pll_d_dsi_out */ + clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, + clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); + clks[TEGRA210_CLK_PLL_D_DSI_OUT] = clk; + + /* dsia */ + clk = tegra_clk_register_periph_gate("dsia", "pll_d_dsi_out", 0, + clk_base, 0, 48, + periph_clk_enb_refcnt); + clks[TEGRA210_CLK_DSIA] = clk; + + /* dsib */ + clk = tegra_clk_register_periph_gate("dsib", "pll_d_dsi_out", 0, + clk_base, 0, 82, + periph_clk_enb_refcnt); + clks[TEGRA210_CLK_DSIB] = clk; + + /* emc mux */ + clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, + ARRAY_SIZE(mux_pllmcp_clkm), 0, + clk_base + CLK_SOURCE_EMC, + 29, 3, 0, &emc_lock); + + clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, + &emc_lock); + clks[TEGRA210_CLK_MC] = clk; + + /* cml0 */ + clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, + 0, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml0", NULL); + clks[TEGRA210_CLK_CML0] = clk; + + /* cml1 */ + clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, + 1, 0, &pll_e_lock); + clk_register_clkdev(clk, "cml1", NULL); + clks[TEGRA210_CLK_CML1] = clk; + + tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params); +} + +static void __init tegra210_pll_init(void __iomem *clk_base, + void __iomem *pmc) +{ + u32 val; + struct clk *clk; + + /* PLLC */ + clk = tegra_clk_register_pllxc_tegra210("pll_c", "pll_ref", clk_base, + pmc, 0, &pll_c_params, NULL); + if (!WARN_ON(IS_ERR(clk))) + clk_register_clkdev(clk, "pll_c", NULL); + clks[TEGRA210_CLK_PLL_C] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c_out1", NULL); + clks[TEGRA210_CLK_PLL_C_OUT1] = clk; + + /* PLLC_UD */ + clk = clk_register_fixed_factor(NULL, "pll_c_ud", "pll_c", + CLK_SET_RATE_PARENT, 1, 1); + clk_register_clkdev(clk, "pll_c_ud", NULL); + clks[TEGRA210_CLK_PLL_C_UD] = clk; + + /* PLLC2 */ + clk = tegra_clk_register_pllc_tegra210("pll_c2", "pll_ref", clk_base, + pmc, 0, &pll_c2_params, NULL); + clk_register_clkdev(clk, "pll_c2", NULL); + clks[TEGRA210_CLK_PLL_C2] = clk; + + /* PLLC3 */ + clk = tegra_clk_register_pllc_tegra210("pll_c3", "pll_ref", clk_base, + pmc, 0, &pll_c3_params, NULL); + clk_register_clkdev(clk, "pll_c3", NULL); + clks[TEGRA210_CLK_PLL_C3] = clk; + + /* PLLM */ + clk = tegra_clk_register_pllm("pll_m", "osc", clk_base, pmc, + CLK_SET_RATE_GATE, &pll_m_params, NULL); + clk_register_clkdev(clk, "pll_m", NULL); + clks[TEGRA210_CLK_PLL_M] = clk; + + /* PLLMB */ + clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base, pmc, + CLK_SET_RATE_GATE, &pll_mb_params, NULL); + clk_register_clkdev(clk, "pll_mb", NULL); + clks[TEGRA210_CLK_PLL_MB] = clk; + + clk_register_clkdev(clk, "pll_m_out1", NULL); + clks[TEGRA210_CLK_PLL_M_OUT1] = clk; + + /* PLLM_UD */ + clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", + CLK_SET_RATE_PARENT, 1, 1); + clk_register_clkdev(clk, "pll_m_ud", NULL); + clks[TEGRA210_CLK_PLL_M_UD] = clk; + + /* PLLU_VCO */ + val = readl(clk_base + pll_u_vco_params.base_reg); + val &= ~BIT(24); /* disable PLLU_OVERRIDE */ + writel(val, clk_base + pll_u_vco_params.base_reg); + + clk = tegra_clk_register_pllre("pll_u_vco", "pll_ref", clk_base, pmc, + 0, &pll_u_vco_params, &pll_u_lock, pll_ref_freq); + clk_register_clkdev(clk, "pll_u_vco", NULL); + clks[TEGRA210_CLK_PLL_U] = clk; + + /* PLLU_OUT */ + clk = clk_register_divider_table(NULL, "pll_u_out", "pll_u_vco", 0, + clk_base + PLLU_BASE, 16, 4, 0, + pll_vco_post_div_table, NULL); + clk_register_clkdev(clk, "pll_u_out", NULL); + clks[TEGRA210_CLK_PLL_U_OUT] = clk; + + /* PLLU_OUT1 */ + clk = tegra_clk_register_divider("pll_u_out1_div", "pll_u_out", + clk_base + PLLU_OUTA, 0, + TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, &pll_u_lock); + clk = tegra_clk_register_pll_out("pll_u_out1", "pll_u_out1_div", + clk_base + PLLU_OUTA, 1, 0, + CLK_SET_RATE_PARENT, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_out1", NULL); + clks[TEGRA210_CLK_PLL_U_OUT1] = clk; + + /* PLLU_OUT2 */ + clk = tegra_clk_register_divider("pll_u_out2_div", "pll_u_out", + clk_base + PLLU_OUTA, 0, + TEGRA_DIVIDER_ROUND_UP, + 24, 8, 1, &pll_u_lock); + clk = tegra_clk_register_pll_out("pll_u_out2", "pll_u_out2_div", + clk_base + PLLU_OUTA, 17, 16, + CLK_SET_RATE_PARENT, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_out2", NULL); + clks[TEGRA210_CLK_PLL_U_OUT2] = clk; + + tegra210_utmi_param_configure(clk_base); + + /* PLLU_480M */ + clk = clk_register_gate(NULL, "pll_u_480M", "pll_u_vco", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 22, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_480M", NULL); + clks[TEGRA210_CLK_PLL_U_480M] = clk; + + /* PLLU_60M */ + clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 23, 0, NULL); + clk_register_clkdev(clk, "pll_u_60M", NULL); + clks[TEGRA210_CLK_PLL_U_60M] = clk; + + /* PLLU_48M */ + clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 25, 0, NULL); + clk_register_clkdev(clk, "pll_u_48M", NULL); + clks[TEGRA210_CLK_PLL_U_48M] = clk; + + /* PLLD */ + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, + &pll_d_params, &pll_d_lock); + clk_register_clkdev(clk, "pll_d", NULL); + clks[TEGRA210_CLK_PLL_D] = clk; + + /* PLLD_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d_out0", NULL); + clks[TEGRA210_CLK_PLL_D_OUT0] = clk; + + /* PLLRE */ + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, + 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); + clk_register_clkdev(clk, "pll_re_vco", NULL); + clks[TEGRA210_CLK_PLL_RE_VCO] = clk; + + clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, + clk_base + PLLRE_BASE, 16, 5, 0, + pll_vco_post_div_table, &pll_re_lock); + clk_register_clkdev(clk, "pll_re_out", NULL); + clks[TEGRA210_CLK_PLL_RE_OUT] = clk; + + /* PLLE */ + clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref", + clk_base, 0, &pll_e_params, NULL); + clk_register_clkdev(clk, "pll_e", NULL); + clks[TEGRA210_CLK_PLL_E] = clk; + + /* PLLC4 */ + clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc, + 0, &pll_c4_vco_params, NULL, pll_ref_freq); + clk_register_clkdev(clk, "pll_c4_vco", NULL); + clks[TEGRA210_CLK_PLL_C4] = clk; + + /* PLLC4_OUT0 */ + clk = clk_register_divider_table(NULL, "pll_c4_out0", "pll_c4_vco", 0, + clk_base + PLLC4_BASE, 19, 4, 0, + pll_vco_post_div_table, NULL); + clk_register_clkdev(clk, "pll_c4_out0", NULL); + clks[TEGRA210_CLK_PLL_C4_OUT0] = clk; + + /* PLLC4_OUT1 */ + clk = clk_register_fixed_factor(NULL, "pll_c4_out1", "pll_c4_vco", + CLK_SET_RATE_PARENT, 1, 3); + clk_register_clkdev(clk, "pll_c4_out1", NULL); + clks[TEGRA210_CLK_PLL_C4_OUT1] = clk; + + /* PLLC4_OUT2 */ + clk = clk_register_fixed_factor(NULL, "pll_c4_out2", "pll_c4_vco", + CLK_SET_RATE_PARENT, 1, 5); + clk_register_clkdev(clk, "pll_c4_out2", NULL); + clks[TEGRA210_CLK_PLL_C4_OUT2] = clk; + + /* PLLC4_OUT3 */ + clk = tegra_clk_register_divider("pll_c4_out3_div", "pll_c4_out0", + clk_base + PLLC4_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c4_out3", "pll_c4_out3_div", + clk_base + PLLC4_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c4_out3", NULL); + clks[TEGRA210_CLK_PLL_C4_OUT3] = clk; + + /* PLLDP */ + clk = tegra_clk_register_pllss_tegra210("pll_dp", "pll_ref", clk_base, + 0, &pll_dp_params, NULL); + clk_register_clkdev(clk, "pll_dp", NULL); + clks[TEGRA210_CLK_PLL_DP] = clk; + + /* PLLD2 */ + clk = tegra_clk_register_pllss_tegra210("pll_d2", "pll_ref", clk_base, + 0, &pll_d2_params, NULL); + clk_register_clkdev(clk, "pll_d2", NULL); + clks[TEGRA210_CLK_PLL_D2] = clk; + + /* PLLD2_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", + CLK_SET_RATE_PARENT, 1, 1); + clk_register_clkdev(clk, "pll_d2_out0", NULL); + clks[TEGRA210_CLK_PLL_D2_OUT0] = clk; + + /* PLLP_OUT2 */ + clk = clk_register_fixed_factor(NULL, "pll_p_out2", "pll_p", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_p_out2", NULL); + clks[TEGRA210_CLK_PLL_P_OUT2] = clk; + +} + +/* Tegra210 CPU clock and reset control functions */ +static void tegra210_wait_cpu_in_reset(u32 cpu) +{ + unsigned int reg; + + do { + reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); + cpu_relax(); + } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ +} + +static void tegra210_disable_cpu_clock(u32 cpu) +{ + /* flow controller would take care in the power sequence. */ +} + +#ifdef CONFIG_PM_SLEEP +static void tegra210_cpu_clock_suspend(void) +{ + /* switch coresite to clk_m, save off original source */ + tegra210_cpu_clk_sctx.clk_csite_src = + readl(clk_base + CLK_SOURCE_CSITE); + writel(3 << 30, clk_base + CLK_SOURCE_CSITE); +} + +static void tegra210_cpu_clock_resume(void) +{ + writel(tegra210_cpu_clk_sctx.clk_csite_src, + clk_base + CLK_SOURCE_CSITE); +} +#endif + +static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { + .wait_for_reset = tegra210_wait_cpu_in_reset, + .disable_clock = tegra210_disable_cpu_clock, +#ifdef CONFIG_PM_SLEEP + .suspend = tegra210_cpu_clock_suspend, + .resume = tegra210_cpu_clock_resume, +#endif +}; + +static const struct of_device_id pmc_match[] __initconst = { + { .compatible = "nvidia,tegra210-pmc" }, + { }, +}; + +static struct tegra_clk_init_table init_table[] __initdata = { + { TEGRA210_CLK_UARTA, TEGRA210_CLK_PLL_P, 408000000, 0 }, + { TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0 }, + { TEGRA210_CLK_UARTC, TEGRA210_CLK_PLL_P, 408000000, 0 }, + { TEGRA210_CLK_UARTD, TEGRA210_CLK_PLL_P, 408000000, 0 }, + { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1 }, + { TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 1 }, + { TEGRA210_CLK_EXTERN1, TEGRA210_CLK_PLL_A_OUT0, 0, 1 }, + { TEGRA210_CLK_CLK_OUT_1_MUX, TEGRA210_CLK_EXTERN1, 0, 1 }, + { TEGRA210_CLK_CLK_OUT_1, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA210_CLK_I2S3, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, + { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 }, + { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 }, + { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, + { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, + { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, + { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, + { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, + { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, + { TEGRA210_CLK_PLL_U_OUT2, TEGRA210_CLK_CLK_MAX, 60000000, 1 }, + { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, + { TEGRA210_CLK_XUSB_FS_SRC, TEGRA210_CLK_PLL_U_48M, 48000000, 0 }, + { TEGRA210_CLK_XUSB_HS_SRC, TEGRA210_CLK_XUSB_SS_SRC, 120000000, 0 }, + { TEGRA210_CLK_XUSB_SSP_SRC, TEGRA210_CLK_XUSB_SS_SRC, 120000000, 0 }, + { TEGRA210_CLK_XUSB_FALCON_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 204000000, 0 }, + { TEGRA210_CLK_XUSB_HOST_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, + { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, + { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 }, + { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 }, + { TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 }, + { TEGRA210_CLK_TSENSOR, TEGRA210_CLK_CLK_M, 400000, 0 }, + { TEGRA210_CLK_I2C1, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_I2C2, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_I2C3, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_I2C4, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_I2C5, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_I2C6, TEGRA210_CLK_PLL_P, 0, 0 }, + { TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0 }, + { TEGRA210_CLK_SOC_THERM, TEGRA210_CLK_PLL_P, 51000000, 0 }, + { TEGRA210_CLK_CCLK_G, TEGRA210_CLK_CLK_MAX, 0, 1 }, + /* This MUST be the last entry. */ + { TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0 }, +}; + +/** + * tegra210_clock_apply_init_table - initialize clocks on Tegra210 SoCs + * + * Program an initial clock rate and enable or disable clocks needed + * by the rest of the kernel, for Tegra210 SoCs. It is intended to be + * called by assigning a pointer to it to tegra_clk_apply_init_table - + * this will be called as an arch_initcall. No return value. + */ +static void __init tegra210_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, TEGRA210_CLK_CLK_MAX); +} + +/** + * tegra210_clock_init - Tegra210-specific clock initialization + * @np: struct device_node * of the DT node for the SoC CAR IP block + * + * Register most SoC clocks for the Tegra210 system-on-chip. Intended + * to be called by the OF init code when a DT node with the + * "nvidia,tegra210-car" string is encountered, and declared with + * CLK_OF_DECLARE. No return value. + */ +static void __init tegra210_clock_init(struct device_node *np) +{ + struct device_node *node; + u32 value, clk_m_div; + + clk_base = of_iomap(np, 0); + if (!clk_base) { + pr_err("ioremap tegra210 CAR failed\n"); + return; + } + + node = of_find_matching_node(NULL, pmc_match); + if (!node) { + pr_err("Failed to find pmc node\n"); + WARN_ON(1); + return; + } + + pmc_base = of_iomap(node, 0); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); + return; + } + + clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, + TEGRA210_CAR_BANK_COUNT); + if (!clks) + return; + + value = clk_readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT; + clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1; + + if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq, + ARRAY_SIZE(tegra210_input_freq), clk_m_div, + &osc_freq, &pll_ref_freq) < 0) + return; + + tegra_fixed_clk_init(tegra210_clks); + tegra210_pll_init(clk_base, pmc_base); + tegra210_periph_clk_init(clk_base, pmc_base); + tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks, + tegra210_audio_plls, + ARRAY_SIZE(tegra210_audio_plls)); + tegra_pmc_clk_init(pmc_base, tegra210_clks); + + /* For Tegra210, PLLD is the only source for DSIA & DSIB */ + value = clk_readl(clk_base + PLLD_BASE); + value &= ~BIT(25); + clk_writel(value, clk_base + PLLD_BASE); + + tegra_clk_apply_init_table = tegra210_clock_apply_init_table; + + tegra_super_clk_gen5_init(clk_base, pmc_base, tegra210_clks, + &pll_x_params); + tegra_add_of_provider(np); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); + + tegra_cpu_car_ops = &tegra210_cpu_car_ops; +} +CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index cb9670ee22a6..4dbcfaec576a 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -242,6 +242,7 @@ struct tegra_clk_pll; * it may be more accurate (especially if SDM present) * TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This * flag indicated that it is PLLMB. + * TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output */ struct tegra_clk_pll_params { unsigned long input_min; @@ -307,6 +308,7 @@ struct tegra_clk_pll_params { #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) #define TEGRA_MDIV_NEW BIT(11) #define TEGRA_PLLMB BIT(12) +#define TEGRA_PLL_VCO_OUT BIT(13) /** * struct tegra_clk_pll - Tegra PLL clock @@ -766,5 +768,6 @@ typedef void (*tegra_clk_apply_init_table_func)(void); extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); +int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); #endif /* TEGRA_CLK_H */ -- cgit v1.2.3 From afff455cf4f2501d30446eefbfd0aecb14b8a0b8 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Jun 2015 17:28:37 -0400 Subject: clk: tegra: pll: Fix issues with rates for VCO PLLs Without this change clk_get_rate would return the final output rather than the VCO output as it would factor in the pdiv when it shouldn't. This will cause problems for all dividers in the subtree of the VCO PLL. Signed-off-by: Andrew Bresticker Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index d00e3289eb79..731c6857c895 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -752,6 +752,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, spin_lock_irqsave(pll->lock, flags); _get_pll_mnp(pll, &old_cfg); + if (pll->params->flags & TEGRA_PLL_VCO_OUT) + cfg.p = old_cfg.p; if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p || old_cfg.sdm_data != cfg.sdm_data) @@ -812,11 +814,15 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, _get_pll_mnp(pll, &cfg); - pdiv = _hw_to_p_div(hw, cfg.p); - if (pdiv < 0) { - WARN(1, "Clock %s has invalid pdiv value : 0x%x\n", - __clk_get_name(hw->clk), cfg.p); + if (pll->params->flags & TEGRA_PLL_VCO_OUT) { pdiv = 1; + } else { + pdiv = _hw_to_p_div(hw, cfg.p); + if (pdiv < 0) { + WARN(1, "Clock %s has invalid pdiv value : 0x%x\n", + clk_hw_get_name(hw), cfg.p); + pdiv = 1; + } } if (pll->params->set_gain) @@ -1103,6 +1109,8 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, spin_lock_irqsave(pll->lock, flags); _get_pll_mnp(pll, &old_cfg); + if (pll->params->flags & TEGRA_PLL_VCO_OUT) + cfg.p = old_cfg.p; if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p) ret = _program_pll(hw, &cfg, rate); -- cgit v1.2.3 From a4ca2b2fe7252032022d14b4efd462161c91165b Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:38 -0400 Subject: clk: tegra: Fix WARN_ON in PLL_RE registration This fixes two things. - Read the correct IDDQ register - Check the correct IDDQ bit position Signed-off-by: Bill Huang Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 731c6857c895..9ca1120262f0 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1735,7 +1735,8 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, val = pll_readl_base(pll); if (val & PLL_BASE_ENABLE) - WARN_ON(val & pll_params->iddq_bit_idx); + WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) & + BIT(pll_params->iddq_bit_idx)); else { int m; -- cgit v1.2.3 From 2d7f61f37731f635af47615a8a331ffe7f884934 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:39 -0400 Subject: clk: tegra: Read correct IDDQ register in PLL_SS registration This fixes a bug in tegra_clk_register_pllss() which mistakenly assume the IDDQ register is the PLL base address. Signed-off-by: Bill Huang Reviewed-by: Benson Leung Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 9ca1120262f0..a534bfab30b3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1934,7 +1934,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, struct clk *clk, *parent; struct tegra_clk_pll_freq_table cfg; unsigned long parent_rate; - u32 val; + u32 val, val_iddq; int i; if (!pll_params->div_nmp) @@ -1981,14 +1981,17 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[2], pll); val = pll_readl_base(pll); + val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); if (val & PLL_BASE_ENABLE) { - if (val & BIT(pll_params->iddq_bit_idx)) { + if (val_iddq & BIT(pll_params->iddq_bit_idx)) { WARN(1, "%s is on but IDDQ set\n", name); kfree(pll); return ERR_PTR(-EINVAL); } - } else - val |= BIT(pll_params->iddq_bit_idx); + } else { + val_iddq |= BIT(pll_params->iddq_bit_idx); + writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); + } val &= ~PLLSS_LOCK_OVERRIDE; pll_writel_base(val, pll); -- cgit v1.2.3