2 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
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.
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
17 #include <linux/clk.h>
18 #include <linux/device.h>
19 #include <linux/of_address.h>
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 */
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 */
73 enum bwmgr_dram_types {
75 DRAM_TYPE_LPDDR4_4CH_ECC,
76 DRAM_TYPE_LPDDR4_2CH_ECC,
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);
90 struct tegra_bwmgr_client;
92 #if defined(CONFIG_TEGRA_BWMGR)
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
98 * Returns a valid handle on successful registration, NULL on error.
100 struct tegra_bwmgr_client *tegra_bwmgr_register(
101 enum tegra_bwmgr_client_id client);
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()
110 * @handle handle acquired during tegra_bwmgr_register
112 void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle);
115 * tegra_bwmgr_get_emc_rate - get the current EMC rate.
117 * Returns current memory clock rate in Hz.
119 unsigned long tegra_bwmgr_get_emc_rate(void);
122 * tegra_bwmgr_get_max_emc_rate - get the max EMC rate.
124 * Returns the max memory clock rate in Hz.
126 unsigned long tegra_bwmgr_get_max_emc_rate(void);
129 * tegra_bwmgr_get_core_emc_rate - get the actual emc frequency calculated
130 * using the dram frequency and emc_to_dram
133 * Returns the core emc rate in Hz.
135 unsigned long tegra_bwmgr_get_core_emc_rate(void);
138 * tegra_bwmgr_round_rate - round up to next EMC rate which can be provided
142 * Returns the next higher rate from the Input rate that EMC can run at.
144 unsigned long tegra_bwmgr_round_rate(unsigned long bw);
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.
153 * Call tegra_bwmgr_set_emc() with same request type and
154 * val = 0 to clear request.
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
160 * Returns success (0) or negative errno.
162 int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle, unsigned long val,
163 enum tegra_bwmgr_request_type req);
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
171 * Returns success (0) or negative errno.
173 int tegra_bwmgr_notifier_register(struct notifier_block *nb);
176 * tegra_bwmgr_notifier_unregister - unregister a notifier callback.
177 * @nb linux notifier block
179 * Returns success (0) or negative errno.
181 int tegra_bwmgr_notifier_unregister(struct notifier_block *nb);
185 * This api would be called by .init_machine during boot.
186 * bwmgr clients, don't call this api.
188 int __init bwmgr_init(void);
190 void __exit bwmgr_exit(void);
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.
196 int __init pmqos_bwmgr_init(void);
198 #else /* CONFIG_TEGRA_BWMGR */
200 static inline struct tegra_bwmgr_client *tegra_bwmgr_register(
201 enum tegra_bwmgr_client_id client_id)
204 /* return a dummy handle to allow client to function
205 * as if bwmgr were enabled.
207 return (struct tegra_bwmgr_client *) &i;
210 static inline void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle) {}
212 static inline int bwmgr_init(void)
217 static inline void bwmgr_exit(void) {}
219 static inline unsigned long tegra_bwmgr_get_emc_rate(void)
221 static struct clk *bwmgr_emc_clk;
222 struct device_node *dn;
224 if (!bwmgr_emc_clk) {
225 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
227 pr_err("bwmgr: dt node not found.\n");
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;
240 return clk_get_rate(bwmgr_emc_clk);
243 static inline unsigned long tegra_bwmgr_get_max_emc_rate(void)
245 static struct clk *bwmgr_emc_clk;
246 struct device_node *dn;
248 if (!bwmgr_emc_clk) {
249 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
251 pr_err("bwmgr: dt node not found.\n");
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;
264 /* Use LONG_MAX as clk_round_rate treats rate argument as signed */
265 return clk_round_rate(bwmgr_emc_clk, LONG_MAX);
268 static inline unsigned long tegra_bwmgr_get_core_emc_rate(void)
272 static inline unsigned long tegra_bwmgr_round_rate(unsigned long bw)
274 static struct clk *bwmgr_emc_clk;
275 struct device_node *dn;
277 if (!bwmgr_emc_clk) {
278 dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
280 pr_err("bwmgr: dt node not found.\n");
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;
293 return clk_round_rate(bwmgr_emc_clk, bw);
296 static inline int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle,
297 unsigned long val, enum tegra_bwmgr_request_type req)
302 static inline int tegra_bwmgr_notifier_register(struct notifier_block *nb)
307 static inline int tegra_bwmgr_notifier_unregister(struct notifier_block *nb)
312 #endif /* CONFIG_TEGRA_BWMGR */
313 #endif /* __EMC_BWMGR_H */