|
@@ -93,18 +93,18 @@ static int enable_clk(struct msm_gpu *gpu)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- if (gpu->grp_clks[0] && gpu->fast_rate)
|
|
|
- clk_set_rate(gpu->grp_clks[0], gpu->fast_rate);
|
|
|
+ if (gpu->core_clk && gpu->fast_rate)
|
|
|
+ clk_set_rate(gpu->core_clk, gpu->fast_rate);
|
|
|
|
|
|
/* Set the RBBM timer rate to 19.2Mhz */
|
|
|
- if (gpu->grp_clks[2])
|
|
|
- clk_set_rate(gpu->grp_clks[2], 19200000);
|
|
|
+ if (gpu->rbbmtimer_clk)
|
|
|
+ clk_set_rate(gpu->rbbmtimer_clk, 19200000);
|
|
|
|
|
|
- for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--)
|
|
|
+ for (i = gpu->nr_clocks - 1; i >= 0; i--)
|
|
|
if (gpu->grp_clks[i])
|
|
|
clk_prepare(gpu->grp_clks[i]);
|
|
|
|
|
|
- for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--)
|
|
|
+ for (i = gpu->nr_clocks - 1; i >= 0; i--)
|
|
|
if (gpu->grp_clks[i])
|
|
|
clk_enable(gpu->grp_clks[i]);
|
|
|
|
|
@@ -115,11 +115,11 @@ static int disable_clk(struct msm_gpu *gpu)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--)
|
|
|
+ for (i = gpu->nr_clocks - 1; i >= 0; i--)
|
|
|
if (gpu->grp_clks[i])
|
|
|
clk_disable(gpu->grp_clks[i]);
|
|
|
|
|
|
- for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i >= 0; i--)
|
|
|
+ for (i = gpu->nr_clocks - 1; i >= 0; i--)
|
|
|
if (gpu->grp_clks[i])
|
|
|
clk_unprepare(gpu->grp_clks[i]);
|
|
|
|
|
@@ -128,10 +128,11 @@ static int disable_clk(struct msm_gpu *gpu)
|
|
|
* speed had to be non zero to avoid problems. On newer targets this
|
|
|
* will be rounded down to zero anyway so it all works out.
|
|
|
*/
|
|
|
- clk_set_rate(gpu->grp_clks[0], 27000000);
|
|
|
+ if (gpu->core_clk)
|
|
|
+ clk_set_rate(gpu->core_clk, 27000000);
|
|
|
|
|
|
- if (gpu->grp_clks[2])
|
|
|
- clk_set_rate(gpu->grp_clks[2], 0);
|
|
|
+ if (gpu->rbbmtimer_clk)
|
|
|
+ clk_set_rate(gpu->rbbmtimer_clk, 0);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -519,16 +520,52 @@ static irqreturn_t irq_handler(int irq, void *data)
|
|
|
return gpu->funcs->irq(gpu);
|
|
|
}
|
|
|
|
|
|
-static const char *clk_names[] = {
|
|
|
- "core", "iface", "rbbmtimer", "mem", "mem_iface", "alt_mem_iface",
|
|
|
-};
|
|
|
+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;
|
|
|
+
|
|
|
+ gpu->nr_clocks = of_property_count_strings(dev->of_node, "clock-names");
|
|
|
+ if (gpu->nr_clocks < 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)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ of_property_for_each_string(dev->of_node, "clock-names", prop, name) {
|
|
|
+ gpu->grp_clks[i] = get_clock(dev, name);
|
|
|
+
|
|
|
+ /* Remember the key clocks that we need to control later */
|
|
|
+ if (!strcmp(name, "core"))
|
|
|
+ gpu->core_clk = gpu->grp_clks[i];
|
|
|
+ else if (!strcmp(name, "rbbmtimer"))
|
|
|
+ gpu->rbbmtimer_clk = gpu->grp_clks[i];
|
|
|
+
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
|
|
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
|
|
|
const char *name, const char *ioname, const char *irqname, int ringsz)
|
|
|
{
|
|
|
struct iommu_domain *iommu;
|
|
|
- int i, ret;
|
|
|
+ int ret;
|
|
|
|
|
|
if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
|
|
|
gpu->num_perfcntrs = ARRAY_SIZE(gpu->last_cntrs);
|
|
@@ -554,7 +591,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
|
|
|
|
|
spin_lock_init(&gpu->perf_lock);
|
|
|
|
|
|
- BUG_ON(ARRAY_SIZE(clk_names) != ARRAY_SIZE(gpu->grp_clks));
|
|
|
|
|
|
/* Map registers: */
|
|
|
gpu->mmio = msm_ioremap(pdev, ioname, name);
|
|
@@ -578,13 +614,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
- /* Acquire clocks: */
|
|
|
- for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
|
|
|
- gpu->grp_clks[i] = msm_clk_get(pdev, clk_names[i]);
|
|
|
- DBG("grp_clks[%s]: %p", clk_names[i], gpu->grp_clks[i]);
|
|
|
- if (IS_ERR(gpu->grp_clks[i]))
|
|
|
- gpu->grp_clks[i] = NULL;
|
|
|
- }
|
|
|
+ ret = get_clocks(pdev, gpu);
|
|
|
+ if (ret)
|
|
|
+ goto fail;
|
|
|
|
|
|
gpu->ebi1_clk = msm_clk_get(pdev, "bus");
|
|
|
DBG("ebi1_clk: %p", gpu->ebi1_clk);
|