summaryrefslogtreecommitdiff
path: root/drivers/platform/msm/sps/spsi.h
blob: 38ee76be13c173febd7153a519c15bca02d72325 (plain)
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
/* Copyright (c) 2011-2017, 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.
 */

/**
 * Smart-Peripheral-Switch (SPS) internal API.
 */

#ifndef _SPSI_H_
#define _SPSI_H_

#include <linux/types.h>	/* u32 */
#include <linux/list.h>		/* list_head */
#include <linux/kernel.h>	/* pr_info() */
#include <linux/compiler.h>
#include <linux/ratelimit.h>
#include <linux/ipc_logging.h>

#include <linux/msm-sps.h>

#include "sps_map.h"

#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_ARM_LPAE)
#define SPS_LPAE (true)
#else
#define SPS_LPAE (false)
#endif

#define BAM_MAX_PIPES              31
#define BAM_MAX_P_LOCK_GROUP_NUM   31

/* Adjust for offset of struct sps_q_event */
#define SPS_EVENT_INDEX(e)    ((e) - 1)
#define SPS_ERROR -1

/* BAM identifier used in log messages */
#define BAM_ID(dev)       (&(dev)->props.phys_addr)

/* "Clear" value for the connection parameter struct */
#define SPSRM_CLEAR     0xccccccccUL
#define SPSRM_ADDR_CLR \
	((sizeof(int) == sizeof(long)) ? 0 : (SPSRM_CLEAR << 32))

#define MAX_MSG_LEN 80
#define SPS_IPC_LOGPAGES 10
#define SPS_IPC_REG_DUMP_FACTOR 3
#define SPS_IPC_DEFAULT_LOGLEVEL 3
#define SPS_IPC_MAX_LOGLEVEL 4

/* Connection mapping control struct */
struct sps_rm {
	struct list_head connections_q;
	struct mutex lock;
};

/* SPS driver state struct */
struct sps_drv {
	struct class *dev_class;
	dev_t dev_num;
	struct device *dev;
	struct clk *pmem_clk;
	struct clk *bamdma_clk;
	struct clk *dfab_clk;

	int is_ready;

	/* Platform data */
	phys_addr_t pipemem_phys_base;
	u32 pipemem_size;
	phys_addr_t bamdma_bam_phys_base;
	u32 bamdma_bam_size;
	phys_addr_t bamdma_dma_phys_base;
	u32 bamdma_dma_size;
	u32 bamdma_irq;
	u32 bamdma_restricted_pipes;

	/* Driver options bitflags (see SPS_OPT_*) */
	u32 options;

	/* Mutex to protect BAM and connection queues */
	struct mutex lock;

	/* BAM devices */
	struct list_head bams_q;

	char *hal_bam_version;

	/* Connection control state */
	struct sps_rm connection_ctrl;

	void *ipc_log0;
	void *ipc_log1;
	void *ipc_log2;
	void *ipc_log3;
	void *ipc_log4;

	u32 ipc_loglevel;
};

extern struct sps_drv *sps;
extern u32 d_type;
extern bool enhd_pipe;
extern bool imem;
extern enum sps_bam_type bam_type;

#ifdef CONFIG_DEBUG_FS
extern u8 debugfs_record_enabled;
extern u8 logging_option;
extern u8 debug_level_option;
extern u8 print_limit_option;

#define SPS_IPC(idx, dev, msg, args...) do { \
		if (dev) { \
			if ((idx == 0) && (dev)->ipc_log0) \
				ipc_log_string((dev)->ipc_log0, \
					"%s: " msg, __func__, args); \
			else if ((idx == 1) && (dev)->ipc_log1) \
				ipc_log_string((dev)->ipc_log1, \
					"%s: " msg, __func__, args); \
			else if ((idx == 2) && (dev)->ipc_log2) \
				ipc_log_string((dev)->ipc_log2, \
					"%s: " msg, __func__, args); \
			else if ((idx == 3) && (dev)->ipc_log3) \
				ipc_log_string((dev)->ipc_log3, \
					"%s: " msg, __func__, args); \
			else if ((idx == 4) && (dev)->ipc_log4) \
				ipc_log_string((dev)->ipc_log4, \
					"%s: " msg, __func__, args); \
			else \
				pr_debug("sps: no such IPC logging index!\n"); \
		} \
	} while (0)
#define SPS_DUMP(msg, args...) do {					\
		SPS_IPC(4, sps, msg, args); \
		if (sps) { \
			if (sps->ipc_log4 == NULL) \
				pr_info(msg, ##args);	\
		} \
	} while (0)
#define SPS_ERR(dev, msg, args...) do {					\
		if (logging_option != 1) {	\
			if (unlikely(print_limit_option > 2))	\
				pr_err_ratelimited(msg, ##args);	\
			else	\
				pr_err(msg, ##args);	\
		}	\
		SPS_IPC(3, dev, msg, args); \
	} while (0)
#define SPS_INFO(dev, msg, args...) do {				\
		if (logging_option != 1) {	\
			if (unlikely(print_limit_option > 1))	\
				pr_info_ratelimited(msg, ##args);	\
			else	\
				pr_info(msg, ##args);	\
		}	\
		SPS_IPC(3, dev, msg, args); \
	} while (0)
#define SPS_DBG(dev, msg, args...) do {					\
		if ((unlikely(logging_option > 1))	\
			&& (unlikely(debug_level_option > 3))) {\
			if (unlikely(print_limit_option > 0))	\
				pr_info_ratelimited(msg, ##args);	\
			else	\
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (dev) { \
			if ((dev)->ipc_loglevel <= 0)	\
				SPS_IPC(0, dev, msg, args); \
		}	\
	} while (0)
#define SPS_DBG1(dev, msg, args...) do {				\
		if ((unlikely(logging_option > 1))	\
			&& (unlikely(debug_level_option > 2))) {\
			if (unlikely(print_limit_option > 0))	\
				pr_info_ratelimited(msg, ##args);	\
			else	\
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (dev) { \
			if ((dev)->ipc_loglevel <= 1)	\
				SPS_IPC(1, dev, msg, args);	\
		}	\
	} while (0)
#define SPS_DBG2(dev, msg, args...) do {				\
		if ((unlikely(logging_option > 1))	\
			&& (unlikely(debug_level_option > 1))) {\
			if (unlikely(print_limit_option > 0))	\
				pr_info_ratelimited(msg, ##args);	\
			else	\
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (dev) { \
			if ((dev)->ipc_loglevel <= 2)	\
				SPS_IPC(2, dev, msg, args); \
		}	\
	} while (0)
#define SPS_DBG3(dev, msg, args...) do {				\
		if ((unlikely(logging_option > 1))	\
			&& (unlikely(debug_level_option > 0))) {\
			if (unlikely(print_limit_option > 0))	\
				pr_info_ratelimited(msg, ##args);	\
			else	\
				pr_info(msg, ##args);	\
		} else	\
			pr_debug(msg, ##args);	\
		if (dev) { \
			if ((dev)->ipc_loglevel <= 3)	\
				SPS_IPC(3, dev, msg, args); \
		}	\
	} while (0)
#else
#define	SPS_DBG3(x...)		pr_debug(x)
#define	SPS_DBG2(x...)		pr_debug(x)
#define	SPS_DBG1(x...)		pr_debug(x)
#define	SPS_DBG(x...)		pr_debug(x)
#define	SPS_INFO(x...)		pr_info(x)
#define	SPS_ERR(x...)		pr_err(x)
#define	SPS_DUMP(x...)		pr_info(x)
#endif

/* End point parameters */
struct sps_conn_end_pt {
	unsigned long dev;		/* Device handle of BAM */
	phys_addr_t bam_phys;		/* Physical address of BAM. */
	u32 pipe_index;		/* Pipe index */
	u32 event_threshold;	/* Pipe event threshold */
	u32 lock_group;	/* The lock group this pipe belongs to */
	void *bam;
};

/* Connection bookkeeping descriptor struct */
struct sps_connection {
	struct list_head list;

	/* Source end point parameters */
	struct sps_conn_end_pt src;

	/* Destination end point parameters */
	struct sps_conn_end_pt dest;

	/* Resource parameters */
	struct sps_mem_buffer desc;	/* Descriptor FIFO */
	struct sps_mem_buffer data;	/* Data FIFO (BAM-to-BAM mode only) */
	u32 config;		/* Client specified connection configuration */

	/* Connection state */
	void *client_src;
	void *client_dest;
	int refs;		/* Reference counter */

	/* Dynamically allocated resouces, if required */
	u32 alloc_src_pipe;	/* Source pipe index */
	u32 alloc_dest_pipe;	/* Destination pipe index */
	/* Physical address of descriptor FIFO */
	phys_addr_t alloc_desc_base;
	phys_addr_t alloc_data_base;	/* Physical address of data FIFO */
};

/* Event bookkeeping descriptor struct */
struct sps_q_event {
	struct list_head list;
	/* Event payload data */
	struct sps_event_notify notify;
};

/* Memory heap statistics */
struct sps_mem_stats {
	u32 base_addr;
	u32 size;
	u32 blocks_used;
	u32 bytes_used;
	u32 max_bytes_used;
};

enum sps_bam_type {
	SPS_BAM_LEGACY,
	SPS_BAM_NDP,
	SPS_BAM_NDP_4K
};

#ifdef CONFIG_DEBUG_FS
/* record debug info for debugfs */
void sps_debugfs_record(const char *);
#endif

/* output the content of BAM-level registers */
void print_bam_reg(void *);

/* output the content of BAM pipe registers */
void print_bam_pipe_reg(void *, u32);

/* output the content of selected BAM-level registers */
void print_bam_selected_reg(void *, u32);

/* output the content of selected BAM pipe registers */
void print_bam_pipe_selected_reg(void *, u32);

/* output descriptor FIFO of a pipe */
void print_bam_pipe_desc_fifo(void *, u32, u32);

/* output BAM_TEST_BUS_REG */
void print_bam_test_bus_reg(void *, u32);

/* halt and un-halt a pipe */
void bam_pipe_halt(void *, u32, bool);

/**
 * Translate physical to virtual address
 *
 * This Function translates physical to virtual address.
 *
 * @phys_addr - physical address to translate
 *
 * @return virtual memory pointer
 *
 */
void *spsi_get_mem_ptr(phys_addr_t phys_addr);

/**
 * Allocate I/O (pipe) memory
 *
 * This function allocates target I/O (pipe) memory.
 *
 * @bytes - number of bytes to allocate
 *
 * @return physical address of allocated memory, or SPS_ADDR_INVALID on error
 */
phys_addr_t sps_mem_alloc_io(u32 bytes);

/**
 * Free I/O (pipe) memory
 *
 * This function frees target I/O (pipe) memory.
 *
 * @phys_addr - physical address of memory to free
 *
 * @bytes - number of bytes to free.
 */
void sps_mem_free_io(phys_addr_t phys_addr, u32 bytes);

/**
 * Find matching connection mapping
 *
 * This function searches for a connection mapping that matches the
 * parameters supplied by the client.  If a match is found, the client's
 * parameter struct is updated with the values specified in the mapping.
 *
 * @connect - pointer to client connection parameters
 *
 * @return 0 if match is found, negative value otherwise
 *
 */
int sps_map_find(struct sps_connect *connect);

/**
 * Allocate a BAM DMA pipe
 *
 * This function allocates a BAM DMA pipe, and is intended to be called
 * internally from the BAM resource manager.  Allocation implies that
 * the pipe has been referenced by a client Connect() and is in use.
 *
 * BAM DMA is permissive with activations, and allows a pipe to be allocated
 * with or without a client-initiated allocation.  This allows the client to
 * specify exactly which pipe should be used directly through the Connect() API.
 * sps_dma_alloc_chan() does not allow the client to specify the pipes/channel.
 *
 * @bam - pointer to BAM device descriptor
 *
 * @pipe_index - pipe index
 *
 * @dir - pipe direction
 *
 * @return 0 on success, negative value on error
 */
int sps_dma_pipe_alloc(void *bam, u32 pipe_index, enum sps_mode dir);

/**
 * Enable a BAM DMA pipe
 *
 * This function enables the channel associated with a BAM DMA pipe, and
 * is intended to be called internally from the BAM resource manager.
 * Enable must occur *after* the pipe has been enabled so that proper
 * sequencing between pipe and DMA channel enables can be enforced.
 *
 * @bam - pointer to BAM device descriptor
 *
 * @pipe_index - pipe index
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_dma_pipe_enable(void *bam, u32 pipe_index);

/**
 * Free a BAM DMA pipe
 *
 * This function disables and frees a BAM DMA pipe, and is intended to be
 * called internally from the BAM resource manager.  This must occur *after*
 * the pipe has been disabled/reset so that proper sequencing between pipe and
 * DMA channel resets can be enforced.
 *
 * @bam_arg - pointer to BAM device descriptor
 *
 * @pipe_index - pipe index
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_dma_pipe_free(void *bam, u32 pipe_index);

/**
 * Initialize driver memory module
 *
 * This function initializes the driver memory module.
 *
 * @pipemem_phys_base - Pipe-Memory physical base.
 *
 * @pipemem_size - Pipe-Memory size.
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_mem_init(phys_addr_t pipemem_phys_base, u32 pipemem_size);

/**
 * De-initialize driver memory module
 *
 * This function de-initializes the driver memory module.
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_mem_de_init(void);

/**
 * Initialize BAM DMA module
 *
 * This function initializes the BAM DMA module.
 *
 * @bam_props - pointer to BAM DMA devices BSP configuration properties
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_dma_init(const struct sps_bam_props *bam_props);

/**
 * De-initialize BAM DMA module
 *
 * This function de-initializes the SPS BAM DMA module.
 *
 */
void sps_dma_de_init(void);

/**
 * Initialize BAM DMA device
 *
 * This function initializes a BAM DMA device.
 *
 * @h - BAM handle
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_dma_device_init(unsigned long h);

/**
 * De-initialize BAM DMA device
 *
 * This function de-initializes a BAM DMA device.
 *
 * @h - BAM handle
 *
 * @return 0 on success, negative value on error
 *
 */
int sps_dma_device_de_init(unsigned long h);

/**
 * Initialize connection mapping module
 *
 * This function initializes the SPS connection mapping module.
 *
 * @map_props - pointer to connection mapping BSP configuration properties
 *
 * @options - driver options bitflags (see SPS_OPT_*)
 *
 * @return 0 on success, negative value on error
 *
 */

int sps_map_init(const struct sps_map *map_props, u32 options);

/**
 * De-initialize connection mapping module
 *
 * This function de-initializes the SPS connection mapping module.
 *
 */
void sps_map_de_init(void);

/*
 * bam_pipe_reset - reset a BAM pipe.
 * @base:	BAM virtual address
 * @pipe:	pipe index
 *
 * This function resets a BAM pipe.
 */
void bam_pipe_reset(void *base, u32 pipe);

/*
 * bam_disable_pipe - disable a BAM pipe.
 * @base:	BAM virtual address
 * @pipe:	pipe index
 *
 * This function disables a BAM pipe.
 */
void bam_disable_pipe(void *base, u32 pipe);
#endif	/* _SPSI_H_ */