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>
This commit is contained in:
Jordan Crouse 2017-03-07 10:02:56 -07:00 committed by Rob Clark
parent e2af8b6b0c
commit 98db803f64
2 changed files with 58 additions and 24 deletions

View File

@ -93,18 +93,18 @@ static int enable_clk(struct msm_gpu *gpu)
{ {
int i; int i;
if (gpu->grp_clks[0] && gpu->fast_rate) if (gpu->core_clk && gpu->fast_rate)
clk_set_rate(gpu->grp_clks[0], gpu->fast_rate); clk_set_rate(gpu->core_clk, gpu->fast_rate);
/* Set the RBBM timer rate to 19.2Mhz */ /* Set the RBBM timer rate to 19.2Mhz */
if (gpu->grp_clks[2]) if (gpu->rbbmtimer_clk)
clk_set_rate(gpu->grp_clks[2], 19200000); 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]) if (gpu->grp_clks[i])
clk_prepare(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]) if (gpu->grp_clks[i])
clk_enable(gpu->grp_clks[i]); clk_enable(gpu->grp_clks[i]);
@ -115,11 +115,11 @@ static int disable_clk(struct msm_gpu *gpu)
{ {
int i; 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]) if (gpu->grp_clks[i])
clk_disable(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]) if (gpu->grp_clks[i])
clk_unprepare(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 * 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. * 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]) if (gpu->rbbmtimer_clk)
clk_set_rate(gpu->grp_clks[2], 0); clk_set_rate(gpu->rbbmtimer_clk, 0);
return 0; return 0;
} }
@ -519,16 +520,52 @@ static irqreturn_t irq_handler(int irq, void *data)
return gpu->funcs->irq(gpu); return gpu->funcs->irq(gpu);
} }
static const char *clk_names[] = { static struct clk *get_clock(struct device *dev, const char *name)
"core", "iface", "rbbmtimer", "mem", "mem_iface", "alt_mem_iface", {
}; 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, int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
const char *name, const char *ioname, const char *irqname, int ringsz) const char *name, const char *ioname, const char *irqname, int ringsz)
{ {
struct iommu_domain *iommu; struct iommu_domain *iommu;
int i, ret; int ret;
if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs))) if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
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); spin_lock_init(&gpu->perf_lock);
BUG_ON(ARRAY_SIZE(clk_names) != ARRAY_SIZE(gpu->grp_clks));
/* Map registers: */ /* Map registers: */
gpu->mmio = msm_ioremap(pdev, ioname, name); 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; goto fail;
} }
/* Acquire clocks: */ ret = get_clocks(pdev, gpu);
for (i = 0; i < ARRAY_SIZE(clk_names); i++) { if (ret)
gpu->grp_clks[i] = msm_clk_get(pdev, clk_names[i]); goto fail;
DBG("grp_clks[%s]: %p", clk_names[i], gpu->grp_clks[i]);
if (IS_ERR(gpu->grp_clks[i]))
gpu->grp_clks[i] = NULL;
}
gpu->ebi1_clk = msm_clk_get(pdev, "bus"); gpu->ebi1_clk = msm_clk_get(pdev, "bus");
DBG("ebi1_clk: %p", gpu->ebi1_clk); DBG("ebi1_clk: %p", gpu->ebi1_clk);

View File

@ -103,7 +103,9 @@ struct msm_gpu {
/* Power Control: */ /* Power Control: */
struct regulator *gpu_reg, *gpu_cx; struct regulator *gpu_reg, *gpu_cx;
struct clk *ebi1_clk, *grp_clks[6]; struct clk **grp_clks;
int nr_clocks;
struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
uint32_t fast_rate, bus_freq; uint32_t fast_rate, bus_freq;
#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING