forked from mirrors/linux
		
	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:
		
							parent
							
								
									e2af8b6b0c
								
							
						
					
					
						commit
						98db803f64
					
				
					 2 changed files with 58 additions and 24 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue