.. | .. |
---|
31 | 31 | #include <linux/clk.h> |
---|
32 | 32 | #include <linux/regulator/consumer.h> |
---|
33 | 33 | #include <linux/mali/mali_utgard.h> |
---|
| 34 | +#include <linux/pm_runtime.h> |
---|
34 | 35 | #include <soc/rockchip/rockchip_opp_select.h> |
---|
35 | 36 | |
---|
36 | 37 | #include "mali_kernel_common.h" |
---|
.. | .. |
---|
521 | 522 | int err; |
---|
522 | 523 | #ifdef CONFIG_MALI_DEVFREQ |
---|
523 | 524 | struct mali_device *mdev; |
---|
| 525 | + const char *name = "mali"; |
---|
524 | 526 | #endif |
---|
525 | 527 | |
---|
526 | 528 | MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name)); |
---|
.. | .. |
---|
575 | 577 | mdev->regulator = NULL; |
---|
576 | 578 | /* Allow probe to continue without regulator */ |
---|
577 | 579 | } |
---|
| 580 | + if (mdev->regulator) { |
---|
| 581 | + mdev->opp_table = dev_pm_opp_set_regulators(mdev->dev, &name, 1); |
---|
| 582 | + if (IS_ERR(mdev->opp_table)) { |
---|
| 583 | + mdev->opp_table = NULL; |
---|
| 584 | + MALI_DEBUG_PRINT(2, ("Continuing without opp regulator\n")); |
---|
| 585 | + } |
---|
| 586 | + } |
---|
578 | 587 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
| 588 | + |
---|
| 589 | + mdev->num_clks = devm_clk_bulk_get_all(mdev->dev, &mdev->clks); |
---|
| 590 | + if (mdev->num_clks < 1) { |
---|
| 591 | + MALI_DEBUG_PRINT(2, ("Continuing without Mali clock control\n")); |
---|
| 592 | + mdev->num_clks = 0; |
---|
| 593 | + mdev->clock = NULL; |
---|
| 594 | + } else { |
---|
| 595 | + /* Get "clk_mali" in the device tree for gpu dvfs */ |
---|
| 596 | + mdev->clock = clk_get(mdev->dev, "clk_mali"); |
---|
| 597 | + if (IS_ERR_OR_NULL(mdev->clock)) { |
---|
| 598 | + MALI_DEBUG_PRINT(2, ("Continuing without Mali dvfs clock\n")); |
---|
| 599 | + /* Allow probe to continue without clock. */ |
---|
| 600 | + mdev->clock = NULL; |
---|
| 601 | + } |
---|
| 602 | + } |
---|
| 603 | + err = clk_bulk_prepare_enable(mdev->num_clks, mdev->clks); |
---|
| 604 | + if (err) { |
---|
| 605 | + MALI_PRINT_ERROR(("Failed to prepare clock (%d)\n", err)); |
---|
| 606 | + goto clock_prepare_failed; |
---|
| 607 | + } |
---|
579 | 608 | |
---|
580 | 609 | err = rk_platform_init_opp_table(mdev->dev); |
---|
581 | 610 | if (err) |
---|
582 | 611 | MALI_DEBUG_PRINT(3, ("Failed to init_opp_table\n")); |
---|
583 | | - |
---|
584 | | - /* Need to name the gpu clock "clk_mali" in the device tree */ |
---|
585 | | - mdev->clock = clk_get(mdev->dev, "clk_mali"); |
---|
586 | | - if (IS_ERR_OR_NULL(mdev->clock)) { |
---|
587 | | - MALI_DEBUG_PRINT(2, ("Continuing without Mali clock control\n")); |
---|
588 | | - mdev->clock = NULL; |
---|
589 | | - /* Allow probe to continue without clock. */ |
---|
590 | | - } else { |
---|
591 | | - err = clk_prepare(mdev->clock); |
---|
592 | | - if (err) { |
---|
593 | | - MALI_PRINT_ERROR(("Failed to prepare clock (%d)\n", err)); |
---|
594 | | - goto clock_prepare_failed; |
---|
595 | | - } |
---|
596 | | - } |
---|
597 | 612 | |
---|
598 | 613 | /* initilize pm metrics related */ |
---|
599 | 614 | if (mali_pm_metrics_init(mdev) < 0) { |
---|
.. | .. |
---|
605 | 620 | MALI_DEBUG_PRINT(2, ("mali devfreq init failed\n")); |
---|
606 | 621 | goto devfreq_init_failed; |
---|
607 | 622 | } |
---|
| 623 | + clk_bulk_disable(mdev->num_clks, mdev->clks); |
---|
608 | 624 | #endif |
---|
609 | 625 | |
---|
610 | 626 | |
---|
.. | .. |
---|
640 | 656 | devfreq_init_failed: |
---|
641 | 657 | mali_pm_metrics_term(mdev); |
---|
642 | 658 | pm_metrics_init_failed: |
---|
643 | | - clk_unprepare(mdev->clock); |
---|
| 659 | + clk_bulk_disable_unprepare(mdev->num_clks, mdev->clks); |
---|
644 | 660 | clock_prepare_failed: |
---|
| 661 | + clk_bulk_put(mdev->num_clks, mdev->clks); |
---|
645 | 662 | clk_put(mdev->clock); |
---|
646 | 663 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \ |
---|
647 | 664 | && defined(CONFIG_PM_OPP) |
---|
.. | .. |
---|
651 | 668 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \ |
---|
652 | 669 | && defined(CONFIG_REGULATOR) |
---|
653 | 670 | regulator_put(mdev->regulator); |
---|
| 671 | + dev_pm_opp_put_regulators(mdev->opp_table); |
---|
654 | 672 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
655 | 673 | mali_device_free(mdev); |
---|
656 | 674 | #endif |
---|
.. | .. |
---|
680 | 698 | mali_pm_metrics_term(mdev); |
---|
681 | 699 | |
---|
682 | 700 | if (mdev->clock) { |
---|
683 | | - clk_unprepare(mdev->clock); |
---|
684 | 701 | clk_put(mdev->clock); |
---|
685 | 702 | mdev->clock = NULL; |
---|
686 | 703 | } |
---|
| 704 | + clk_bulk_unprepare(mdev->num_clks, mdev->clks); |
---|
| 705 | + clk_bulk_put(mdev->num_clks, mdev->clks); |
---|
| 706 | + |
---|
687 | 707 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \ |
---|
688 | 708 | && defined(CONFIG_PM_OPP) |
---|
689 | 709 | dev_pm_opp_of_remove_table(mdev->dev); |
---|
.. | .. |
---|
692 | 712 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \ |
---|
693 | 713 | && defined(CONFIG_REGULATOR) |
---|
694 | 714 | regulator_put(mdev->regulator); |
---|
| 715 | + dev_pm_opp_put_regulators(mdev->opp_table); |
---|
695 | 716 | #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */ |
---|
696 | 717 | mali_device_free(mdev); |
---|
697 | 718 | #endif |
---|
.. | .. |
---|
733 | 754 | return -ENODEV; |
---|
734 | 755 | #endif |
---|
735 | 756 | |
---|
| 757 | + pm_runtime_force_suspend(dev); |
---|
736 | 758 | #if defined(CONFIG_MALI_DEVFREQ) && \ |
---|
737 | 759 | (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) |
---|
738 | 760 | devfreq_suspend_device(mdev->devfreq); |
---|
.. | .. |
---|
777 | 799 | (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) |
---|
778 | 800 | devfreq_resume_device(mdev->devfreq); |
---|
779 | 801 | #endif |
---|
| 802 | + pm_runtime_force_resume(dev); |
---|
780 | 803 | |
---|
781 | 804 | return 0; |
---|
782 | 805 | } |
---|