@@ -1008,13 +1008,35 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
1008
1008
return rate ;
1009
1009
}
1010
1010
1011
+ static void tegra_clk_pll_restore_context (struct clk_hw * hw )
1012
+ {
1013
+ struct tegra_clk_pll * pll = to_clk_pll (hw );
1014
+ struct clk_hw * parent = clk_hw_get_parent (hw );
1015
+ unsigned long parent_rate = clk_hw_get_rate (parent );
1016
+ unsigned long rate = clk_hw_get_rate (hw );
1017
+
1018
+ if (clk_pll_is_enabled (hw ))
1019
+ return ;
1020
+
1021
+ if (pll -> params -> set_defaults )
1022
+ pll -> params -> set_defaults (pll );
1023
+
1024
+ clk_pll_set_rate (hw , rate , parent_rate );
1025
+
1026
+ if (!__clk_get_enable_count (hw -> clk ))
1027
+ clk_pll_disable (hw );
1028
+ else
1029
+ clk_pll_enable (hw );
1030
+ }
1031
+
1011
1032
const struct clk_ops tegra_clk_pll_ops = {
1012
1033
.is_enabled = clk_pll_is_enabled ,
1013
1034
.enable = clk_pll_enable ,
1014
1035
.disable = clk_pll_disable ,
1015
1036
.recalc_rate = clk_pll_recalc_rate ,
1016
1037
.round_rate = clk_pll_round_rate ,
1017
1038
.set_rate = clk_pll_set_rate ,
1039
+ .restore_context = tegra_clk_pll_restore_context ,
1018
1040
};
1019
1041
1020
1042
const struct clk_ops tegra_clk_plle_ops = {
@@ -1802,6 +1824,27 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
1802
1824
1803
1825
return ret ;
1804
1826
}
1827
+
1828
+ static void _clk_plle_tegra_init_parent (struct tegra_clk_pll * pll )
1829
+ {
1830
+ u32 val , val_aux ;
1831
+
1832
+ /* ensure parent is set to pll_ref */
1833
+ val = pll_readl_base (pll );
1834
+ val_aux = pll_readl (pll -> params -> aux_reg , pll );
1835
+
1836
+ if (val & PLL_BASE_ENABLE ) {
1837
+ if ((val_aux & PLLE_AUX_PLLRE_SEL ) ||
1838
+ (val_aux & PLLE_AUX_PLLP_SEL ))
1839
+ WARN (1 , "pll_e enabled with unsupported parent %s\n" ,
1840
+ (val_aux & PLLE_AUX_PLLP_SEL ) ? "pllp_out0" :
1841
+ "pll_re_vco" );
1842
+ } else {
1843
+ val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL );
1844
+ pll_writel (val_aux , pll -> params -> aux_reg , pll );
1845
+ fence_udelay (1 , pll -> clk_base );
1846
+ }
1847
+ }
1805
1848
#endif
1806
1849
1807
1850
static struct tegra_clk_pll * _tegra_init_pll (void __iomem * clk_base ,
@@ -2214,27 +2257,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
2214
2257
{
2215
2258
struct tegra_clk_pll * pll ;
2216
2259
struct clk * clk ;
2217
- u32 val , val_aux ;
2218
2260
2219
2261
pll = _tegra_init_pll (clk_base , NULL , pll_params , lock );
2220
2262
if (IS_ERR (pll ))
2221
2263
return ERR_CAST (pll );
2222
2264
2223
- /* ensure parent is set to pll_re_vco */
2224
-
2225
- val = pll_readl_base (pll );
2226
- val_aux = pll_readl (pll_params -> aux_reg , pll );
2227
-
2228
- if (val & PLL_BASE_ENABLE ) {
2229
- if ((val_aux & PLLE_AUX_PLLRE_SEL ) ||
2230
- (val_aux & PLLE_AUX_PLLP_SEL ))
2231
- WARN (1 , "pll_e enabled with unsupported parent %s\n" ,
2232
- (val_aux & PLLE_AUX_PLLP_SEL ) ? "pllp_out0" :
2233
- "pll_re_vco" );
2234
- } else {
2235
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL );
2236
- pll_writel (val_aux , pll_params -> aux_reg , pll );
2237
- }
2265
+ _clk_plle_tegra_init_parent (pll );
2238
2266
2239
2267
clk = _tegra_clk_register_pll (pll , name , parent_name , flags ,
2240
2268
& tegra_clk_plle_tegra114_ops );
@@ -2276,6 +2304,7 @@ static const struct clk_ops tegra_clk_pllss_ops = {
2276
2304
.recalc_rate = clk_pll_recalc_rate ,
2277
2305
.round_rate = clk_pll_ramp_round_rate ,
2278
2306
.set_rate = clk_pllxc_set_rate ,
2307
+ .restore_context = tegra_clk_pll_restore_context ,
2279
2308
};
2280
2309
2281
2310
struct clk * tegra_clk_register_pllss (const char * name , const char * parent_name ,
@@ -2520,11 +2549,19 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw)
2520
2549
spin_unlock_irqrestore (pll -> lock , flags );
2521
2550
}
2522
2551
2552
+ static void tegra_clk_plle_t210_restore_context (struct clk_hw * hw )
2553
+ {
2554
+ struct tegra_clk_pll * pll = to_clk_pll (hw );
2555
+
2556
+ _clk_plle_tegra_init_parent (pll );
2557
+ }
2558
+
2523
2559
static const struct clk_ops tegra_clk_plle_tegra210_ops = {
2524
2560
.is_enabled = clk_plle_tegra210_is_enabled ,
2525
2561
.enable = clk_plle_tegra210_enable ,
2526
2562
.disable = clk_plle_tegra210_disable ,
2527
2563
.recalc_rate = clk_pll_recalc_rate ,
2564
+ .restore_context = tegra_clk_plle_t210_restore_context ,
2528
2565
};
2529
2566
2530
2567
struct clk * tegra_clk_register_plle_tegra210 (const char * name ,
@@ -2535,27 +2572,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
2535
2572
{
2536
2573
struct tegra_clk_pll * pll ;
2537
2574
struct clk * clk ;
2538
- u32 val , val_aux ;
2539
2575
2540
2576
pll = _tegra_init_pll (clk_base , NULL , pll_params , lock );
2541
2577
if (IS_ERR (pll ))
2542
2578
return ERR_CAST (pll );
2543
2579
2544
- /* ensure parent is set to pll_re_vco */
2545
-
2546
- val = pll_readl_base (pll );
2547
- val_aux = pll_readl (pll_params -> aux_reg , pll );
2548
-
2549
- if (val & PLLE_BASE_ENABLE ) {
2550
- if ((val_aux & PLLE_AUX_PLLRE_SEL ) ||
2551
- (val_aux & PLLE_AUX_PLLP_SEL ))
2552
- WARN (1 , "pll_e enabled with unsupported parent %s\n" ,
2553
- (val_aux & PLLE_AUX_PLLP_SEL ) ? "pllp_out0" :
2554
- "pll_re_vco" );
2555
- } else {
2556
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL );
2557
- pll_writel (val_aux , pll_params -> aux_reg , pll );
2558
- }
2580
+ _clk_plle_tegra_init_parent (pll );
2559
2581
2560
2582
clk = _tegra_clk_register_pll (pll , name , parent_name , flags ,
2561
2583
& tegra_clk_plle_tegra210_ops );
0 commit comments