drm/msm: Add a helper function to parse clock names
authorJordan Crouse <jcrouse@codeaurora.org>
Mon, 6 Aug 2018 17:33:21 +0000 (11:33 -0600)
committerRob Clark <robdclark@gmail.com>
Fri, 10 Aug 2018 22:49:18 +0000 (18:49 -0400)
Add a helper function to parse the clock names and set up
the bulk data so we can take advantage of the bulk clock
functions instead of rolling our own. This is added
as a helper function so the upcoming a6xx GMU code can
also take advantage of it.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpu.h

index 46876bc8b7077e9ef8ed7f7d116ae2f8a99f78fc..c1abad8a8612683a237dfae4fec766c806c9caf8 100644 (file)
@@ -81,6 +81,63 @@ module_param(modeset, bool, 0600);
  * Util/helpers:
  */
 
+int msm_clk_bulk_get(struct device *dev, struct clk_bulk_data **bulk)
+{
+       struct property *prop;
+       const char *name;
+       struct clk_bulk_data *local;
+       int i = 0, ret, count;
+
+       count = of_property_count_strings(dev->of_node, "clock-names");
+       if (count < 1)
+               return 0;
+
+       local = devm_kcalloc(dev, sizeof(struct clk_bulk_data *),
+               count, GFP_KERNEL);
+       if (!local)
+               return -ENOMEM;
+
+       of_property_for_each_string(dev->of_node, "clock-names", prop, name) {
+               local[i].id = devm_kstrdup(dev, name, GFP_KERNEL);
+               if (!local[i].id) {
+                       devm_kfree(dev, local);
+                       return -ENOMEM;
+               }
+
+               i++;
+       }
+
+       ret = devm_clk_bulk_get(dev, count, local);
+
+       if (ret) {
+               for (i = 0; i < count; i++)
+                       devm_kfree(dev, (void *) local[i].id);
+               devm_kfree(dev, local);
+
+               return ret;
+       }
+
+       *bulk = local;
+       return count;
+}
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+               const char *name)
+{
+       int i;
+       char n[32];
+
+       snprintf(n, sizeof(n), "%s_clk", name);
+
+       for (i = 0; bulk && i < count; i++) {
+               if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
+                       return bulk[i].clk;
+       }
+
+
+       return NULL;
+}
+
 struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
 {
        struct clk *clk;
index b611484866d68ac032fff312198b784342434941..8e510d5c758a59b5922ba8357f68ce33ca404eae 100644 (file)
@@ -387,6 +387,10 @@ static inline void msm_perf_debugfs_cleanup(struct msm_drm_private *priv) {}
 #endif
 
 struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
+int msm_clk_bulk_get(struct device *dev, struct clk_bulk_data **bulk);
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+       const char *name);
 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
                const char *dbgname);
 void msm_writel(u32 data, void __iomem *addr);
index f388944c93e2750a5b3092fee535b400e5fa63ca..ca368490b3ee2e47efcb129b5225d6d340abd983 100644 (file)
@@ -142,8 +142,6 @@ static int disable_pwrrail(struct msm_gpu *gpu)
 
 static int enable_clk(struct msm_gpu *gpu)
 {
-       int i;
-
        if (gpu->core_clk && gpu->fast_rate)
                clk_set_rate(gpu->core_clk, gpu->fast_rate);
 
@@ -151,28 +149,12 @@ static int enable_clk(struct msm_gpu *gpu)
        if (gpu->rbbmtimer_clk)
                clk_set_rate(gpu->rbbmtimer_clk, 19200000);
 
-       for (i = gpu->nr_clocks - 1; i >= 0; i--)
-               if (gpu->grp_clks[i])
-                       clk_prepare(gpu->grp_clks[i]);
-
-       for (i = gpu->nr_clocks - 1; i >= 0; i--)
-               if (gpu->grp_clks[i])
-                       clk_enable(gpu->grp_clks[i]);
-
-       return 0;
+       return clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
 }
 
 static int disable_clk(struct msm_gpu *gpu)
 {
-       int i;
-
-       for (i = gpu->nr_clocks - 1; i >= 0; i--)
-               if (gpu->grp_clks[i])
-                       clk_disable(gpu->grp_clks[i]);
-
-       for (i = gpu->nr_clocks - 1; i >= 0; i--)
-               if (gpu->grp_clks[i])
-                       clk_unprepare(gpu->grp_clks[i]);
+       clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);
 
        /*
         * Set the clock to a deliberately low rate. On older targets the clock
@@ -785,44 +767,22 @@ static irqreturn_t irq_handler(int irq, void *data)
        return gpu->funcs->irq(gpu);
 }
 
-static struct clk *get_clock(struct device *dev, const char *name)
-{
-       struct clk *clk = devm_clk_get(dev, name);
-
-       return IS_ERR(clk) ? NULL : clk;
-}
-
 static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
 {
-       struct device *dev = &pdev->dev;
-       struct property *prop;
-       const char *name;
-       int i = 0;
+       int ret = msm_clk_bulk_get(&pdev->dev, &gpu->grp_clks);
 
-       gpu->nr_clocks = of_property_count_strings(dev->of_node, "clock-names");
-       if (gpu->nr_clocks < 1) {
+       if (ret < 1) {
                gpu->nr_clocks = 0;
-               return 0;
-       }
-
-       gpu->grp_clks = devm_kcalloc(dev, sizeof(struct clk *), gpu->nr_clocks,
-               GFP_KERNEL);
-       if (!gpu->grp_clks) {
-               gpu->nr_clocks = 0;
-               return -ENOMEM;
+               return ret;
        }
 
-       of_property_for_each_string(dev->of_node, "clock-names", prop, name) {
-               gpu->grp_clks[i] = get_clock(dev, name);
+       gpu->nr_clocks = ret;
 
-               /* Remember the key clocks that we need to control later */
-               if (!strcmp(name, "core") || !strcmp(name, "core_clk"))
-                       gpu->core_clk = gpu->grp_clks[i];
-               else if (!strcmp(name, "rbbmtimer") || !strcmp(name, "rbbmtimer_clk"))
-                       gpu->rbbmtimer_clk = gpu->grp_clks[i];
+       gpu->core_clk = msm_clk_bulk_get_clock(gpu->grp_clks,
+               gpu->nr_clocks, "core");
 
-               ++i;
-       }
+       gpu->rbbmtimer_clk = msm_clk_bulk_get_clock(gpu->grp_clks,
+               gpu->nr_clocks, "rbbmtimer");
 
        return 0;
 }
index 1c6105bc55c767735e13c771c66ebe1d243cc859..9122ee6e55e4c30907de8fdd533a29682e8800ba 100644 (file)
@@ -112,7 +112,7 @@ struct msm_gpu {
 
        /* Power Control: */
        struct regulator *gpu_reg, *gpu_cx;
-       struct clk **grp_clks;
+       struct clk_bulk_data *grp_clks;
        int nr_clocks;
        struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
        uint32_t fast_rate;