]> Git Repo - linux.git/blob - drivers/gpu/drm/msm/msm_io_utils.c
Merge branch 'md-fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md...
[linux.git] / drivers / gpu / drm / msm / msm_io_utils.c
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 <[email protected]>
6  */
7
8 #include <linux/interconnect.h>
9
10 #include "msm_drv.h"
11
12 /*
13  * Util/helpers:
14  */
15
16 struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
17                 const char *name)
18 {
19         int i;
20         char n[32];
21
22         snprintf(n, sizeof(n), "%s_clk", name);
23
24         for (i = 0; bulk && i < count; i++) {
25                 if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
26                         return bulk[i].clk;
27         }
28
29
30         return NULL;
31 }
32
33 struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
34 {
35         struct clk *clk;
36         char name2[32];
37
38         clk = devm_clk_get(&pdev->dev, name);
39         if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
40                 return clk;
41
42         snprintf(name2, sizeof(name2), "%s_clk", name);
43
44         clk = devm_clk_get(&pdev->dev, name2);
45         if (!IS_ERR(clk))
46                 dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
47                                 "\"%s\" instead of \"%s\"\n", name, name2);
48
49         return clk;
50 }
51
52 static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
53                                   bool quiet, phys_addr_t *psize)
54 {
55         struct resource *res;
56         unsigned long size;
57         void __iomem *ptr;
58
59         if (name)
60                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
61         else
62                 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
63
64         if (!res) {
65                 if (!quiet)
66                         DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
67                 return ERR_PTR(-EINVAL);
68         }
69
70         size = resource_size(res);
71
72         ptr = devm_ioremap(&pdev->dev, res->start, size);
73         if (!ptr) {
74                 if (!quiet)
75                         DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
76                 return ERR_PTR(-ENOMEM);
77         }
78
79         if (psize)
80                 *psize = size;
81
82         return ptr;
83 }
84
85 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
86 {
87         return _msm_ioremap(pdev, name, false, NULL);
88 }
89
90 void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
91 {
92         return _msm_ioremap(pdev, name, true, NULL);
93 }
94
95 void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
96                           phys_addr_t *psize)
97 {
98         return _msm_ioremap(pdev, name, false, psize);
99 }
100
101 static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
102 {
103         struct msm_hrtimer_work *work = container_of(t,
104                         struct msm_hrtimer_work, timer);
105
106         kthread_queue_work(work->worker, &work->work);
107
108         return HRTIMER_NORESTART;
109 }
110
111 void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
112                             ktime_t wakeup_time,
113                             enum hrtimer_mode mode)
114 {
115         hrtimer_start(&work->timer, wakeup_time, mode);
116 }
117
118 void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
119                            struct kthread_worker *worker,
120                            kthread_work_func_t fn,
121                            clockid_t clock_id,
122                            enum hrtimer_mode mode)
123 {
124         hrtimer_init(&work->timer, clock_id, mode);
125         work->timer.function = msm_hrtimer_worktimer;
126         work->worker = worker;
127         kthread_init_work(&work->work, fn);
128 }
129
130 struct icc_path *msm_icc_get(struct device *dev, const char *name)
131 {
132         struct device *mdss_dev = dev->parent;
133         struct icc_path *path;
134
135         path = of_icc_get(dev, name);
136         if (path)
137                 return path;
138
139         /*
140          * If there are no interconnects attached to the corresponding device
141          * node, of_icc_get() will return NULL.
142          *
143          * If the MDP5/DPU device node doesn't have interconnects, lookup the
144          * path in the parent (MDSS) device.
145          */
146         return of_icc_get(mdss_dev, name);
147
148 }
This page took 0.04484 seconds and 4 git commands to generate.