aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2017-03-07 12:02:56 -0500
committerRob Clark <robdclark@gmail.com>2017-04-08 06:59:37 -0400
commit98db803f6413e6d4bf1f590ea57e9e7dfe1eb32b (patch)
tree28d814bedb2d3dfdd886613de45d5c1697743caf /drivers
parente2af8b6b0ca1f55e9b2c8a034c352c56ae054066 (diff)
msm/drm: gpu: Dynamically locate the clocks from the device tree
Instead of using a fixed list of clock names use the clock-names list in the device tree to discover and get the list of clocks that we need. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c78
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h4
2 files changed, 58 insertions, 24 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index f8ee1489e691..97b9c38c6b3f 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -93,18 +93,18 @@ static int enable_clk(struct msm_gpu *gpu)
93{ 93{
94 int i; 94 int i;
95 95
96 if (gpu->grp_clks[0] && gpu->fast_rate) 96 if (gpu->core_clk && gpu->fast_rate)
97 clk_set_rate(gpu->grp_clks[0], gpu->fast_rate); 97 clk_set_rate(gpu->core_clk, gpu->fast_rate);
98 98
99 /* Set the RBBM timer rate to 19.2Mhz */ 99 /* Set the RBBM timer rate to 19.2Mhz */
100 if (gpu->grp_clks[2]) 100 if (gpu->rbbmtimer_clk)
101 clk_set_rate(gpu->grp_clks[2], 19200000); 101 clk_set_rate(gpu->rbbmtimer_clk, 19200000);
102 102
103 for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--) 103 for (i = gpu->nr_clocks - 1; i >= 0; i--)
104 if (gpu->grp_clks[i]) 104 if (gpu->grp_clks[i])
105 clk_prepare(gpu->grp_clks[i]); 105 clk_prepare(gpu->grp_clks[i]);
106 106
107 for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--) 107 for (i = gpu->nr_clocks - 1; i >= 0; i--)
108 if (gpu->grp_clks[i]) 108 if (gpu->grp_clks[i])
109 clk_enable(gpu->grp_clks[i]); 109 clk_enable(gpu->grp_clks[i]);
110 110
@@ -115,11 +115,11 @@ static int disable_clk(struct msm_gpu *gpu)
115{ 115{
116 int i; 116 int i;
117 117
118 for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--) 118 for (i = gpu->nr_clocks - 1; i >= 0; i--)
119 if (gpu->grp_clks[i]) 119 if (gpu->grp_clks[i])
120 clk_disable(gpu->grp_clks[i]); 120 clk_disable(gpu->grp_clks[i]);
121 121
122 for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--) 122 for (i = gpu->nr_clocks - 1; i >= 0; i--)
123 if (gpu->grp_clks[i]) 123 if (gpu->grp_clks[i])
124 clk_unprepare(gpu->grp_clks[i]); 124 clk_unprepare(gpu->grp_clks[i]);
125 125
@@ -128,10 +128,11 @@ static int disable_clk(struct msm_gpu *gpu)
128 * speed had to be non zero to avoid problems. On newer targets this 128 * speed had to be non zero to avoid problems. On newer targets this
129 * will be rounded down to zero anyway so it all works out. 129 * will be rounded down to zero anyway so it all works out.
130 */ 130 */
131 clk_set_rate(gpu->grp_clks[0], 27000000); 131 if (gpu->core_clk)
132 clk_set_rate(gpu->core_clk, 27000000);
132 133
133 if (gpu->grp_clks[2]) 134 if (gpu->rbbmtimer_clk)
134 clk_set_rate(gpu->grp_clks[2], 0); 135 clk_set_rate(gpu->rbbmtimer_clk, 0);
135 136
136 return 0; 137 return 0;
137} 138}
@@ -519,16 +520,52 @@ static irqreturn_t irq_handler(int irq, void *data)
519 return gpu->funcs->irq(gpu); 520 return gpu->funcs->irq(gpu);
520} 521}
521 522
522static const char *clk_names[] = { 523static struct clk *get_clock(struct device *dev, const char *name)
523 "core", "iface", "rbbmtimer", "mem", "mem_iface", "alt_mem_iface", 524{
524}; 525 struct clk *clk = devm_clk_get(dev, name);
526
527 return IS_ERR(clk) ? NULL : clk;
528}
529
530static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
531{
532 struct device *dev = &pdev->dev;
533 struct property *prop;
534 const char *name;
535 int i = 0;
536
537 gpu->nr_clocks = of_property_count_strings(dev->of_node, "clock-names");
538 if (gpu->nr_clocks < 1) {
539 gpu->nr_clocks = 0;
540 return 0;
541 }
542
543 gpu->grp_clks = devm_kcalloc(dev, sizeof(struct clk *), gpu->nr_clocks,
544 GFP_KERNEL);
545 if (!gpu->grp_clks)
546 return -ENOMEM;
547
548 of_property_for_each_string(dev->of_node, "clock-names", prop, name) {
549 gpu->grp_clks[i] = get_clock(dev, name);
550
551 /* Remember the key clocks that we need to control later */
552 if (!strcmp(name, "core"))
553 gpu->core_clk = gpu->grp_clks[i];
554 else if (!strcmp(name, "rbbmtimer"))
555 gpu->rbbmtimer_clk = gpu->grp_clks[i];
556
557 ++i;
558 }
559
560 return 0;
561}
525 562
526int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, 563int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
527 struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, 564 struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
528 const char *name, const char *ioname, const char *irqname, int ringsz) 565 const char *name, const char *ioname, const char *irqname, int ringsz)
529{ 566{
530 struct iommu_domain *iommu; 567 struct iommu_domain *iommu;
531 int i, ret; 568 int ret;
532 569
533 if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs))) 570 if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
534 gpu->num_perfcntrs = ARRAY_SIZE(gpu->last_cntrs); 571 gpu->num_perfcntrs = ARRAY_SIZE(gpu->last_cntrs);
@@ -554,7 +591,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
554 591
555 spin_lock_init(&gpu->perf_lock); 592 spin_lock_init(&gpu->perf_lock);
556 593
557 BUG_ON(ARRAY_SIZE(clk_names) != ARRAY_SIZE(gpu->grp_clks));
558 594
559 /* Map registers: */ 595 /* Map registers: */
560 gpu->mmio = msm_ioremap(pdev, ioname, name); 596 gpu->mmio = msm_ioremap(pdev, ioname, name);
@@ -578,13 +614,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
578 goto fail; 614 goto fail;
579 } 615 }
580 616
581 /* Acquire clocks: */ 617 ret = get_clocks(pdev, gpu);
582 for (i = 0; i < ARRAY_SIZE(clk_names); i++) { 618 if (ret)
583 gpu->grp_clks[i] = msm_clk_get(pdev, clk_names[i]); 619 goto fail;
584 DBG("grp_clks[%s]: %p", clk_names[i], gpu->grp_clks[i]);
585 if (IS_ERR(gpu->grp_clks[i]))
586 gpu->grp_clks[i] = NULL;
587 }
588 620
589 gpu->ebi1_clk = msm_clk_get(pdev, "bus"); 621 gpu->ebi1_clk = msm_clk_get(pdev, "bus");
590 DBG("ebi1_clk: %p", gpu->ebi1_clk); 622 DBG("ebi1_clk: %p", gpu->ebi1_clk);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 44f0c34ee5e4..aa3241000455 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -103,7 +103,9 @@ struct msm_gpu {
103 103
104 /* Power Control: */ 104 /* Power Control: */
105 struct regulator *gpu_reg, *gpu_cx; 105 struct regulator *gpu_reg, *gpu_cx;
106 struct clk *ebi1_clk, *grp_clks[6]; 106 struct clk **grp_clks;
107 int nr_clocks;
108 struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
107 uint32_t fast_rate, bus_freq; 109 uint32_t fast_rate, bus_freq;
108 110
109#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 111#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING