1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
/*
* include/mach/isomgr.h
*
* Copyright (c) 2012-2018, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _INCLUDE_MACH_ISOMGR_H
#define _INCLUDE_MACH_ISOMGR_H
#include <linux/platform/tegra/emc_bwmgr.h>
#include <linux/platform/tegra/iso_client.h>
#define ISOMGR_MAGIC 0x150A1C
/* handle to identify registered client */
#define tegra_isomgr_handle void *
/* callback to client to renegotiate ISO BW allocation */
typedef void (*tegra_isomgr_renegotiate)(void *priv,
u32 avail_bw); /* KB/sec */
struct isoclient_info {
enum tegra_iso_client client;
char *name;
char *dev_name;
char *emc_clk_name;
enum tegra_bwmgr_client_id bwmgr_id;
};
struct isomgr_client {
u32 magic; /* magic to identify handle */
struct kref kref; /* ref counting */
s32 dedi_bw; /* BW dedicated to this client (KB/sec) */
s32 rsvd_bw; /* BW reserved for this client (KB/sec) */
s32 real_bw; /* BW realized for this client (KB/sec) */
s32 lti; /* Client spec'd Latency Tolerance (usec) */
s32 lto; /* MC calculated Latency Tolerance (usec) */
s32 rsvd_mf; /* reserved minimum freq in support of LT */
s32 real_mf; /* realized minimum freq in support of LT */
s32 real_mf_rq; /* real_mf requested */
tegra_isomgr_renegotiate renegotiate; /* ask client to renegotiate */
bool realize; /* bw realization in progress */
s32 sleep_bw; /* sleeping for realize */
s32 margin_bw; /* BW set aside for this client (KB/sec) */
u8 limit_bw_percentage; /* Insufficient HW buffers cause BW to be
* limited to this percentage of DRAM BW
*/
void *priv; /* client driver's private data */
struct completion cmpl; /* so we can sleep waiting for delta BW */
#ifdef CONFIG_COMMON_CLK
struct tegra_bwmgr_client *bwmgr_handle;
#else
struct clk *emc_clk; /* client emc clk for bw */
#endif
#ifdef CONFIG_TEGRA_ISOMGR_SYSFS
struct kobject *client_kobj;
struct isomgr_client_attrs {
struct kobj_attribute dedi_bw;
struct kobj_attribute rsvd_bw;
struct kobj_attribute real_bw;
struct kobj_attribute lti;
struct kobj_attribute lto;
struct kobj_attribute rsvd_mf;
struct kobj_attribute real_mf;
struct kobj_attribute sleep_bw;
struct kobj_attribute margin_bw;
} client_attrs;
#endif /* CONFIG_TEGRA_ISOMGR_SYSFS */
};
struct isomgr {
struct mutex lock; /* to lock ALL isomgr state */
struct task_struct *task; /* check reentrant/mismatched locks */
#ifdef CONFIG_COMMON_CLK
struct tegra_bwmgr_client *bwmgr_handle;
#else
struct clk *emc_clk; /* isomgr emc clock for floor freq */
#endif
s32 lt_mf; /* min freq to support worst LT */
s32 lt_mf_rq; /* requested lt_mf */
s32 avail_bw; /* globally available MC BW */
s32 dedi_bw; /* total BW 'dedicated' to clients */
s32 sleep_bw; /* pending bw requirement */
u32 max_iso_bw; /* max ISO BW MC can accommodate */
struct kobject *kobj; /* for sysfs linkage */
struct isomgr_ops *ops; /* ops structure for isomgr*/
};
extern struct isoclient_info *isoclient_info;
/*platform specific flag for requesting max emc floor req for camera client*/
extern u8 isomgr_camera_max_floor_req;
extern int isoclients;
extern bool client_valid[TEGRA_ISO_CLIENT_COUNT];
extern struct isomgr_client isomgr_clients[TEGRA_ISO_CLIENT_COUNT];
extern struct isomgr isomgr;
extern char *cname[];
struct isomgr_ops {
void (*isomgr_plat_init)(void);
bool (*isomgr_plat_register)(u32 dedi_bw,
enum tegra_iso_client client);
void (*isomgr_plat_unregister)(struct isomgr_client *cp);
bool (*isomgr_plat_reserve)(struct isomgr_client *cp,
u32 bw, enum tegra_iso_client client);
bool (*isomgr_plat_realize)(struct isomgr_client *cp);
u32 (*isomgr_max_iso_bw)(enum tegra_iso_client client);
};
struct isomgr_ops *pre_t19x_isomgr_init(void);
struct isomgr_ops *t19x_isomgr_init(void);
#if defined(CONFIG_TEGRA_ISOMGR)
/* Register an ISO BW client */
tegra_isomgr_handle tegra_isomgr_register(enum tegra_iso_client client,
u32 dedicated_bw, /* KB/sec */
tegra_isomgr_renegotiate renegotiate,
void *priv);
/* Unregister an ISO BW client */
void tegra_isomgr_unregister(tegra_isomgr_handle handle);
/* Reserve ISO BW on behalf of client - don't apply, rval is dvfs thresh usec */
u32 tegra_isomgr_reserve(tegra_isomgr_handle handle,
u32 bw, /* KB/sec */
u32 lt); /* usec */
/* Realize client reservation - apply settings, rval is dvfs thresh usec */
u32 tegra_isomgr_realize(tegra_isomgr_handle handle);
/* This sets bw aside for the client specified. */
int tegra_isomgr_set_margin(enum tegra_iso_client client, u32 bw, bool wait);
int tegra_isomgr_get_imp_time(enum tegra_iso_client, u32 bw);
/* returns available in iso bw in KB/sec */
u32 tegra_isomgr_get_available_iso_bw(void);
/* returns total iso bw in KB/sec */
u32 tegra_isomgr_get_total_iso_bw(enum tegra_iso_client client);
/* Initialize isomgr.
* This api would be called by .init_machine during boot.
* isomgr clients, don't call this api.
*/
int __init isomgr_init(void);
#else
static inline tegra_isomgr_handle tegra_isomgr_register(
enum tegra_iso_client client,
u32 dedicated_bw,
tegra_isomgr_renegotiate renegotiate,
void *priv)
{
/* return a dummy handle to allow client function
* as if isomgr were enabled.
*/
return (tegra_isomgr_handle)1;
}
static inline void tegra_isomgr_unregister(tegra_isomgr_handle handle) {}
static inline u32 tegra_isomgr_reserve(tegra_isomgr_handle handle,
u32 bw, u32 lt)
{
return 1;
}
static inline u32 tegra_isomgr_realize(tegra_isomgr_handle handle)
{
return 1;
}
static inline int tegra_isomgr_set_margin(enum tegra_iso_client client, u32 bw)
{
return 0;
}
static inline int tegra_isomgr_get_imp_time(enum tegra_iso_client client,
u32 bw)
{
return 0;
}
static inline u32 tegra_isomgr_get_available_iso_bw(void)
{
return UINT_MAX;
}
static inline u32 tegra_isomgr_get_total_iso_bw(enum tegra_iso_client client)
{
return UINT_MAX;
}
static inline int isomgr_init(void)
{
return 0;
}
#endif
#endif /* _INCLUDE_MACH_ISOMGR_H */
|