diff options
Diffstat (limited to 'drivers/gpu/nvgpu/tegra')
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c index a8a1451a..d6e448d8 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | |||
@@ -753,6 +753,87 @@ void gk20a_tegra_init_secure_alloc(struct gk20a *g) | |||
753 | g->ops.mm.secure_alloc = gk20a_tegra_secure_alloc; | 753 | g->ops.mm.secure_alloc = gk20a_tegra_secure_alloc; |
754 | } | 754 | } |
755 | 755 | ||
756 | #ifdef CONFIG_COMMON_CLK | ||
757 | static int gm20b_clk_prepare_ops(struct clk_hw *hw) | ||
758 | { | ||
759 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
760 | return gm20b_clk_prepare(clk); | ||
761 | } | ||
762 | |||
763 | static void gm20b_clk_unprepare_ops(struct clk_hw *hw) | ||
764 | { | ||
765 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
766 | gm20b_clk_unprepare(clk); | ||
767 | } | ||
768 | |||
769 | static int gm20b_clk_is_prepared_ops(struct clk_hw *hw) | ||
770 | { | ||
771 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
772 | return gm20b_clk_is_prepared(clk); | ||
773 | } | ||
774 | |||
775 | static unsigned long gm20b_recalc_rate_ops(struct clk_hw *hw, unsigned long parent_rate) | ||
776 | { | ||
777 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
778 | return gm20b_recalc_rate(clk, parent_rate); | ||
779 | } | ||
780 | |||
781 | static int gm20b_gpcclk_set_rate_ops(struct clk_hw *hw, unsigned long rate, | ||
782 | unsigned long parent_rate) | ||
783 | { | ||
784 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
785 | return gm20b_gpcclk_set_rate(clk, rate, parent_rate); | ||
786 | } | ||
787 | |||
788 | static long gm20b_round_rate_ops(struct clk_hw *hw, unsigned long rate, | ||
789 | unsigned long *parent_rate) | ||
790 | { | ||
791 | struct clk_gk20a *clk = to_clk_gk20a(hw); | ||
792 | return gm20b_round_rate(clk, rate, parent_rate); | ||
793 | } | ||
794 | |||
795 | static const struct clk_ops gm20b_clk_ops = { | ||
796 | .prepare = gm20b_clk_prepare_ops, | ||
797 | .unprepare = gm20b_clk_unprepare_ops, | ||
798 | .is_prepared = gm20b_clk_is_prepared_ops, | ||
799 | .recalc_rate = gm20b_recalc_rate_ops, | ||
800 | .set_rate = gm20b_gpcclk_set_rate_ops, | ||
801 | .round_rate = gm20b_round_rate_ops, | ||
802 | }; | ||
803 | |||
804 | static int gm20b_register_gpcclk(struct gk20a *g) | ||
805 | { | ||
806 | const char *parent_name = "pllg_ref"; | ||
807 | struct clk_gk20a *clk = &g->clk; | ||
808 | struct clk_init_data init; | ||
809 | struct clk *c; | ||
810 | int err = 0; | ||
811 | |||
812 | err = gm20b_init_clk_setup_sw(g); | ||
813 | if (err) | ||
814 | return err; | ||
815 | |||
816 | init.name = "gpcclk"; | ||
817 | init.ops = &gm20b_clk_ops; | ||
818 | init.parent_names = &parent_name; | ||
819 | init.num_parents = 1; | ||
820 | init.flags = 0; | ||
821 | |||
822 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
823 | clk->hw.init = &init; | ||
824 | c = clk_register(g->dev, &clk->hw); | ||
825 | if (IS_ERR(c)) { | ||
826 | nvgpu_err(g, "Failed to register GPCPLL clock"); | ||
827 | return -EINVAL; | ||
828 | } | ||
829 | |||
830 | clk->g = g; | ||
831 | clk_register_clkdev(c, "gpcclk", "gpcclk"); | ||
832 | |||
833 | return err; | ||
834 | } | ||
835 | #endif /* CONFIG_COMMON_CLK */ | ||
836 | |||
756 | static int gk20a_tegra_probe(struct device *dev) | 837 | static int gk20a_tegra_probe(struct device *dev) |
757 | { | 838 | { |
758 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 839 | struct gk20a_platform *platform = dev_get_drvdata(dev); |