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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
/* Copyright (c) 2012-2014, The Linux Foundation. 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 and
* only 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.
*/
#ifndef _ARCH_ARM_MACH_MSM_OCMEM_PRIV_H
#define _ARCH_ARM_MACH_MSM_OCMEM_PRIV_H
/** All interfaces in this header should only be used by OCMEM driver
* Client drivers should use wrappers available in ocmem.h
**/
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <soc/qcom/ocmem.h>
#define OCMEM_PHYS_BASE 0xFEC00000
#define OCMEM_PHYS_SIZE 0x180000
#define TO_OCMEM 0x0
#define TO_DDR 0x1
#define OCMEM_SVC_ID 15
#define OCMEM_LOCK_CMD_ID 0x1
#define OCMEM_UNLOCK_CMD_ID 0x2
#define OCMEM_ENABLE_DUMP_CMD_ID 0x3
#define OCMEM_DISABLE_DUMP_CMD_ID 0x4
#define OCMEM_SECURE_SVC_ID 12
#define OCMEM_SECURE_CFG_ID 0x2
#define OCMEM_SECURE_DEV_ID 0x5
struct ocmem_zone;
struct ocmem_zone_ops {
int (*allocate) (struct ocmem_zone *, unsigned long, unsigned long *);
int (*free) (struct ocmem_zone *, unsigned long, unsigned long);
};
/* OCMEM Zone specific counters */
/* Must be in sync with zstat_names */
enum ocmem_zstat_item {
NR_REQUESTS = 0x0,
NR_SYNC_ALLOCATIONS,
NR_RANGE_ALLOCATIONS,
NR_ASYNC_ALLOCATIONS,
NR_ALLOCATION_FAILS,
NR_GROWTHS,
NR_FREES,
NR_SHRINKS,
NR_MAPS,
NR_MAP_FAILS,
NR_UNMAPS,
NR_UNMAP_FAILS,
NR_TRANSFERS_TO_OCMEM,
NR_TRANSFERS_TO_DDR,
NR_TRANSFER_FAILS,
NR_EVICTIONS,
NR_RESTORES,
NR_DUMP_REQUESTS,
NR_DUMP_COMPLETE,
NR_OCMEM_ZSTAT_ITEMS,
};
struct ocmem_zone {
bool active;
int owner;
int active_regions;
int max_regions;
struct list_head req_list;
unsigned long z_start;
unsigned long z_end;
unsigned long z_head;
unsigned long z_tail;
unsigned long z_free;
atomic_long_t z_stat[NR_OCMEM_ZSTAT_ITEMS];
struct gen_pool *z_pool;
struct ocmem_zone_ops *z_ops;
unsigned int max_alloc_time;
unsigned int min_alloc_time;
u64 total_alloc_time;
unsigned int max_free_time;
unsigned int min_free_time;
u64 total_free_time;
};
enum op_code {
SCHED_NOP = 0x0,
SCHED_ALLOCATE,
SCHED_FREE,
SCHED_GROW,
SCHED_SHRINK,
SCHED_MAP,
SCHED_UNMAP,
SCHED_EVICT,
SCHED_RESTORE,
SCHED_DUMP,
};
/* Operational modes of each region */
enum region_mode {
WIDE_MODE = 0x0,
THIN_MODE,
MODE_DEFAULT = WIDE_MODE,
};
struct ocmem_plat_data {
void __iomem *vbase;
unsigned long size;
unsigned long base;
struct clk *core_clk;
struct clk *iface_clk;
struct clk *br_clk;
struct ocmem_partition *parts;
int nr_parts;
void __iomem *reg_base;
void __iomem *br_base;
void __iomem *dm_base;
struct dentry *debug_node;
unsigned nr_regions;
unsigned nr_macros;
unsigned nr_ports;
int ocmem_irq;
int dm_irq;
bool interleaved;
bool rpm_pwr_ctrl;
unsigned rpm_rsc_type;
};
struct ocmem_eviction_data {
struct completion completion;
struct list_head victim_list;
struct list_head req_list;
struct work_struct work;
int prio;
atomic_t pending;
bool passive;
};
struct ocmem_req {
struct rw_semaphore rw_sem;
/* Chain in sched queue */
struct list_head sched_list;
/* Chain in zone list */
struct list_head zone_list;
/* Chain in eviction list */
struct list_head eviction_list;
int owner;
int prio;
uint32_t req_id;
unsigned long req_min;
unsigned long req_max;
unsigned long req_step;
/* reverse pointers */
struct ocmem_zone *zone;
struct ocmem_buf *buffer;
struct ocmem_map_list *mlist;
enum op_code op;
unsigned long state;
/* Request assignments */
unsigned long req_start;
unsigned long req_end;
unsigned long req_sz;
/* Request Power State */
unsigned power_state;
struct ocmem_eviction_data *edata;
/* Eviction data of the request being evicted */
struct ocmem_eviction_data *eviction_info;
};
struct ocmem_handle {
struct ocmem_buf buffer;
struct mutex handle_mutex;
struct ocmem_req *req;
};
struct ocmem_buf *handle_to_buffer(struct ocmem_handle *);
struct ocmem_handle *buffer_to_handle(struct ocmem_buf *);
struct ocmem_req *handle_to_req(struct ocmem_handle *);
struct ocmem_handle *req_to_handle(struct ocmem_req *);
int ocmem_read(void *);
int ocmem_write(unsigned long, void *);
void inc_ocmem_stat(struct ocmem_zone *, enum ocmem_zstat_item);
unsigned long get_ocmem_stat(struct ocmem_zone *z,
enum ocmem_zstat_item item);
struct ocmem_zone *get_zone(unsigned);
int zone_active(int);
unsigned long offset_to_phys(unsigned long);
unsigned long phys_to_offset(unsigned long);
int allocate_head(struct ocmem_zone *, unsigned long, unsigned long *);
int free_head(struct ocmem_zone *, unsigned long, unsigned long);
int allocate_tail(struct ocmem_zone *, unsigned long, unsigned long *);
int free_tail(struct ocmem_zone *, unsigned long, unsigned long);
int ocmem_notifier_init(void);
int check_notifier(int);
const char *get_name(int);
int get_tz_id(int);
int ocmem_restore_sec_program(int);
int ocmem_enable_dump(enum ocmem_client, unsigned long, unsigned long);
int ocmem_disable_dump(enum ocmem_client, unsigned long, unsigned long);
bool is_probe_done(void);
int check_id(int);
int dispatch_notification(int, enum ocmem_notif_type, struct ocmem_buf *);
int ocmem_sched_init(struct platform_device *);
int ocmem_rdm_init(struct platform_device *);
int ocmem_core_init(struct platform_device *);
int process_allocate(int, struct ocmem_handle *, unsigned long, unsigned long,
unsigned long, bool, bool);
int process_free(int, struct ocmem_handle *);
int process_xfer(int, struct ocmem_handle *, struct ocmem_map_list *, int);
int process_drop(int, struct ocmem_handle *, struct ocmem_map_list *);
int process_evict(int);
int process_restore(int);
int process_shrink(int, struct ocmem_handle *, unsigned long);
int process_dump(int, struct ocmem_handle *, unsigned long);
int ocmem_rdm_transfer(int, struct ocmem_map_list *,
unsigned long, int);
unsigned long process_quota(int);
int ocmem_memory_off(int, unsigned long, unsigned long);
int ocmem_memory_on(int, unsigned long, unsigned long);
int ocmem_enable_core_clock(void);
int ocmem_enable_iface_clock(void);
int ocmem_enable_br_clock(void);
void ocmem_disable_core_clock(void);
void ocmem_disable_iface_clock(void);
void ocmem_disable_br_clock(void);
int ocmem_lock(enum ocmem_client, unsigned long, unsigned long,
enum region_mode);
int ocmem_unlock(enum ocmem_client, unsigned long, unsigned long);
#endif
|