]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - include/linux/platform/tegra/emc_bwmgr.h
nvpmodel: add nvpmodel_emc_cap driver and sysfs
[hercules2020/nv-tegra/linux-4.4.git] / include / linux / platform / tegra / emc_bwmgr.h
1 /**
2  * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  */
13
14 #ifndef __EMC_BWMGR_H
15 #define __EMC_BWMGR_H
16
17 #include <linux/clk.h>
18 #include <linux/device.h>
19 #include <linux/of_address.h>
20
21 /* keep in sync with tegra_bwmgr_client_names */
22 enum tegra_bwmgr_client_id {
23         TEGRA_BWMGR_CLIENT_CPU_0,
24         TEGRA_BWMGR_CLIENT_CPU_1,
25         TEGRA_BWMGR_CLIENT_DISP0,
26         TEGRA_BWMGR_CLIENT_DISP1,
27         TEGRA_BWMGR_CLIENT_DISP2,
28         TEGRA_BWMGR_CLIENT_USBD,
29         TEGRA_BWMGR_CLIENT_XHCI,
30         TEGRA_BWMGR_CLIENT_SDMMC1,
31         TEGRA_BWMGR_CLIENT_SDMMC2,
32         TEGRA_BWMGR_CLIENT_SDMMC3,
33         TEGRA_BWMGR_CLIENT_SDMMC4,
34         TEGRA_BWMGR_CLIENT_MON,
35         TEGRA_BWMGR_CLIENT_GPU,
36         TEGRA_BWMGR_CLIENT_MSENC,
37         TEGRA_BWMGR_CLIENT_NVJPG,
38         TEGRA_BWMGR_CLIENT_NVDEC,
39         TEGRA_BWMGR_CLIENT_TSEC,
40         TEGRA_BWMGR_CLIENT_TSECB,
41         TEGRA_BWMGR_CLIENT_VI,
42         TEGRA_BWMGR_CLIENT_ISPA,
43         TEGRA_BWMGR_CLIENT_ISPB,
44         TEGRA_BWMGR_CLIENT_CAMERA,
45         TEGRA_BWMGR_CLIENT_ISOMGR,
46         TEGRA_BWMGR_CLIENT_THERMAL_CAP,
47         TEGRA_BWMGR_CLIENT_VIC,
48         TEGRA_BWMGR_CLIENT_APE_ADSP,
49         TEGRA_BWMGR_CLIENT_APE_ADMA,
50         TEGRA_BWMGR_CLIENT_PCIE,
51         TEGRA_BWMGR_CLIENT_BBC_0,
52         TEGRA_BWMGR_CLIENT_EQOS,
53         TEGRA_BWMGR_CLIENT_SE0,
54         TEGRA_BWMGR_CLIENT_SE1,
55         TEGRA_BWMGR_CLIENT_SE2,
56         TEGRA_BWMGR_CLIENT_SE3,
57         TEGRA_BWMGR_CLIENT_SE4,
58         TEGRA_BWMGR_CLIENT_PMQOS,
59         TEGRA_BWMGR_CLIENT_NVPMODEL,
60         TEGRA_BWMGR_CLIENT_DEBUG,
61         TEGRA_BWMGR_CLIENT_COUNT /* Should always be last */
62 };
63
64 enum tegra_bwmgr_request_type {
65         TEGRA_BWMGR_SET_EMC_FLOOR, /* lower bound */
66         TEGRA_BWMGR_SET_EMC_CAP, /* upper bound */
67         TEGRA_BWMGR_SET_EMC_ISO_CAP, /* upper bound that affects ISO Bw */
68         TEGRA_BWMGR_SET_EMC_SHARED_BW, /* shared bw request */
69         TEGRA_BWMGR_SET_EMC_SHARED_BW_ISO, /* for use by ISO Mgr only */
70         TEGRA_BWMGR_SET_EMC_REQ_COUNT /* Should always be last */
71 };
72
73 enum bwmgr_dram_types {
74         DRAM_TYPE_NONE,
75         DRAM_TYPE_LPDDR4_4CH_ECC,
76         DRAM_TYPE_LPDDR4_2CH_ECC,
77         DRAM_TYPE_LPDDR4_4CH,
78         DRAM_TYPE_LPDDR4_2CH,
79         DRAM_TYPE_LPDDR3_2CH,
80         DRAM_TYPE_DDR3_2CH
81 };
82
83 extern u8 bwmgr_dram_efficiency;
84 extern u32 *bwmgr_dram_iso_eff_table;
85 extern int bwmgr_iso_bw_percentage;
86 extern enum bwmgr_dram_types bwmgr_dram_type;
87 extern int emc_to_dram_freq_factor;
88 void bwmgr_eff_init(void);
89
90 struct tegra_bwmgr_client;
91
92 #if defined(CONFIG_TEGRA_BWMGR)
93 /**
94  * tegra_bwmgr_register - register an EMC Bandwidth Manager client.
95  *                        Also see tegra_bwmgr_unregister().
96  * @client      client id from tegra_bwmgr_client_id
97  *
98  * Returns a valid handle on successful registration, NULL on error.
99  */
100 struct tegra_bwmgr_client *tegra_bwmgr_register(
101                 enum tegra_bwmgr_client_id client);
102
103 /**
104  * tegra_bwmgr_unregister - unregister an EMC Bandwidth Manager client.
105  *                          Callers should match register/unregister calls.
106  *                          Persistence of old requests across
107  *                          register/unregister calls is undefined.
108  *                          Also see tegra_bwmgr_set_emc()
109  *
110  * @handle      handle acquired during tegra_bwmgr_register
111  */
112 void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle);
113
114 /**
115  * tegra_bwmgr_get_emc_rate - get the current EMC rate.
116  *
117  * Returns current memory clock rate in Hz.
118  */
119 unsigned long tegra_bwmgr_get_emc_rate(void);
120
121 /**
122  * tegra_bwmgr_get_max_emc_rate - get the max EMC rate.
123  *
124  * Returns the max memory clock rate in Hz.
125  */
126 unsigned long tegra_bwmgr_get_max_emc_rate(void);
127
128 /**
129  * tegra_bwmgr_get_core_emc_rate - get the actual emc frequency calculated
130  *                      using the dram frequency and emc_to_dram
131  *                      conversion factor.
132  *
133  * Returns the core emc rate in Hz.
134  */
135 unsigned long tegra_bwmgr_get_core_emc_rate(void);
136
137 /**
138  * tegra_bwmgr_round_rate - round up to next EMC rate which can be provided
139  *
140  * @bw          Input rate
141  *
142  * Returns the next higher rate from the Input rate that EMC can run at.
143  */
144 unsigned long tegra_bwmgr_round_rate(unsigned long bw);
145
146 /**
147  * tegra_bwmgr_set_emc - request to bwmgr to set an EMC rate parameter.
148  *                       Actual clock rate depends on aggregation of
149  *                       requests by all clients. If needed, use
150  *                       tegra_bwmgr_get_emc_rate() to get the rate after
151  *                       a tegra_bwmgr_set_emc() call.
152  *
153  *                       Call tegra_bwmgr_set_emc() with same request type and
154  *                       val = 0 to clear request.
155  *
156  * @handle      handle acquired during tegra_bwmgr_register
157  * @val         value to be set in Hz, 0 to clear old request of the same type
158  * @req         chosen type from tegra_bwmgr_request_type
159  *
160  * Returns success (0) or negative errno.
161  */
162 int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle, unsigned long val,
163                 enum tegra_bwmgr_request_type req);
164
165 /**
166  * tegra_bwmgr_notifier_register - register a notifier callback when
167  *              emc rate changes. Must be called from non-atomic
168  *              context. The callback must not call any bwmgr API.
169  * @nb          linux notifier block
170  *
171  * Returns success (0) or negative errno.
172  */
173 int tegra_bwmgr_notifier_register(struct notifier_block *nb);
174
175 /**
176  * tegra_bwmgr_notifier_unregister - unregister a notifier callback.
177  * @nb          linux notifier block
178  *
179  * Returns success (0) or negative errno.
180  */
181 int tegra_bwmgr_notifier_unregister(struct notifier_block *nb);
182
183 /*
184  * Initialize bwmgr.
185  * This api would be called by .init_machine during boot.
186  * bwmgr clients, don't call this api.
187  */
188 int __init bwmgr_init(void);
189
190 void __exit bwmgr_exit(void);
191
192 /*
193  * Initialize pmqos bwmgr code which registers pmqos as bwmgr client and
194  * registers a notifier which gets called on update to PMQOS_EMC_FREQ_MIN.
195  */
196 int __init pmqos_bwmgr_init(void);
197
198 #else /* CONFIG_TEGRA_BWMGR */
199
200 static inline struct tegra_bwmgr_client *tegra_bwmgr_register(
201                 enum tegra_bwmgr_client_id client_id)
202 {
203         static int i;
204         /* return a dummy handle to allow client to function
205          * as if bwmgr were enabled.
206          */
207         return (struct tegra_bwmgr_client *) &i;
208 }
209
210 static inline void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle) {}
211
212 static inline int bwmgr_init(void)
213 {
214         return 0;
215 }
216
217 static inline void bwmgr_exit(void) {}
218
219 static inline unsigned long tegra_bwmgr_get_emc_rate(void)
220 {
221         static struct clk *bwmgr_emc_clk;
222         struct device_node *dn;
223
224         if (!bwmgr_emc_clk) {
225                 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
226                 if (dn == NULL) {
227                         pr_err("bwmgr: dt node not found.\n");
228                         return 0;
229                 }
230
231                 bwmgr_emc_clk = of_clk_get(dn, 0);
232                 if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
233                         pr_err("bwmgr: couldn't find emc clock.\n");
234                         bwmgr_emc_clk = NULL;
235                         WARN_ON(true);
236                         return 0;
237                 }
238         }
239
240         return clk_get_rate(bwmgr_emc_clk);
241 }
242
243 static inline unsigned long tegra_bwmgr_get_max_emc_rate(void)
244 {
245         static struct clk *bwmgr_emc_clk;
246         struct device_node *dn;
247
248         if (!bwmgr_emc_clk) {
249                 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
250                 if (dn == NULL) {
251                         pr_err("bwmgr: dt node not found.\n");
252                         return 0;
253                 }
254
255                 bwmgr_emc_clk = of_clk_get(dn, 0);
256                 if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
257                         pr_err("bwmgr: couldn't find emc clock.\n");
258                         bwmgr_emc_clk = NULL;
259                         WARN_ON(true);
260                         return 0;
261                 }
262         }
263
264         /* Use LONG_MAX as clk_round_rate treats rate argument as signed */
265         return clk_round_rate(bwmgr_emc_clk, LONG_MAX);
266 }
267
268 static inline unsigned long tegra_bwmgr_get_core_emc_rate(void)
269 {
270         return 0;
271 }
272 static inline unsigned long tegra_bwmgr_round_rate(unsigned long bw)
273 {
274         static struct clk *bwmgr_emc_clk;
275         struct device_node *dn;
276
277         if (!bwmgr_emc_clk) {
278                 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
279                 if (dn == NULL) {
280                         pr_err("bwmgr: dt node not found.\n");
281                         return 0;
282                 }
283
284                 bwmgr_emc_clk = of_clk_get(dn, 0);
285                 if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
286                         pr_err("bwmgr: couldn't find emc clock.\n");
287                         bwmgr_emc_clk = NULL;
288                         WARN_ON(true);
289                         return 0;
290                 }
291         }
292
293         return clk_round_rate(bwmgr_emc_clk, bw);
294 }
295
296 static inline int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle,
297                 unsigned long val, enum tegra_bwmgr_request_type req)
298 {
299         return 0;
300 }
301
302 static inline int tegra_bwmgr_notifier_register(struct notifier_block *nb)
303 {
304         return 0;
305 }
306
307 static inline int tegra_bwmgr_notifier_unregister(struct notifier_block *nb)
308 {
309         return 0;
310 }
311
312 #endif /* CONFIG_TEGRA_BWMGR */
313 #endif /* __EMC_BWMGR_H */
314