Commit 1c472d8e8284917a7687694effcc7ebb6911b63d

Authored by Paul Walmsley
Committed by Mike Turquette
1 parent 9e60121fd1

clk: tegra: T114: add DFLL DVCO reset control

Add DFLL DVCO reset line control functions to the CAR IP block driver.

The DVCO present in the DFLL IP block has a separate reset line,
exposed via the CAR IP block.  This reset line is asserted upon SoC
reset.  Unless something (such as the DFLL driver) deasserts this
line, the DVCO will not oscillate, although reads and writes to the
DFLL IP block will complete.

Thanks to Aleksandr Frid <afrid@nvidia.com> for identifying this and
saving hours of debugging time.

Signed-off-by: Paul Walmsley <pwalmsley@nvidia.com>
Cc: Aleksandr Frid <afrid@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

Showing 2 changed files with 39 additions and 0 deletions Side-by-side Diff

drivers/clk/tegra/clk-tegra114.c
... ... @@ -29,6 +29,7 @@
29 29 #define RST_DEVICES_L 0x004
30 30 #define RST_DEVICES_H 0x008
31 31 #define RST_DEVICES_U 0x00C
  32 +#define RST_DFLL_DVCO 0x2F4
32 33 #define RST_DEVICES_V 0x358
33 34 #define RST_DEVICES_W 0x35C
34 35 #define RST_DEVICES_X 0x28C
... ... @@ -47,6 +48,9 @@
47 48 #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */
48 49 #define RST_DEVICES_NUM 5
49 50  
  51 +/* RST_DFLL_DVCO bitfields */
  52 +#define DVFS_DFLL_RESET_SHIFT 0
  53 +
50 54 /* CPU_FINETRIM_SELECT and CPU_FINETRIM_DR bitfields */
51 55 #define CPU_FINETRIM_1_FCPU_1 BIT(0) /* fcpu0 */
52 56 #define CPU_FINETRIM_1_FCPU_2 BIT(1) /* fcpu1 */
... ... @@ -2247,6 +2251,39 @@
2247 2251 tegra114_clock_tune_cpu_trimmers_low();
2248 2252 }
2249 2253 EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_init);
  2254 +
  2255 +/**
  2256 + * tegra114_clock_assert_dfll_dvco_reset - assert the DFLL's DVCO reset
  2257 + *
  2258 + * Assert the reset line of the DFLL's DVCO. No return value.
  2259 + */
  2260 +void tegra114_clock_assert_dfll_dvco_reset(void)
  2261 +{
  2262 + u32 v;
  2263 +
  2264 + v = readl_relaxed(clk_base + RST_DFLL_DVCO);
  2265 + v |= (1 << DVFS_DFLL_RESET_SHIFT);
  2266 + writel_relaxed(v, clk_base + RST_DFLL_DVCO);
  2267 + tegra114_car_barrier();
  2268 +}
  2269 +EXPORT_SYMBOL(tegra114_clock_assert_dfll_dvco_reset);
  2270 +
  2271 +/**
  2272 + * tegra114_clock_deassert_dfll_dvco_reset - deassert the DFLL's DVCO reset
  2273 + *
  2274 + * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to
  2275 + * operate. No return value.
  2276 + */
  2277 +void tegra114_clock_deassert_dfll_dvco_reset(void)
  2278 +{
  2279 + u32 v;
  2280 +
  2281 + v = readl_relaxed(clk_base + RST_DFLL_DVCO);
  2282 + v &= ~(1 << DVFS_DFLL_RESET_SHIFT);
  2283 + writel_relaxed(v, clk_base + RST_DFLL_DVCO);
  2284 + tegra114_car_barrier();
  2285 +}
  2286 +EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
2250 2287  
2251 2288 static void __init tegra114_clock_init(struct device_node *np)
2252 2289 {
drivers/clk/tegra/clk.h
... ... @@ -590,6 +590,8 @@
590 590 void tegra114_clock_tune_cpu_trimmers_high(void);
591 591 void tegra114_clock_tune_cpu_trimmers_low(void);
592 592 void tegra114_clock_tune_cpu_trimmers_init(void);
  593 +void tegra114_clock_assert_dfll_dvco_reset(void);
  594 +void tegra114_clock_deassert_dfll_dvco_reset(void);
593 595  
594 596 typedef void (*tegra_clk_apply_init_table_func)(void);
595 597 extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;