Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved.
  4 * Copyright (C) 2013 Red Hat
  5 * Author: Rob Clark <robdclark@gmail.com>
  6 */
  7
  8#include <linux/interconnect.h>
  9#include <linux/io.h>
 10
 11#include "msm_drv.h"
 12
 13/*
 14 * Util/helpers:
 15 */
 16
 17struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
 18		const char *name)
 19{
 20	int i;
 21	char n[32];
 22
 23	snprintf(n, sizeof(n), "%s_clk", name);
 24
 25	for (i = 0; bulk && i < count; i++) {
 26		if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
 27			return bulk[i].clk;
 28	}
 29
 30
 31	return NULL;
 32}
 33
 34struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
 35{
 36	struct clk *clk;
 37	char name2[32];
 38
 39	clk = devm_clk_get(&pdev->dev, name);
 40	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
 41		return clk;
 42
 43	snprintf(name2, sizeof(name2), "%s_clk", name);
 44
 45	clk = devm_clk_get(&pdev->dev, name2);
 46	if (!IS_ERR(clk))
 47		dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
 48				"\"%s\" instead of \"%s\"\n", name, name2);
 49
 50	return clk;
 51}
 52
 53void __iomem *msm_ioremap_mdss(struct platform_device *mdss_pdev,
 54			       struct platform_device *pdev,
 55			       const char *name)
 56{
 57	struct resource *res;
 58
 59	res = platform_get_resource_byname(mdss_pdev, IORESOURCE_MEM, name);
 60	if (!res)
 61		return ERR_PTR(-EINVAL);
 62
 63	return devm_ioremap_resource(&pdev->dev, res);
 64}
 65
 66static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
 67				  bool quiet, phys_addr_t *psize)
 68{
 69	struct resource *res;
 70	unsigned long size;
 71	void __iomem *ptr;
 72
 73	if (name)
 74		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 75	else
 76		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 77
 78	if (!res) {
 79		if (!quiet)
 80			DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
 81		return ERR_PTR(-EINVAL);
 82	}
 83
 84	size = resource_size(res);
 85
 86	ptr = devm_ioremap(&pdev->dev, res->start, size);
 87	if (!ptr) {
 88		if (!quiet)
 89			DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
 90		return ERR_PTR(-ENOMEM);
 91	}
 92
 93	if (psize)
 94		*psize = size;
 95
 96	return ptr;
 97}
 98
 99void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
100{
101	return _msm_ioremap(pdev, name, false, NULL);
102}
103
104void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
105{
106	return _msm_ioremap(pdev, name, true, NULL);
107}
108
109void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
110			  phys_addr_t *psize)
111{
112	return _msm_ioremap(pdev, name, false, psize);
113}
114
115static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
116{
117	struct msm_hrtimer_work *work = container_of(t,
118			struct msm_hrtimer_work, timer);
119
120	kthread_queue_work(work->worker, &work->work);
121
122	return HRTIMER_NORESTART;
123}
124
125void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
126			    ktime_t wakeup_time,
127			    enum hrtimer_mode mode)
128{
129	hrtimer_start(&work->timer, wakeup_time, mode);
130}
131
132void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
133			   struct kthread_worker *worker,
134			   kthread_work_func_t fn,
135			   clockid_t clock_id,
136			   enum hrtimer_mode mode)
137{
138	hrtimer_init(&work->timer, clock_id, mode);
139	work->timer.function = msm_hrtimer_worktimer;
140	work->worker = worker;
141	kthread_init_work(&work->work, fn);
142}
143
144struct icc_path *msm_icc_get(struct device *dev, const char *name)
145{
146	struct device *mdss_dev = dev->parent;
147	struct icc_path *path;
148
149	path = of_icc_get(dev, name);
150	if (path)
151		return path;
152
153	/*
154	 * If there are no interconnects attached to the corresponding device
155	 * node, of_icc_get() will return NULL.
156	 *
157	 * If the MDP5/DPU device node doesn't have interconnects, lookup the
158	 * path in the parent (MDSS) device.
159	 */
160	return of_icc_get(mdss_dev, name);
161
162}