6
6
*/
7
7
8
8
#include <linux/clk.h>
9
+ #include <linux/delay.h>
9
10
#include <linux/dma-mapping.h>
10
11
#include <linux/io.h>
11
12
#include <linux/list.h>
12
13
#include <linux/module.h>
13
14
#include <linux/of_device.h>
14
15
#include <linux/of.h>
16
+ #include <linux/pm_runtime.h>
15
17
#include <linux/slab.h>
16
18
19
+ #include <soc/tegra/common.h>
20
+
17
21
#define CREATE_TRACE_POINTS
18
22
#include <trace/events/host1x.h>
19
23
#undef CREATE_TRACE_POINTS
@@ -208,6 +212,9 @@ static void host1x_setup_sid_table(struct host1x *host)
208
212
const struct host1x_info * info = host -> info ;
209
213
unsigned int i ;
210
214
215
+ if (!info -> has_hypervisor )
216
+ return ;
217
+
211
218
for (i = 0 ; i < info -> num_sid_entries ; i ++ ) {
212
219
const struct host1x_sid_entry * entry = & info -> sid_table [i ];
213
220
@@ -365,6 +372,27 @@ static void host1x_iommu_exit(struct host1x *host)
365
372
}
366
373
}
367
374
375
+ static int host1x_get_resets (struct host1x * host )
376
+ {
377
+ int err ;
378
+
379
+ host -> resets [0 ].id = "mc" ;
380
+ host -> resets [1 ].id = "host1x" ;
381
+ host -> nresets = ARRAY_SIZE (host -> resets );
382
+
383
+ err = devm_reset_control_bulk_get_optional_exclusive_released (
384
+ host -> dev , host -> nresets , host -> resets );
385
+ if (err ) {
386
+ dev_err (host -> dev , "failed to get reset: %d\n" , err );
387
+ return err ;
388
+ }
389
+
390
+ if (WARN_ON (!host -> resets [1 ].rstc ))
391
+ return - ENOENT ;
392
+
393
+ return 0 ;
394
+ }
395
+
368
396
static int host1x_probe (struct platform_device * pdev )
369
397
{
370
398
struct host1x * host ;
@@ -442,12 +470,9 @@ static int host1x_probe(struct platform_device *pdev)
442
470
return err ;
443
471
}
444
472
445
- host -> rst = devm_reset_control_get (& pdev -> dev , "host1x" );
446
- if (IS_ERR (host -> rst )) {
447
- err = PTR_ERR (host -> rst );
448
- dev_err (& pdev -> dev , "failed to get reset: %d\n" , err );
473
+ err = host1x_get_resets (host );
474
+ if (err )
449
475
return err ;
450
- }
451
476
452
477
err = host1x_iommu_init (host );
453
478
if (err < 0 ) {
@@ -462,22 +487,10 @@ static int host1x_probe(struct platform_device *pdev)
462
487
goto iommu_exit ;
463
488
}
464
489
465
- err = clk_prepare_enable (host -> clk );
466
- if (err < 0 ) {
467
- dev_err (& pdev -> dev , "failed to enable clock\n" );
468
- goto free_channels ;
469
- }
470
-
471
- err = reset_control_deassert (host -> rst );
472
- if (err < 0 ) {
473
- dev_err (& pdev -> dev , "failed to deassert reset: %d\n" , err );
474
- goto unprepare_disable ;
475
- }
476
-
477
490
err = host1x_syncpt_init (host );
478
491
if (err ) {
479
492
dev_err (& pdev -> dev , "failed to initialize syncpts\n" );
480
- goto reset_assert ;
493
+ goto free_channels ;
481
494
}
482
495
483
496
err = host1x_intr_init (host , syncpt_irq );
@@ -486,10 +499,18 @@ static int host1x_probe(struct platform_device *pdev)
486
499
goto deinit_syncpt ;
487
500
}
488
501
489
- host1x_debug_init (host );
502
+ pm_runtime_enable (& pdev -> dev );
503
+
504
+ err = devm_tegra_core_dev_init_opp_table_common (& pdev -> dev );
505
+ if (err )
506
+ goto pm_disable ;
490
507
491
- if (host -> info -> has_hypervisor )
492
- host1x_setup_sid_table (host );
508
+ /* the driver's code isn't ready yet for the dynamic RPM */
509
+ err = pm_runtime_resume_and_get (& pdev -> dev );
510
+ if (err )
511
+ goto pm_disable ;
512
+
513
+ host1x_debug_init (host );
493
514
494
515
err = host1x_register (host );
495
516
if (err < 0 )
@@ -505,13 +526,14 @@ static int host1x_probe(struct platform_device *pdev)
505
526
host1x_unregister (host );
506
527
deinit_debugfs :
507
528
host1x_debug_deinit (host );
529
+
530
+ pm_runtime_put_sync_suspend (& pdev -> dev );
531
+ pm_disable :
532
+ pm_runtime_disable (& pdev -> dev );
533
+
508
534
host1x_intr_deinit (host );
509
535
deinit_syncpt :
510
536
host1x_syncpt_deinit (host );
511
- reset_assert :
512
- reset_control_assert (host -> rst );
513
- unprepare_disable :
514
- clk_disable_unprepare (host -> clk );
515
537
free_channels :
516
538
host1x_channel_list_free (& host -> channel_list );
517
539
iommu_exit :
@@ -526,20 +548,94 @@ static int host1x_remove(struct platform_device *pdev)
526
548
527
549
host1x_unregister (host );
528
550
host1x_debug_deinit (host );
551
+
552
+ pm_runtime_force_suspend (& pdev -> dev );
553
+
529
554
host1x_intr_deinit (host );
530
555
host1x_syncpt_deinit (host );
531
- reset_control_assert (host -> rst );
532
- clk_disable_unprepare (host -> clk );
533
556
host1x_iommu_exit (host );
534
557
host1x_bo_cache_destroy (& host -> cache );
535
558
536
559
return 0 ;
537
560
}
538
561
562
+ static int __maybe_unused host1x_runtime_suspend (struct device * dev )
563
+ {
564
+ struct host1x * host = dev_get_drvdata (dev );
565
+ int err ;
566
+
567
+ host1x_intr_stop (host );
568
+ host1x_syncpt_save (host );
569
+
570
+ err = reset_control_bulk_assert (host -> nresets , host -> resets );
571
+ if (err ) {
572
+ dev_err (dev , "failed to assert reset: %d\n" , err );
573
+ goto resume_host1x ;
574
+ }
575
+
576
+ usleep_range (1000 , 2000 );
577
+
578
+ clk_disable_unprepare (host -> clk );
579
+ reset_control_bulk_release (host -> nresets , host -> resets );
580
+
581
+ return 0 ;
582
+
583
+ resume_host1x :
584
+ host1x_setup_sid_table (host );
585
+ host1x_syncpt_restore (host );
586
+ host1x_intr_start (host );
587
+
588
+ return err ;
589
+ }
590
+
591
+ static int __maybe_unused host1x_runtime_resume (struct device * dev )
592
+ {
593
+ struct host1x * host = dev_get_drvdata (dev );
594
+ int err ;
595
+
596
+ err = reset_control_bulk_acquire (host -> nresets , host -> resets );
597
+ if (err ) {
598
+ dev_err (dev , "failed to acquire reset: %d\n" , err );
599
+ return err ;
600
+ }
601
+
602
+ err = clk_prepare_enable (host -> clk );
603
+ if (err ) {
604
+ dev_err (dev , "failed to enable clock: %d\n" , err );
605
+ goto release_reset ;
606
+ }
607
+
608
+ err = reset_control_bulk_deassert (host -> nresets , host -> resets );
609
+ if (err < 0 ) {
610
+ dev_err (dev , "failed to deassert reset: %d\n" , err );
611
+ goto disable_clk ;
612
+ }
613
+
614
+ host1x_setup_sid_table (host );
615
+ host1x_syncpt_restore (host );
616
+ host1x_intr_start (host );
617
+
618
+ return 0 ;
619
+
620
+ disable_clk :
621
+ clk_disable_unprepare (host -> clk );
622
+ release_reset :
623
+ reset_control_bulk_release (host -> nresets , host -> resets );
624
+
625
+ return err ;
626
+ }
627
+
628
+ static const struct dev_pm_ops host1x_pm_ops = {
629
+ SET_RUNTIME_PM_OPS (host1x_runtime_suspend , host1x_runtime_resume ,
630
+ NULL )
631
+ /* TODO: add system suspend-resume once driver will be ready for that */
632
+ };
633
+
539
634
static struct platform_driver tegra_host1x_driver = {
540
635
.driver = {
541
636
.name = "tegra-host1x" ,
542
637
.of_match_table = host1x_of_match ,
638
+ .pm = & host1x_pm_ops ,
543
639
},
544
640
.probe = host1x_probe ,
545
641
.remove = host1x_remove ,
0 commit comments