drm/tegra: nvdec: Support multiple clocks
authorMikko Perttunen <mperttunen@nvidia.com>
Tue, 20 Sep 2022 08:12:01 +0000 (11:12 +0300)
committerThierry Reding <treding@nvidia.com>
Fri, 25 Nov 2022 15:14:58 +0000 (16:14 +0100)
NVDEC on Tegra234 requires multiple clocks. Add support for that.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/nvdec.c

index 276fe04..05af4d1 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2021, NVIDIA Corporation.
+ * Copyright (c) 2015-2022, NVIDIA Corporation.
  */
 
 #include <linux/clk.h>
@@ -28,6 +28,7 @@ struct nvdec_config {
        const char *firmware;
        unsigned int version;
        bool supports_sid;
+       bool has_extra_clocks;
 };
 
 struct nvdec {
@@ -37,7 +38,8 @@ struct nvdec {
        struct tegra_drm_client client;
        struct host1x_channel *channel;
        struct device *dev;
-       struct clk *clk;
+       struct clk_bulk_data clks[3];
+       unsigned int num_clks;
 
        /* Platform configuration */
        const struct nvdec_config *config;
@@ -258,7 +260,7 @@ static __maybe_unused int nvdec_runtime_resume(struct device *dev)
        struct nvdec *nvdec = dev_get_drvdata(dev);
        int err;
 
-       err = clk_prepare_enable(nvdec->clk);
+       err = clk_bulk_prepare_enable(nvdec->num_clks, nvdec->clks);
        if (err < 0)
                return err;
 
@@ -275,7 +277,7 @@ static __maybe_unused int nvdec_runtime_resume(struct device *dev)
        return 0;
 
 disable:
-       clk_disable_unprepare(nvdec->clk);
+       clk_bulk_disable_unprepare(nvdec->num_clks, nvdec->clks);
        return err;
 }
 
@@ -285,7 +287,7 @@ static __maybe_unused int nvdec_runtime_suspend(struct device *dev)
 
        host1x_channel_stop(nvdec->channel);
 
-       clk_disable_unprepare(nvdec->clk);
+       clk_bulk_disable_unprepare(nvdec->num_clks, nvdec->clks);
 
        return 0;
 }
@@ -383,13 +385,22 @@ static int nvdec_probe(struct platform_device *pdev)
        if (IS_ERR(nvdec->regs))
                return PTR_ERR(nvdec->regs);
 
-       nvdec->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(nvdec->clk)) {
-               dev_err(&pdev->dev, "failed to get clock\n");
-               return PTR_ERR(nvdec->clk);
+       nvdec->clks[0].id = "nvdec";
+       nvdec->num_clks = 1;
+
+       if (nvdec->config->has_extra_clocks) {
+               nvdec->num_clks = 3;
+               nvdec->clks[1].id = "fuse";
+               nvdec->clks[2].id = "tsec_pka";
+       }
+
+       err = devm_clk_bulk_get(dev, nvdec->num_clks, nvdec->clks);
+       if (err) {
+               dev_err(&pdev->dev, "failed to get clock(s)\n");
+               return err;
        }
 
-       err = clk_set_rate(nvdec->clk, ULONG_MAX);
+       err = clk_set_rate(nvdec->clks[0].clk, ULONG_MAX);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to set clock rate\n");
                return err;