28
28
#include <linux/delay.h>
29
29
#include <linux/phy/omap_control_phy.h>
30
30
#include <linux/of_platform.h>
31
- #include <linux/spinlock.h>
32
31
33
32
#define PLL_STATUS 0x00000004
34
33
#define PLL_GO 0x00000008
@@ -83,10 +82,6 @@ struct ti_pipe3 {
83
82
struct clk * refclk ;
84
83
struct clk * div_clk ;
85
84
struct pipe3_dpll_map * dpll_map ;
86
- bool enabled ;
87
- spinlock_t lock ; /* serialize clock enable/disable */
88
- /* the below flag is needed specifically for SATA */
89
- bool refclk_enabled ;
90
85
};
91
86
92
87
static struct pipe3_dpll_map dpll_map_usb [] = {
@@ -137,6 +132,9 @@ static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
137
132
return NULL ;
138
133
}
139
134
135
+ static int ti_pipe3_enable_clocks (struct ti_pipe3 * phy );
136
+ static void ti_pipe3_disable_clocks (struct ti_pipe3 * phy );
137
+
140
138
static int ti_pipe3_power_off (struct phy * x )
141
139
{
142
140
struct ti_pipe3 * phy = phy_get_drvdata (x );
@@ -217,6 +215,7 @@ static int ti_pipe3_init(struct phy *x)
217
215
u32 val ;
218
216
int ret = 0 ;
219
217
218
+ ti_pipe3_enable_clocks (phy );
220
219
/*
221
220
* Set pcie_pcs register to 0x96 for proper functioning of phy
222
221
* as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table
@@ -250,33 +249,35 @@ static int ti_pipe3_exit(struct phy *x)
250
249
u32 val ;
251
250
unsigned long timeout ;
252
251
253
- /* SATA DPLL can't be powered down due to Errata i783 and PCIe
254
- * does not have internal DPLL
255
- */
256
- if (of_device_is_compatible (phy -> dev -> of_node , "ti,phy-pipe3-sata" ) ||
257
- of_device_is_compatible (phy -> dev -> of_node , "ti,phy-pipe3-pcie" ))
252
+ /* SATA DPLL can't be powered down due to Errata i783 */
253
+ if (of_device_is_compatible (phy -> dev -> of_node , "ti,phy-pipe3-sata" ))
258
254
return 0 ;
259
255
260
- /* Put DPLL in IDLE mode */
261
- val = ti_pipe3_readl (phy -> pll_ctrl_base , PLL_CONFIGURATION2 );
262
- val |= PLL_IDLE ;
263
- ti_pipe3_writel (phy -> pll_ctrl_base , PLL_CONFIGURATION2 , val );
264
-
265
- /* wait for LDO and Oscillator to power down */
266
- timeout = jiffies + msecs_to_jiffies (PLL_IDLE_TIME );
267
- do {
268
- cpu_relax ();
269
- val = ti_pipe3_readl (phy -> pll_ctrl_base , PLL_STATUS );
270
- if ((val & PLL_TICOPWDN ) && (val & PLL_LDOPWDN ))
271
- break ;
272
- } while (!time_after (jiffies , timeout ));
256
+ /* PCIe doesn't have internal DPLL */
257
+ if (!of_device_is_compatible (phy -> dev -> of_node , "ti,phy-pipe3-pcie" )) {
258
+ /* Put DPLL in IDLE mode */
259
+ val = ti_pipe3_readl (phy -> pll_ctrl_base , PLL_CONFIGURATION2 );
260
+ val |= PLL_IDLE ;
261
+ ti_pipe3_writel (phy -> pll_ctrl_base , PLL_CONFIGURATION2 , val );
273
262
274
- if (!(val & PLL_TICOPWDN ) || !(val & PLL_LDOPWDN )) {
275
- dev_err (phy -> dev , "Failed to power down: PLL_STATUS 0x%x\n" ,
276
- val );
277
- return - EBUSY ;
263
+ /* wait for LDO and Oscillator to power down */
264
+ timeout = jiffies + msecs_to_jiffies (PLL_IDLE_TIME );
265
+ do {
266
+ cpu_relax ();
267
+ val = ti_pipe3_readl (phy -> pll_ctrl_base , PLL_STATUS );
268
+ if ((val & PLL_TICOPWDN ) && (val & PLL_LDOPWDN ))
269
+ break ;
270
+ } while (!time_after (jiffies , timeout ));
271
+
272
+ if (!(val & PLL_TICOPWDN ) || !(val & PLL_LDOPWDN )) {
273
+ dev_err (phy -> dev , "Failed to power down: PLL_STATUS 0x%x\n" ,
274
+ val );
275
+ return - EBUSY ;
276
+ }
278
277
}
279
278
279
+ ti_pipe3_disable_clocks (phy );
280
+
280
281
return 0 ;
281
282
}
282
283
static struct phy_ops ops = {
@@ -306,7 +307,6 @@ static int ti_pipe3_probe(struct platform_device *pdev)
306
307
return - ENOMEM ;
307
308
308
309
phy -> dev = & pdev -> dev ;
309
- spin_lock_init (& phy -> lock );
310
310
311
311
if (!of_device_is_compatible (node , "ti,phy-pipe3-pcie" )) {
312
312
match = of_match_device (ti_pipe3_id_table , & pdev -> dev );
@@ -402,6 +402,10 @@ static int ti_pipe3_probe(struct platform_device *pdev)
402
402
403
403
platform_set_drvdata (pdev , phy );
404
404
pm_runtime_enable (phy -> dev );
405
+ /* Prevent auto-disable of refclk for SATA PHY due to Errata i783 */
406
+ if (of_device_is_compatible (node , "ti,phy-pipe3-sata" ))
407
+ if (!IS_ERR (phy -> refclk ))
408
+ clk_prepare_enable (phy -> refclk );
405
409
406
410
generic_phy = devm_phy_create (phy -> dev , NULL , & ops );
407
411
if (IS_ERR (generic_phy ))
@@ -413,160 +417,67 @@ static int ti_pipe3_probe(struct platform_device *pdev)
413
417
if (IS_ERR (phy_provider ))
414
418
return PTR_ERR (phy_provider );
415
419
416
- pm_runtime_get (& pdev -> dev );
417
-
418
420
return 0 ;
419
421
}
420
422
421
423
static int ti_pipe3_remove (struct platform_device * pdev )
422
424
{
423
- if (!pm_runtime_suspended (& pdev -> dev ))
424
- pm_runtime_put (& pdev -> dev );
425
425
pm_runtime_disable (& pdev -> dev );
426
426
427
427
return 0 ;
428
428
}
429
429
430
- #ifdef CONFIG_PM
431
- static int ti_pipe3_enable_refclk (struct ti_pipe3 * phy )
430
+ static int ti_pipe3_enable_clocks (struct ti_pipe3 * phy )
432
431
{
433
- if (!IS_ERR (phy -> refclk ) && !phy -> refclk_enabled ) {
434
- int ret ;
432
+ int ret = 0 ;
435
433
434
+ if (!IS_ERR (phy -> refclk )) {
436
435
ret = clk_prepare_enable (phy -> refclk );
437
436
if (ret ) {
438
437
dev_err (phy -> dev , "Failed to enable refclk %d\n" , ret );
439
438
return ret ;
440
439
}
441
- phy -> refclk_enabled = true;
442
440
}
443
441
444
- return 0 ;
445
- }
446
-
447
- static void ti_pipe3_disable_refclk (struct ti_pipe3 * phy )
448
- {
449
- if (!IS_ERR (phy -> refclk ))
450
- clk_disable_unprepare (phy -> refclk );
451
-
452
- phy -> refclk_enabled = false;
453
- }
454
-
455
- static int ti_pipe3_enable_clocks (struct ti_pipe3 * phy )
456
- {
457
- int ret = 0 ;
458
- unsigned long flags ;
459
-
460
- spin_lock_irqsave (& phy -> lock , flags );
461
- if (phy -> enabled )
462
- goto err1 ;
463
-
464
- ret = ti_pipe3_enable_refclk (phy );
465
- if (ret )
466
- goto err1 ;
467
-
468
442
if (!IS_ERR (phy -> wkupclk )) {
469
443
ret = clk_prepare_enable (phy -> wkupclk );
470
444
if (ret ) {
471
445
dev_err (phy -> dev , "Failed to enable wkupclk %d\n" , ret );
472
- goto err2 ;
446
+ goto disable_refclk ;
473
447
}
474
448
}
475
449
476
450
if (!IS_ERR (phy -> div_clk )) {
477
451
ret = clk_prepare_enable (phy -> div_clk );
478
452
if (ret ) {
479
453
dev_err (phy -> dev , "Failed to enable div_clk %d\n" , ret );
480
- goto err3 ;
454
+ goto disable_wkupclk ;
481
455
}
482
456
}
483
457
484
- phy -> enabled = true;
485
- spin_unlock_irqrestore (& phy -> lock , flags );
486
458
return 0 ;
487
459
488
- err3 :
460
+ disable_wkupclk :
489
461
if (!IS_ERR (phy -> wkupclk ))
490
462
clk_disable_unprepare (phy -> wkupclk );
491
463
492
- err2 :
464
+ disable_refclk :
493
465
if (!IS_ERR (phy -> refclk ))
494
466
clk_disable_unprepare (phy -> refclk );
495
467
496
- ti_pipe3_disable_refclk (phy );
497
- err1 :
498
- spin_unlock_irqrestore (& phy -> lock , flags );
499
468
return ret ;
500
469
}
501
470
502
471
static void ti_pipe3_disable_clocks (struct ti_pipe3 * phy )
503
472
{
504
- unsigned long flags ;
505
-
506
- spin_lock_irqsave (& phy -> lock , flags );
507
- if (!phy -> enabled ) {
508
- spin_unlock_irqrestore (& phy -> lock , flags );
509
- return ;
510
- }
511
-
512
473
if (!IS_ERR (phy -> wkupclk ))
513
474
clk_disable_unprepare (phy -> wkupclk );
514
- /* Don't disable refclk for SATA PHY due to Errata i783 */
515
- if (!of_device_is_compatible (phy -> dev -> of_node , "ti,phy-pipe3-sata" ))
516
- ti_pipe3_disable_refclk (phy );
475
+ if (!IS_ERR (phy -> refclk ))
476
+ clk_disable_unprepare (phy -> refclk );
517
477
if (!IS_ERR (phy -> div_clk ))
518
478
clk_disable_unprepare (phy -> div_clk );
519
- phy -> enabled = false;
520
- spin_unlock_irqrestore (& phy -> lock , flags );
521
- }
522
-
523
- static int ti_pipe3_runtime_suspend (struct device * dev )
524
- {
525
- struct ti_pipe3 * phy = dev_get_drvdata (dev );
526
-
527
- ti_pipe3_disable_clocks (phy );
528
- return 0 ;
529
479
}
530
480
531
- static int ti_pipe3_runtime_resume (struct device * dev )
532
- {
533
- struct ti_pipe3 * phy = dev_get_drvdata (dev );
534
- int ret = 0 ;
535
-
536
- ret = ti_pipe3_enable_clocks (phy );
537
- return ret ;
538
- }
539
-
540
- static int ti_pipe3_suspend (struct device * dev )
541
- {
542
- struct ti_pipe3 * phy = dev_get_drvdata (dev );
543
-
544
- ti_pipe3_disable_clocks (phy );
545
- return 0 ;
546
- }
547
-
548
- static int ti_pipe3_resume (struct device * dev )
549
- {
550
- struct ti_pipe3 * phy = dev_get_drvdata (dev );
551
- int ret ;
552
-
553
- ret = ti_pipe3_enable_clocks (phy );
554
- if (ret )
555
- return ret ;
556
-
557
- pm_runtime_disable (dev );
558
- pm_runtime_set_active (dev );
559
- pm_runtime_enable (dev );
560
- return 0 ;
561
- }
562
- #endif
563
-
564
- static const struct dev_pm_ops ti_pipe3_pm_ops = {
565
- SET_RUNTIME_PM_OPS (ti_pipe3_runtime_suspend ,
566
- ti_pipe3_runtime_resume , NULL )
567
- SET_SYSTEM_SLEEP_PM_OPS (ti_pipe3_suspend , ti_pipe3_resume )
568
- };
569
-
570
481
static const struct of_device_id ti_pipe3_id_table [] = {
571
482
{
572
483
.compatible = "ti,phy-usb3" ,
@@ -592,7 +503,6 @@ static struct platform_driver ti_pipe3_driver = {
592
503
.remove = ti_pipe3_remove ,
593
504
.driver = {
594
505
.name = "ti-pipe3" ,
595
- .pm = & ti_pipe3_pm_ops ,
596
506
.of_match_table = ti_pipe3_id_table ,
597
507
},
598
508
};
0 commit comments