@@ -174,9 +174,9 @@ struct tegra_sor {
174
174
175
175
struct reset_control * rst ;
176
176
struct clk * clk_parent ;
177
- struct clk * clk_brick ;
178
177
struct clk * clk_safe ;
179
- struct clk * clk_src ;
178
+ struct clk * clk_out ;
179
+ struct clk * clk_pad ;
180
180
struct clk * clk_dp ;
181
181
struct clk * clk ;
182
182
@@ -255,7 +255,7 @@ static int tegra_sor_set_parent_clock(struct tegra_sor *sor, struct clk *parent)
255
255
256
256
clk_disable_unprepare (sor -> clk );
257
257
258
- err = clk_set_parent (sor -> clk , parent );
258
+ err = clk_set_parent (sor -> clk_out , parent );
259
259
if (err < 0 )
260
260
return err ;
261
261
@@ -266,24 +266,24 @@ static int tegra_sor_set_parent_clock(struct tegra_sor *sor, struct clk *parent)
266
266
return 0 ;
267
267
}
268
268
269
- struct tegra_clk_sor_brick {
269
+ struct tegra_clk_sor_pad {
270
270
struct clk_hw hw ;
271
271
struct tegra_sor * sor ;
272
272
};
273
273
274
- static inline struct tegra_clk_sor_brick * to_brick (struct clk_hw * hw )
274
+ static inline struct tegra_clk_sor_pad * to_pad (struct clk_hw * hw )
275
275
{
276
- return container_of (hw , struct tegra_clk_sor_brick , hw );
276
+ return container_of (hw , struct tegra_clk_sor_pad , hw );
277
277
}
278
278
279
- static const char * const tegra_clk_sor_brick_parents [] = {
279
+ static const char * const tegra_clk_sor_pad_parents [] = {
280
280
"pll_d2_out0" , "pll_dp"
281
281
};
282
282
283
- static int tegra_clk_sor_brick_set_parent (struct clk_hw * hw , u8 index )
283
+ static int tegra_clk_sor_pad_set_parent (struct clk_hw * hw , u8 index )
284
284
{
285
- struct tegra_clk_sor_brick * brick = to_brick (hw );
286
- struct tegra_sor * sor = brick -> sor ;
285
+ struct tegra_clk_sor_pad * pad = to_pad (hw );
286
+ struct tegra_sor * sor = pad -> sor ;
287
287
u32 value ;
288
288
289
289
value = tegra_sor_readl (sor , SOR_CLK_CNTRL );
@@ -304,10 +304,10 @@ static int tegra_clk_sor_brick_set_parent(struct clk_hw *hw, u8 index)
304
304
return 0 ;
305
305
}
306
306
307
- static u8 tegra_clk_sor_brick_get_parent (struct clk_hw * hw )
307
+ static u8 tegra_clk_sor_pad_get_parent (struct clk_hw * hw )
308
308
{
309
- struct tegra_clk_sor_brick * brick = to_brick (hw );
310
- struct tegra_sor * sor = brick -> sor ;
309
+ struct tegra_clk_sor_pad * pad = to_pad (hw );
310
+ struct tegra_sor * sor = pad -> sor ;
311
311
u8 parent = U8_MAX ;
312
312
u32 value ;
313
313
@@ -328,33 +328,33 @@ static u8 tegra_clk_sor_brick_get_parent(struct clk_hw *hw)
328
328
return parent ;
329
329
}
330
330
331
- static const struct clk_ops tegra_clk_sor_brick_ops = {
332
- .set_parent = tegra_clk_sor_brick_set_parent ,
333
- .get_parent = tegra_clk_sor_brick_get_parent ,
331
+ static const struct clk_ops tegra_clk_sor_pad_ops = {
332
+ .set_parent = tegra_clk_sor_pad_set_parent ,
333
+ .get_parent = tegra_clk_sor_pad_get_parent ,
334
334
};
335
335
336
- static struct clk * tegra_clk_sor_brick_register (struct tegra_sor * sor ,
337
- const char * name )
336
+ static struct clk * tegra_clk_sor_pad_register (struct tegra_sor * sor ,
337
+ const char * name )
338
338
{
339
- struct tegra_clk_sor_brick * brick ;
339
+ struct tegra_clk_sor_pad * pad ;
340
340
struct clk_init_data init ;
341
341
struct clk * clk ;
342
342
343
- brick = devm_kzalloc (sor -> dev , sizeof (* brick ), GFP_KERNEL );
344
- if (!brick )
343
+ pad = devm_kzalloc (sor -> dev , sizeof (* pad ), GFP_KERNEL );
344
+ if (!pad )
345
345
return ERR_PTR (- ENOMEM );
346
346
347
- brick -> sor = sor ;
347
+ pad -> sor = sor ;
348
348
349
349
init .name = name ;
350
350
init .flags = 0 ;
351
- init .parent_names = tegra_clk_sor_brick_parents ;
352
- init .num_parents = ARRAY_SIZE (tegra_clk_sor_brick_parents );
353
- init .ops = & tegra_clk_sor_brick_ops ;
351
+ init .parent_names = tegra_clk_sor_pad_parents ;
352
+ init .num_parents = ARRAY_SIZE (tegra_clk_sor_pad_parents );
353
+ init .ops = & tegra_clk_sor_pad_ops ;
354
354
355
- brick -> hw .init = & init ;
355
+ pad -> hw .init = & init ;
356
356
357
- clk = devm_clk_register (sor -> dev , & brick -> hw );
357
+ clk = devm_clk_register (sor -> dev , & pad -> hw );
358
358
359
359
return clk ;
360
360
}
@@ -998,8 +998,10 @@ static int tegra_sor_power_down(struct tegra_sor *sor)
998
998
999
999
/* switch to safe parent clock */
1000
1000
err = tegra_sor_set_parent_clock (sor , sor -> clk_safe );
1001
- if (err < 0 )
1001
+ if (err < 0 ) {
1002
1002
dev_err (sor -> dev , "failed to set safe parent clock: %d\n" , err );
1003
+ return err ;
1004
+ }
1003
1005
1004
1006
value = tegra_sor_readl (sor , SOR_DP_PADCTL0 );
1005
1007
value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
@@ -2007,8 +2009,10 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
2007
2009
2008
2010
/* switch to safe parent clock */
2009
2011
err = tegra_sor_set_parent_clock (sor , sor -> clk_safe );
2010
- if (err < 0 )
2012
+ if (err < 0 ) {
2011
2013
dev_err (sor -> dev , "failed to set safe parent clock: %d\n" , err );
2014
+ return ;
2015
+ }
2012
2016
2013
2017
div = clk_get_rate (sor -> clk ) / 1000000 * 4 ;
2014
2018
@@ -2111,13 +2115,17 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
2111
2115
tegra_sor_writel (sor , value , SOR_XBAR_CTRL );
2112
2116
2113
2117
/* switch to parent clock */
2114
- err = clk_set_parent (sor -> clk_src , sor -> clk_parent );
2115
- if (err < 0 )
2116
- dev_err (sor -> dev , "failed to set source clock: %d\n" , err );
2117
-
2118
- err = tegra_sor_set_parent_clock (sor , sor -> clk_src );
2119
- if (err < 0 )
2118
+ err = clk_set_parent (sor -> clk , sor -> clk_parent );
2119
+ if (err < 0 ) {
2120
2120
dev_err (sor -> dev , "failed to set parent clock: %d\n" , err );
2121
+ return ;
2122
+ }
2123
+
2124
+ err = tegra_sor_set_parent_clock (sor , sor -> clk_pad );
2125
+ if (err < 0 ) {
2126
+ dev_err (sor -> dev , "failed to set pad clock: %d\n" , err );
2127
+ return ;
2128
+ }
2121
2129
2122
2130
value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT (dc -> pipe );
2123
2131
@@ -2628,11 +2636,24 @@ static int tegra_sor_probe(struct platform_device *pdev)
2628
2636
}
2629
2637
2630
2638
if (sor -> soc -> supports_hdmi || sor -> soc -> supports_dp ) {
2631
- sor -> clk_src = devm_clk_get (& pdev -> dev , "source" );
2632
- if (IS_ERR (sor -> clk_src )) {
2633
- err = PTR_ERR (sor -> clk_src );
2634
- dev_err (sor -> dev , "failed to get source clock: %d\n" ,
2635
- err );
2639
+ struct device_node * np = pdev -> dev .of_node ;
2640
+ const char * name ;
2641
+
2642
+ /*
2643
+ * For backwards compatibility with Tegra210 device trees,
2644
+ * fall back to the old clock name "source" if the new "out"
2645
+ * clock is not available.
2646
+ */
2647
+ if (of_property_match_string (np , "clock-names" , "out" ) < 0 )
2648
+ name = "source" ;
2649
+ else
2650
+ name = "out" ;
2651
+
2652
+ sor -> clk_out = devm_clk_get (& pdev -> dev , name );
2653
+ if (IS_ERR (sor -> clk_out )) {
2654
+ err = PTR_ERR (sor -> clk_out );
2655
+ dev_err (sor -> dev , "failed to get %s clock: %d\n" ,
2656
+ name , err );
2636
2657
goto remove ;
2637
2658
}
2638
2659
}
@@ -2658,16 +2679,60 @@ static int tegra_sor_probe(struct platform_device *pdev)
2658
2679
goto remove ;
2659
2680
}
2660
2681
2682
+ /*
2683
+ * Starting with Tegra186, the BPMP provides an implementation for
2684
+ * the pad output clock, so we have to look it up from device tree.
2685
+ */
2686
+ sor -> clk_pad = devm_clk_get (& pdev -> dev , "pad" );
2687
+ if (IS_ERR (sor -> clk_pad )) {
2688
+ if (sor -> clk_pad != ERR_PTR (- ENOENT )) {
2689
+ err = PTR_ERR (sor -> clk_pad );
2690
+ goto remove ;
2691
+ }
2692
+
2693
+ /*
2694
+ * If the pad output clock is not available, then we assume
2695
+ * we're on Tegra210 or earlier and have to provide our own
2696
+ * implementation.
2697
+ */
2698
+ sor -> clk_pad = NULL ;
2699
+ }
2700
+
2701
+ /*
2702
+ * The bootloader may have set up the SOR such that it's module clock
2703
+ * is sourced by one of the display PLLs. However, that doesn't work
2704
+ * without properly having set up other bits of the SOR.
2705
+ */
2706
+ err = clk_set_parent (sor -> clk_out , sor -> clk_safe );
2707
+ if (err < 0 ) {
2708
+ dev_err (& pdev -> dev , "failed to use safe clock: %d\n" , err );
2709
+ goto remove ;
2710
+ }
2711
+
2661
2712
platform_set_drvdata (pdev , sor );
2662
2713
pm_runtime_enable (& pdev -> dev );
2663
2714
2664
- pm_runtime_get_sync (& pdev -> dev );
2665
- sor -> clk_brick = tegra_clk_sor_brick_register (sor , "sor1_brick" );
2666
- pm_runtime_put (& pdev -> dev );
2715
+ /*
2716
+ * On Tegra210 and earlier, provide our own implementation for the
2717
+ * pad output clock.
2718
+ */
2719
+ if (!sor -> clk_pad ) {
2720
+ err = pm_runtime_get_sync (& pdev -> dev );
2721
+ if (err < 0 ) {
2722
+ dev_err (& pdev -> dev , "failed to get runtime PM: %d\n" ,
2723
+ err );
2724
+ goto remove ;
2725
+ }
2726
+
2727
+ sor -> clk_pad = tegra_clk_sor_pad_register (sor ,
2728
+ "sor1_pad_clkout" );
2729
+ pm_runtime_put (& pdev -> dev );
2730
+ }
2667
2731
2668
- if (IS_ERR (sor -> clk_brick )) {
2669
- err = PTR_ERR (sor -> clk_brick );
2670
- dev_err (& pdev -> dev , "failed to register SOR clock: %d\n" , err );
2732
+ if (IS_ERR (sor -> clk_pad )) {
2733
+ err = PTR_ERR (sor -> clk_pad );
2734
+ dev_err (& pdev -> dev , "failed to register SOR pad clock: %d\n" ,
2735
+ err );
2671
2736
goto remove ;
2672
2737
}
2673
2738
0 commit comments