summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/include/mach/sdma.h
blob: d864b0680fbd0f439981f995a7521b733a838ed8 (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
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

/*
 * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#ifndef __ASM_ARCH_MXC_SDMA_H__
#define __ASM_ARCH_MXC_SDMA_H__

/*!
 * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver
 */

/*!
 * @file arch-mxc/sdma.h
 *
 * @brief This file contains the SDMA API declarations.
 *
 * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP).
 *
 * @ingroup SDMA
 */

#include <linux/interrupt.h>
#include <asm/dma.h>
#include <stdarg.h>

#include <mach/hardware.h>
#include <mach/dma.h>

/*!
 * This defines maximum DMA address
 */
#define MAX_DMA_ADDRESS 0xffffffff

/*!
 * This defines maximum number of DMA channels
 */
#ifdef CONFIG_MXC_SDMA_API
#define MAX_DMA_CHANNELS 32
#define MAX_BD_NUMBER    16
#define MXC_SDMA_DEFAULT_PRIORITY 1
#define MXC_SDMA_MIN_PRIORITY 1
#define MXC_SDMA_MAX_PRIORITY 7
#else
#define MAX_DMA_CHANNELS 0
#endif

#define MXC_FIFO_MEM_DEST_FIXED   0x1
#define MXC_FIFO_MEM_SRC_FIXED    0x2

#define SDMA_ASRC_INFO_WML_OFF	0
#define SDMA_ASRC_INFO_WML_MASK ((1 << 10) - 1)
#define SDMA_ASRC_INFO_PS	(1 << 10)
#define SDMA_ASRC_INFO_PA	(1 << 11)
#define SDMA_ASRC_INFO_TXFR_DIR	(1 << 14)
#define SDMA_ASRC_INFO_N_OFF	(24)
#define SDMA_ASRC_INFO_N_MASK	((1 << 4) - 1)

#define SDMA_ASRC_P2P_INFO_LWML_OFF 0
#define SDMA_ASRC_P2P_INFO_LWML_MASK ((1 << 8) - 1)
#define SDMA_ASRC_P2P_INFO_PS	(1 << 8)
#define SDMA_ASRC_P2P_INFO_PA	(1 << 9)
#define SDMA_ASRC_P2P_INFO_SPDIF (1 << 10)
#define SDMA_ASRC_P2P_INFO_SP (1 << 11)
#define SDMA_ASRC_P2P_INFO_DP (1 << 12)
#define SDMA_ASRC_P2P_INFO_HWML_OFF 14
#define SDMA_ASRC_P2P_INFO_HWML_MASK ((1 << 10) - 1)
#define SDMA_ASRC_P2P_INFO_LWE (1 << 28)
#define SDMA_ASRC_P2P_INFO_HWE (1 << 29)
#define SDMA_ASRC_P2P_INFO_CONT (1 << 31)

/*!
 * This enumerates  transfer types
 */
typedef enum {
	emi_2_per = 0,		/*!< EMI memory to peripheral */
	emi_2_int,		/*!< EMI memory to internal RAM */
	emi_2_emi,		/*!< EMI memory to EMI memory */
	emi_2_dsp,		/*!< EMI memory to DSP memory */
	per_2_int,		/*!< Peripheral to internal RAM */
	per_2_emi,		/*!< Peripheral to internal EMI memory */
	per_2_dsp,		/*!< Peripheral to DSP memory */
	per_2_per,		/*!< Peripheral to Peripheral */
	int_2_per,		/*!< Internal RAM to peripheral */
	int_2_int,		/*!< Internal RAM to Internal RAM */
	int_2_emi,		/*!< Internal RAM to EMI memory */
	int_2_dsp,		/*!< Internal RAM to DSP memory */
	dsp_2_per,		/*!< DSP memory to peripheral */
	dsp_2_int,		/*!< DSP memory to internal RAM */
	dsp_2_emi,		/*!< DSP memory to EMI memory */
	dsp_2_dsp,		/*!< DSP memory to DSP memory */
	emi_2_dsp_loop,		/*!< EMI memory to DSP memory loopback */
	dsp_2_emi_loop,		/*!< DSP memory to EMI memory loopback */
	dvfs_pll,		/*!< DVFS script with PLL change       */
	dvfs_pdr		/*!< DVFS script without PLL change    */
} sdma_transferT;

/*!
 * This enumerates peripheral types
 */
typedef enum {
	SSI,			/*!< MCU domain SSI */
	SSI_SP,			/*!< Shared SSI */
	MMC,			/*!< MMC */
	SDHC,			/*!< SDHC */
	UART,			/*!< MCU domain UART */
	UART_SP,		/*!< Shared UART */
	FIRI,			/*!< FIRI */
	CSPI,			/*!< MCU domain CSPI */
	CSPI_SP,		/*!< Shared CSPI */
	SIM,			/*!< SIM */
	ATA,			/*!< ATA */
	CCM,			/*!< CCM */
	EXT,			/*!< External peripheral */
	MSHC,			/*!< Memory Stick Host Controller */
	MSHC_SP,		/*!< Shared Memory Stick Host Controller */
	DSP,			/*!< DSP */
	MEMORY,			/*!< Memory */
	FIFO_MEMORY,		/*!< FIFO type Memory */
	SPDIF,			/*!< SPDIF */
	IPU_MEMORY,		/*!< IPU Memory */
	ASRC,			/*!< ASRC */
	ESAI,			/*!< ESAI */
} sdma_periphT;

#ifndef TRANSFER_32BIT
/*!
 * This defines SDMA access data size
 */
#define TRANSFER_32BIT      0x00
#define TRANSFER_8BIT       0x01
#define TRANSFER_16BIT      0x02
#define TRANSFER_24BIT      0x03

#endif

/*!
 * This defines maximum device name length passed during mxc_request_dma().
 */
#define MAX_DEVNAME_LENGTH 32

/*!
 * This defines SDMA interrupt callback function prototype.
 */
typedef void (*dma_callback_t) (void *arg);

/*!
 * Structure containing sdma channel parameters.
 */
typedef struct {
	__u32 watermark_level;	/*!< Lower/upper threshold that
				 *   triggers SDMA event
				 *   for p2p, this is event1 watermark level
				 */
	__u32 per_address;	/*!< Peripheral source/destination
				 *   physical address
				 *   for p2p, this is destination address
				 */
	sdma_periphT peripheral_type;	/*!< Peripheral type */
	sdma_transferT transfer_type;	/*!< Transfer type   */
	int event_id;		/*!< Event number,
				 *   needed by all channels
				 *   that started by peripherals dma
				 *   request (per_2_*,*_2_per)
				 *   Not used for memory and DSP
				 *   transfers.
				 */
	int event_id2;		/*!< Second event number,
				 *   used in ATA scripts only.
				 */
	int bd_number;		/*!< Buffer descriptors number.
				 *   If not set, single buffer
				 *   descriptor will be used.
				 */
	dma_callback_t callback;	/*!   callback function            */
	void *arg;		/*!   callback argument            */
	unsigned long word_size:8;	/*!< SDMA data access word size    */
	unsigned long ext:1;	/*!< 1: extend parameter structure */
} dma_channel_params;

typedef struct {
	dma_channel_params common;
	unsigned long p2p_dir:1;	/*!< 0: per2 to per.
					 * the device of peripheral_type is per.
					 * 1: per to per2
					 * the device of peripheral_type is per2
					 */
	unsigned long info_bits;	/*!< info field in context */
	unsigned long info_mask;	/*!< info field mask in context */
	__u32 watermark_level2;	/*!< event2 threshold that
				 *   triggers SDMA event
				 *   just valid for p2p.
				 */
	__u32 per_address2;	/*!< Peripheral source
				 *   physical address.
				 *   just valid for p2p.
				 */
	struct dma_channel_info info;	/*!< the channel special parameter */
} dma_channel_ext_params;

/*!
 * Structure containing sdma request  parameters.
 */
typedef struct {
	/*!   physical source memory address        */
	__u8 *sourceAddr;
	/*!   physical destination memory address   */
	__u8 *destAddr;
	/*!   amount of data to transfer,
	 * updated during mxc_dma_get_config
	 */
	__u16 count;
	/*!< DONE bit of the buffer descriptor,
	 * updated during mxc_dma_get_config
	 * 0 - means the BD is done and closed by SDMA
	 * 1 - means the BD is still being processed by SDMA
	 */
	int bd_done;
	/*!< CONT bit of the buffer descriptor,
	 * set it if full multi-buffer descriptor mechanism
	 * required.
	 */
	int bd_cont;
	/*!< ERROR bit of the buffer descriptor,
	 * updated during mxc_dma_get_config.
	 * If it is set - there was an error during BD processing.
	 */
	int bd_error;
} dma_request_t;

/*!
 * Structure containing sdma request  parameters.
 */
typedef struct {
	/*! address of ap_2_ap script */
	int mxc_sdma_ap_2_ap_addr;
	/*! address of ap_2_bp script */
	int mxc_sdma_ap_2_bp_addr;
	/*! address of ap_2_ap_fixed script */
	int mxc_sdma_ap_2_ap_fixed_addr;
	/*! address of bp_2_ap script */
	int mxc_sdma_bp_2_ap_addr;
	/*! address of loopback_on_dsp_side script */
	int mxc_sdma_loopback_on_dsp_side_addr;
	/*! address of mcu_interrupt_only script */
	int mxc_sdma_mcu_interrupt_only_addr;

	/*! address of firi_2_per script */
	int mxc_sdma_firi_2_per_addr;
	/*! address of firi_2_mcu script */
	int mxc_sdma_firi_2_mcu_addr;
	/*! address of per_2_firi script */
	int mxc_sdma_per_2_firi_addr;
	/*! address of mcu_2_firi script */
	int mxc_sdma_mcu_2_firi_addr;

	/*! address of uart_2_per script */
	int mxc_sdma_uart_2_per_addr;
	/*! address of uart_2_mcu script */
	int mxc_sdma_uart_2_mcu_addr;
	/*! address of per_2_app script */
	int mxc_sdma_per_2_app_addr;
	/*! address of mcu_2_app script */
	int mxc_sdma_mcu_2_app_addr;
	/*! address of per_2_per script */
	int mxc_sdma_per_2_per_addr;

	/*! address of uartsh_2_per script */
	int mxc_sdma_uartsh_2_per_addr;
	/*! address of uartsh_2_mcu script */
	int mxc_sdma_uartsh_2_mcu_addr;
	/*! address of per_2_shp script */
	int mxc_sdma_per_2_shp_addr;
	/*! address of mcu_2_shp script */
	int mxc_sdma_mcu_2_shp_addr;

	/*! address of ata_2_mcu script */
	int mxc_sdma_ata_2_mcu_addr;
	/*! address of mcu_2_ata script */
	int mxc_sdma_mcu_2_ata_addr;

	/*! address of app_2_per script */
	int mxc_sdma_app_2_per_addr;
	/*! address of app_2_mcu script */
	int mxc_sdma_app_2_mcu_addr;
	/*! address of shp_2_per script */
	int mxc_sdma_shp_2_per_addr;
	/*! address of shp_2_mcu script */
	int mxc_sdma_shp_2_mcu_addr;

	/*! address of mshc_2_mcu script */
	int mxc_sdma_mshc_2_mcu_addr;
	/*! address of mcu_2_mshc script */
	int mxc_sdma_mcu_2_mshc_addr;

	/*! address of spdif_2_mcu script */
	int mxc_sdma_spdif_2_mcu_addr;
	/*! address of mcu_2_spdif script */
	int mxc_sdma_mcu_2_spdif_addr;

	/*! address of asrc_2_mcu script */
	int mxc_sdma_asrc_2_mcu_addr;

	/*! address of ext_mem_2_ipu script */
	int mxc_sdma_ext_mem_2_ipu_addr;

	/*! address of descrambler script */
	int mxc_sdma_descrambler_addr;

	/*! address of dptc_dvfs script */
	int mxc_sdma_dptc_dvfs_addr;

	int mxc_sdma_utra_addr;

	/*! address where ram code starts */
	int mxc_sdma_ram_code_start_addr;
	/*! size of the ram code */
	int mxc_sdma_ram_code_size;
	/*! RAM image address */
	unsigned short *mxc_sdma_start_addr;
} sdma_script_start_addrs;

/*! Structure to store the initialized dma_channel parameters */
typedef struct mxc_sdma_channel_params {
	/*! Channel type (static channel number or dynamic channel) */
	unsigned int channel_num;
	/*! Channel priority [0x1(lowest) - 0x7(highest)] */
	unsigned int chnl_priority;
	/*! Channel params */
	dma_channel_params chnl_params;
} mxc_sdma_channel_params_t;

/*! Structure to store the initialized dma_channel extend parameters */
typedef struct mxc_sdma_channel_ext_params {
	/*! Channel type (static channel number or dynamic channel) */
	unsigned int channel_num;
	/*! Channel priority [0x1(lowest) - 0x7(highest)] */
	unsigned int chnl_priority;
	/*! Channel extend params */
	dma_channel_ext_params chnl_ext_params;
} mxc_sdma_channel_ext_params_t;

/*! Private SDMA data structure */
typedef struct mxc_dma_channel_private {
	/*! ID of the buffer that was processed */
	unsigned int buf_tail;
	/*! Tasklet for the channel */
	struct tasklet_struct chnl_tasklet;
	/*! Flag indicates if interrupt is required after every BD transfer */
	int intr_after_every_bd;
} mxc_dma_channel_private_t;

/*!
 * Setup channel according to parameters.
 * Must be called once after mxc_request_dma()
 *
 * @param   channel           channel number
 * @param   p                 channel parameters pointer
 * @return  0 on success, error code on fail
 */
int mxc_dma_setup_channel(int channel, dma_channel_params * p);

/*!
 * Setup the channel priority. This can be used to change the default priority
 * for the channel.
 *
 * @param   channel           channel number
 * @param   priority          priority to be set for the channel
 *
 * @return  0 on success, error code on failure
 */
int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority);

/*!
 * Allocates dma channel.
 * If channel's value is 0, then the function allocates a free channel
 * dynamically and sets its value to channel.
 * Else allocates requested channel if it is free.
 * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned.
 *
 * @param   channel           pointer to channel number
 * @param   devicename        device name
 * @return  0 on success, error code on fail
 */
int mxc_request_dma(int *channel, const char *devicename);

/*!
 * Configures request parameters. Can be called multiple times after
 * mxc_request_dma() and mxc_dma_setup_channel().
 *
 *
 * @param   channel           channel number
 * @param   p                 request parameters pointer
 * @param   bd_index          index of buffer descriptor to set
 * @return  0 on success, error code on fail
 */
/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */
int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index);

/*!
 * Returns request parameters.
 *
 * @param   channel           channel number
 * @param   p                 request parameters pointer
 * @param   bd_index          index of buffer descriptor to get
 * @return  0 on success, error code on fail
 */
/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */
int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index);

/*!
 * This function is used by MXC IPC's write_ex2. It passes the a pointer to the
 * data control structure to iapi_write_ipcv2()
 *
 * @param channel  SDMA channel number
 * @param ctrl_ptr Data Control structure pointer
 */
int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr);

/*!
 * This function is used by MXC IPC's read_ex2. It passes the a pointer to the
 * data control structure to iapi_read_ipcv2()
 *
 * @param channel   SDMA channel number
 * @param ctrl_ptr  Data Control structure pointer
 */
int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr);

/*!
 * Starts dma channel.
 *
 * @param   channel           channel number
 */
int mxc_dma_start(int channel);

/*!
 * Stops dma channel.
 *
 * @param   channel           channel number
 */
int mxc_dma_stop(int channel);

/*!
 * Frees dma channel.
 *
 * @param   channel           channel number
 */
void mxc_free_dma(int channel);

/*!
 * Sets callback function. Used with standard dma api
 *  for supporting interrupts
 *
 * @param   channel           channel number
 * @param   callback          callback function pointer
 * @param   arg               argument for callback function
 */
void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg);

/*!
 * Allocates uncachable buffer. Uses hash table.
 *
 * @param   size    size of allocated buffer
 * @return  pointer to buffer
 */
void *sdma_malloc(size_t size);

#ifdef CONFIG_SDMA_IRAM
/*!
 * Allocates uncachable buffer from IRAM..
 *
 * @param   size    size of allocated buffer
 * @return  pointer to buffer
 */
void *sdma_iram_malloc(size_t size);
#endif				/*CONFIG_SDMA_IRAM */

/*!
 * Frees uncachable buffer. Uses hash table.
 */
void sdma_free(void *buf);

/*!
 * Converts virtual to physical address. Uses hash table.
 *
 * @param   buf  virtual address pointer
 * @return  physical address value
 */
unsigned long sdma_virt_to_phys(void *buf);

/*!
 * Converts physical to virtual address. Uses hash table.
 *
 * @param   buf  physical address value
 * @return  virtual address pointer
 */
void *sdma_phys_to_virt(unsigned long buf);

/*!
 * Configures the BD_INTR bit on a buffer descriptor parameters.
 *
 *
 * @param   channel           channel number
 * @param   bd_index          index of buffer descriptor to set
 * @param   bd_intr           flag to set or clear the BD_INTR bit
 */
void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr);

/*!
 * Gets the BD_INTR bit on a buffer descriptor.
 *
 *
 * @param   channel           channel number
 * @param   bd_index          index of buffer descriptor to set
 *
 * @return returns the BD_INTR bit status
 */
int mxc_dma_get_bd_intr(int channel, int bd_index);

/*!
 * Stop the current transfer
 *
 * @param   channel           channel number
 * @param   buffer_number     number of buffers (beginning with 0),
 *                            whose done bits should be reset to 0
 */
int mxc_dma_reset(int channel, int buffer_number);

/*!
 * This functions Returns the SDMA paramaters associated for a module
 *
 * @param channel_id the ID of the module requesting DMA
 * @return returns the sdma parameters structure for the device
 */
mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
						       channel_id);

/*!
 * This functions marks the SDMA channels that are statically allocated
 *
 * @param chnl the channel array used to store channel information
 */
void mxc_get_static_channels(mxc_dma_channel_t * chnl);

/*!
 * Initializes SDMA driver
 */
int __init sdma_init(void);

#define DEFAULT_ERR     1

#endif