1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Michael Sevakis
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
26 #include "ccm-imx31.h"
27 #include "avic-imx31.h"
28 #include "sdma_struct.h"
29 #include "sdma-imx31.h"
30 #include "sdma_script_code.h"
31 #include "mmu-imx31.h"
33 /* Most of the code in here is based upon the Linux BSP provided by Freescale
34 * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. */
36 /* Cut down to bare bones essentials */
38 /* Script information that depends on system revision */
39 static struct sdma_script_start_addrs script_info
;
40 /* Mask of channels with callback enabled */
41 static unsigned long sdma_enabled_ints
= 0;
42 /* One channel control block per channel in physically mapped device RAM */
43 static struct channel_control_block ccb_array
[CH_NUM
] NOCACHEBSS_ATTR
;
44 /* Channel 0 (command channel) data */
45 static struct buffer_descriptor_extd c0_buffer_desc NOCACHEBSS_ATTR
;
47 /* All SDMA channel interrupts are handled here.
48 * Dispatches lower channel numbers first (prioritized by SDMA API callers
49 * who specify the desired channel number).
51 static void __attribute__((interrupt("IRQ"))) SDMA_HANDLER(void)
53 unsigned long pending
= SDMA_INTR
;
55 SDMA_INTR
= pending
; /* Ack all ints */
56 pending
&= sdma_enabled_ints
; /* Only dispatch ints with callback */
63 break; /* No bits set */
65 channel
= find_first_set_bit(pending
);
67 pending
&= ~(1ul << channel
);
69 /* Call callback (required if using an interrupt) */
70 ccb_array
[channel
].channel_desc
->callback();
74 /* Initialize script information based upon the system revision */
75 static void init_script_info(void)
77 if (iim_system_rev() == IIM_SREV_1_0
)
79 /* Channel script info */
80 script_info
.app_2_mcu_addr
= app_2_mcu_ADDR_1
;
81 script_info
.ap_2_ap_addr
= ap_2_ap_ADDR_1
;
82 script_info
.ap_2_bp_addr
= -1;
83 script_info
.bp_2_ap_addr
= -1;
84 script_info
.loopback_on_dsp_side_addr
= -1;
85 script_info
.mcu_2_app_addr
= mcu_2_app_ADDR_1
;
86 script_info
.mcu_2_shp_addr
= mcu_2_shp_ADDR_1
;
87 script_info
.mcu_interrupt_only_addr
= -1;
88 script_info
.shp_2_mcu_addr
= shp_2_mcu_ADDR_1
;
89 script_info
.uartsh_2_mcu_addr
= uartsh_2_mcu_ADDR_1
;
90 script_info
.uart_2_mcu_addr
= uart_2_mcu_ADDR_1
;
91 script_info
.dptc_dvfs_addr
= dptc_dvfs_ADDR_1
;
92 script_info
.firi_2_mcu_addr
= firi_2_mcu_ADDR_1
;
93 script_info
.firi_2_per_addr
= -1;
94 script_info
.mshc_2_mcu_addr
= mshc_2_mcu_ADDR_1
;
95 script_info
.per_2_app_addr
= -1;
96 script_info
.per_2_firi_addr
= -1;
97 script_info
.per_2_shp_addr
= -1;
98 script_info
.mcu_2_ata_addr
= mcu_2_ata_ADDR_1
;
99 script_info
.mcu_2_firi_addr
= mcu_2_firi_ADDR_1
;
100 script_info
.mcu_2_mshc_addr
= mcu_2_mshc_ADDR_1
;
101 script_info
.ata_2_mcu_addr
= ata_2_mcu_ADDR_1
;
102 script_info
.uartsh_2_per_addr
= -1;
103 script_info
.shp_2_per_addr
= -1;
104 script_info
.uart_2_per_addr
= -1;
105 script_info
.app_2_per_addr
= -1;
106 /* Main code block info */
107 script_info
.ram_code_size
= RAM_CODE_SIZE_1
;
108 script_info
.ram_code_start_addr
= RAM_CODE_START_ADDR_1
;
109 script_info
.mcu_start_addr
= (unsigned long)sdma_code_1
;
113 /* Channel script info */
114 script_info
.app_2_mcu_addr
= app_2_mcu_patched_ADDR_2
;
115 script_info
.ap_2_ap_addr
= ap_2_ap_ADDR_2
;
116 script_info
.ap_2_bp_addr
= ap_2_bp_ADDR_2
;
117 script_info
.bp_2_ap_addr
= bp_2_ap_ADDR_2
;
118 script_info
.loopback_on_dsp_side_addr
= -1;
119 script_info
.mcu_2_app_addr
= mcu_2_app_patched_ADDR_2
;
120 script_info
.mcu_2_shp_addr
= mcu_2_shp_patched_ADDR_2
;
121 script_info
.mcu_interrupt_only_addr
= -1;
122 script_info
.shp_2_mcu_addr
= shp_2_mcu_patched_ADDR_2
;
123 script_info
.uartsh_2_mcu_addr
= uartsh_2_mcu_patched_ADDR_2
;
124 script_info
.uart_2_mcu_addr
= uart_2_mcu_patched_ADDR_2
;
125 script_info
.dptc_dvfs_addr
= -1;
126 script_info
.firi_2_mcu_addr
= firi_2_mcu_ADDR_2
;
127 script_info
.firi_2_per_addr
= -1;
128 script_info
.mshc_2_mcu_addr
= -1;
129 script_info
.per_2_app_addr
= -1;
130 script_info
.per_2_firi_addr
= -1;
131 script_info
.per_2_shp_addr
= per_2_shp_ADDR_2
;
132 script_info
.mcu_2_ata_addr
= mcu_2_ata_ADDR_2
;
133 script_info
.mcu_2_firi_addr
= mcu_2_firi_ADDR_2
;
134 script_info
.mcu_2_mshc_addr
= -1;
135 script_info
.ata_2_mcu_addr
= ata_2_mcu_ADDR_2
;
136 script_info
.uartsh_2_per_addr
= -1;
137 script_info
.shp_2_per_addr
= shp_2_per_ADDR_2
;
138 script_info
.uart_2_per_addr
= -1;
139 script_info
.app_2_per_addr
= -1;
140 /* Main code block info */
141 script_info
.ram_code_size
= RAM_CODE_SIZE_2
;
142 script_info
.ram_code_start_addr
= RAM_CODE_START_ADDR_2
;
143 script_info
.mcu_start_addr
= (unsigned long)sdma_code_2
;
147 /* Return pc of SDMA script in SDMA halfword space according to peripheral
148 * and transfer type */
149 static unsigned long get_script_pc(unsigned int peripheral_type
,
150 unsigned int transfer_type
)
152 unsigned long res
= (unsigned short)-1;
154 switch (peripheral_type
)
156 case SDMA_PER_MEMORY
:
157 switch (transfer_type
)
159 case SDMA_TRAN_EMI_2_INT
:
160 case SDMA_TRAN_EMI_2_EMI
:
161 case SDMA_TRAN_INT_2_EMI
:
162 res
= script_info
.ap_2_ap_addr
;
167 #if 0 /* Not using this */
169 switch (transfer_type
)
171 case SDMA_TRAN_EMI_2_DSP
:
172 res
= script_info
.ap_2_bp_addr
;
174 case SDMA_TRAN_DSP_2_EMI
:
175 res
= script_info
.bp_2_ap_addr
;
177 case SDMA_TRAN_DSP_2_EMI_LOOP
:
178 res
= script_info
.loopback_on_dsp_side_addr
;
180 case SDMA_TRAN_EMI_2_DSP_LOOP
:
181 res
= script_info
.mcu_interrupt_only_addr
;
187 #if 0 /* Not using this */
189 switch (transfer_type
)
191 case SDMA_TRAN_PER_2_INT
:
192 res
= script_info
.firi_2_per_addr
;
194 case SDMA_TRAN_PER_2_EMI
:
195 res
= script_info
.firi_2_mcu_addr
;
197 case SDMA_TRAN_INT_2_PER
:
198 res
= script_info
.per_2_firi_addr
;
200 case SDMA_TRAN_EMI_2_PER
:
201 res
= script_info
.mcu_2_firi_addr
;
207 #if 0 /* Not using this */
209 switch (transfer_type
)
211 case SDMA_TRAN_PER_2_INT
:
212 res
= script_info
.uart_2_per_addr
;
214 case SDMA_TRAN_PER_2_EMI
:
215 res
= script_info
.uart_2_mcu_addr
;
217 case SDMA_TRAN_INT_2_PER
:
218 res
= script_info
.per_2_app_addr
;
220 case SDMA_TRAN_EMI_2_PER
:
221 res
= script_info
.mcu_2_app_addr
;
227 #if 0 /* Not using this */
228 case SDMA_PER_UART_SHP
:
229 switch (transfer_type
)
231 case SDMA_TRAN_PER_2_INT
:
232 res
= script_info
.uartsh_2_per_addr
;
234 case SDMA_TRAN_PER_2_EMI
:
235 res
= script_info
.uartsh_2_mcu_addr
;
237 case SDMA_TRAN_INT_2_PER
:
238 res
= script_info
.per_2_shp_addr
;
240 case SDMA_TRAN_EMI_2_PER
:
241 res
= script_info
.mcu_2_shp_addr
;
248 switch (transfer_type
)
250 case SDMA_TRAN_PER_2_EMI
:
251 res
= script_info
.ata_2_mcu_addr
;
253 case SDMA_TRAN_EMI_2_PER
:
254 res
= script_info
.mcu_2_ata_addr
;
262 switch (transfer_type
)
264 case SDMA_TRAN_PER_2_INT
:
265 res
= script_info
.app_2_per_addr
;
267 case SDMA_TRAN_PER_2_EMI
:
268 res
= script_info
.app_2_mcu_addr
;
270 case SDMA_TRAN_INT_2_PER
:
271 res
= script_info
.per_2_app_addr
;
273 case SDMA_TRAN_EMI_2_PER
:
274 res
= script_info
.mcu_2_app_addr
;
279 #if 0 /* Not using this */
283 case SDMA_PER_SSI_SHP
:
284 case SDMA_PER_CSPI_SHP
:
285 switch (transfer_type
)
287 case SDMA_TRAN_PER_2_INT
:
288 res
= script_info
.shp_2_per_addr
;
290 case SDMA_TRAN_PER_2_EMI
:
291 res
= script_info
.shp_2_mcu_addr
;
293 case SDMA_TRAN_INT_2_PER
:
294 res
= script_info
.per_2_shp_addr
;
296 case SDMA_TRAN_EMI_2_PER
:
297 res
= script_info
.mcu_2_shp_addr
;
303 switch (transfer_type
)
305 case SDMA_TRAN_PER_2_EMI
:
306 res
= script_info
.mshc_2_mcu_addr
;
308 case SDMA_TRAN_EMI_2_PER
:
309 res
= script_info
.mcu_2_mshc_addr
;
315 switch (transfer_type
)
317 case SDMA_TRAN_PER_2_EMI
:
318 res
= script_info
.dptc_dvfs_addr
;
324 if (res
== (unsigned short)-1)
326 logf("SDMA script not found\n");
332 static unsigned int get_config(unsigned int transfer_type
)
334 unsigned int res
= -1;
336 switch (transfer_type
)
338 case SDMA_TRAN_PER_2_INT
:
339 case SDMA_TRAN_PER_2_EMI
:
340 case SDMA_TRAN_INT_2_PER
:
341 case SDMA_TRAN_EMI_2_PER
:
343 * Peripheral <------> Memory
344 * evtOvr = 0 mcuOvr = 0 dspOvr = 1
346 res
= CH_OWNSHP_MCU
| CH_OWNSHP_EVT
;
349 #if 0 /* Not using this */
350 case SDMA_TRAN_DSP_2_PER
:
353 case SDMA_TRAN_EMI_2_DSP
:
354 case SDMA_TRAN_INT_2_DSP
:
355 case SDMA_TRAN_DSP_2_INT
:
356 case SDMA_TRAN_DSP_2_EMI
:
357 case SDMA_TRAN_DSP_2_DSP
:
359 * DSP <-----------> Memory
360 * evtOvr = 1 mcuOvr = 0 dspOvr = 0
362 res
= CH_OWNSHP_MCU
| CH_OWNSHP_DSP
;
366 case SDMA_TRAN_EMI_2_INT
:
367 case SDMA_TRAN_EMI_2_EMI
:
368 case SDMA_TRAN_INT_2_INT
:
369 case SDMA_TRAN_INT_2_EMI
:
370 #if 0 /* Not using this */
371 case SDMA_TRAN_DSP_2_EMI_LOOP
:
372 case SDMA_TRAN_EMI_2_DSP_LOOP
:
374 /* evtOvr = 1 mcuOvr = 0 dspOvr = 1 */
378 #if 0 /* Not using this */
379 case SDMA_TRAN_PER_2_DSP
:
380 /* evtOvr = 0 mcuOvr = 1 dspOvr = 0 */
381 res
= CH_OWNSHP_DSP
| CH_OWNSHP_EVT
;
392 /* Fill the buffer descriptor with the values given in parameter.
393 * Expects physical addresses. */
394 static inline void set_buffer_descriptor(
395 struct buffer_descriptor
*bd_p
,
396 unsigned int command
, /* C0_* command or transfer size */
397 unsigned int status
, /* BD_* flags */
398 unsigned int count
, /* Size of buffer to transfer */
399 void *buf_addr
, /* Buffer to transfer */
402 bd_p
->mode
.command
= command
;
403 bd_p
->mode
.status
= status
;
404 bd_p
->mode
.count
= count
;
405 bd_p
->buf_addr
= buf_addr
;
406 if (status
& BD_EXTD
)
407 ((struct buffer_descriptor_extd
*)bd_p
)->buf_addr_ext
= buf_addr_ext
;
410 /* Configure channel ownership */
411 static void set_channel_ownership(unsigned int channel
, unsigned int config
)
413 unsigned long bit
= 1ul << channel
;
416 #if 0 /* Not using this */
417 imx31_regmod32(&SDMA_DSPOVR
, (config
& CH_OWNSHP_DSP
) ? 0 : bit
, bit
);
420 imx31_regmod32(&SDMA_EVTOVR
, (config
& CH_OWNSHP_EVT
) ? 0 : bit
, bit
);
422 imx31_regmod32(&SDMA_HOSTOVR
, (config
& CH_OWNSHP_MCU
) ? 0 : bit
, bit
);
425 static bool setup_channel(struct channel_control_block
*ccb_p
)
427 struct context_data context_buffer
;
428 struct channel_descriptor
*cd_p
;
429 unsigned int channel_cfg
;
430 unsigned int channel
;
433 memset(&context_buffer
, 0x00, sizeof (context_buffer
));
435 channel
= ccb_p
- ccb_array
;
436 cd_p
= ccb_p
->channel_desc
;
438 /* Obtain script start address for perihperal and transfer type */
439 pc
= get_script_pc(cd_p
->per_type
, cd_p
->tran_type
);
441 if (pc
== (unsigned short)-1)
442 return false; /* Failed to find a script */
444 context_buffer
.channel_state
.pc
= pc
;
446 if (cd_p
->per_type
!= SDMA_PER_MEMORY
&& cd_p
->per_type
!= SDMA_PER_DSP
)
448 /* Set peripheral DMA request mask for this channel */
449 context_buffer
.event_mask1
= 1ul << cd_p
->event_id1
;
451 if (cd_p
->per_type
== SDMA_PER_ATA
)
454 context_buffer
.event_mask2
= 1ul << cd_p
->event_id2
;
457 context_buffer
.shp_addr
= cd_p
->shp_addr
;
458 context_buffer
.wml
= cd_p
->wml
;
462 context_buffer
.wml
= SDMA_PER_ADDR_SDRAM
;
465 /* Send channel context to SDMA core */
466 clean_dcache_range(&context_buffer
, sizeof (context_buffer
));
467 sdma_write_words((unsigned long *)&context_buffer
,
468 CHANNEL_CONTEXT_ADDR(channel
),
469 sizeof (context_buffer
)/4);
471 ccb_p
->status
.error
= 0; /* Clear channel-wide error flag */
473 if (cd_p
->is_setup
!= 0)
474 return true; /* No more to do */
476 /* Obtain channel ownership configuration */
477 channel_cfg
= get_config(cd_p
->tran_type
);
479 if (channel_cfg
== (unsigned int)-1)
482 /* Set who owns it and thus can activate it */
483 set_channel_ownership(channel
, channel_cfg
);
485 if (channel_cfg
& CH_OWNSHP_EVT
)
487 /* Set event ID to channel activation bitmapping */
488 imx31_regset32(&SDMA_CHNENBL(cd_p
->event_id1
), 1ul << channel
);
490 if (cd_p
->per_type
== SDMA_PER_ATA
)
493 imx31_regset32(&SDMA_CHNENBL(cd_p
->event_id2
), 1ul << channel
);
502 /** Public routines **/
503 void INIT_ATTR
sdma_init(void)
508 ccm_module_clock_gating(CG_SDMA
, CGM_ON_RUN_WAIT
);
510 /* Reset the controller */
511 SDMA_RESET
|= SDMA_RESET_RESET
;
512 while (SDMA_RESET
& SDMA_RESET_RESET
);
516 /* No channel enabled, all priorities 0 */
517 for (i
= 0; i
< CH_NUM
; i
++)
523 /* Ensure no ints pending */
524 SDMA_INTR
= 0xffffffff;
526 /* Nobody owns any channel (yet) */
527 SDMA_HOSTOVR
= 0xffffffff;
528 SDMA_DSPOVR
= 0xffffffff;
529 SDMA_EVTOVR
= 0xffffffff;
531 SDMA_MC0PTR
= 0x00000000;
533 /* 32-word channel contexts, use default bootscript address */
534 SDMA_CHN0ADDR
= SDMA_CHN0ADDR_SMSZ
| 0x0050;
536 avic_enable_int(INT_SDMA
, INT_TYPE_IRQ
, INT_PRIO_SDMA
, SDMA_HANDLER
);
538 /* SDMA core must run at the proper frequency based upon the AHB/IPG
540 acr
= (ccm_get_ahb_clk() / ccm_get_ipg_clk()) < 2 ? SDMA_CONFIG_ACR
: 0;
543 * Static context switching - TLSbo86520L SW Workaround for SDMA Chnl0
547 /* Tell SDMA where the host channel table is */
548 SDMA_MC0PTR
= (unsigned long)ccb_array
;
550 ccb_array
[0].status
.opened_init
= 1;
551 ccb_array
[0].curr_bd_ptr
= &c0_buffer_desc
.bd
;
552 ccb_array
[0].base_bd_ptr
= &c0_buffer_desc
.bd
;
553 ccb_array
[0].channel_desc
= NULL
; /* No channel descriptor */
555 /* Command channel owned by AP */
556 set_channel_ownership(0, CH_OWNSHP_MCU
);
558 sdma_channel_set_priority(0, 1);
560 /* Load SDMA script code */
561 set_buffer_descriptor(&c0_buffer_desc
.bd
,
563 BD_DONE
| BD_WRAP
| BD_EXTD
,
564 script_info
.ram_code_size
,
565 (void *)addr_virt_to_phys(script_info
.mcu_start_addr
),
566 (void *)(unsigned long)script_info
.ram_code_start_addr
);
569 sdma_channel_wait_nonblocking(0);
571 /* No dsp, no debug, dynamic context switching */
572 SDMA_CONFIG
= acr
| SDMA_CONFIG_CSM_DYNAMIC
;
575 /* Busy wait for a channel to complete */
576 void sdma_channel_wait_nonblocking(unsigned int channel
)
580 if (channel
>= CH_NUM
)
583 if (ccb_array
[channel
].status
.opened_init
== 0)
586 mask
= 1ul << channel
;
587 while (SDMA_STOP_STAT
& mask
);
590 /* Set a new channel priority */
591 void sdma_channel_set_priority(unsigned int channel
, unsigned int priority
)
593 if (channel
>= CH_NUM
|| priority
> MAX_CH_PRIORITY
)
596 if (ccb_array
[channel
].status
.opened_init
== 0)
599 SDMA_CHNPRI(channel
) = priority
;
602 /* Resets a channel to start of script next time it runs. */
603 bool sdma_channel_reset(unsigned int channel
)
605 struct channel_control_block
*ccb_p
;
607 if (channel
== 0 || channel
>= CH_NUM
)
610 ccb_p
= &ccb_array
[channel
];
612 if (ccb_p
->status
.opened_init
== 0)
615 if (!setup_channel(ccb_p
))
621 /* Resume or start execution on a channel */
622 void sdma_channel_run(unsigned int channel
)
624 if (channel
== 0 || channel
>= CH_NUM
)
627 if (ccb_array
[channel
].status
.opened_init
== 0)
630 SDMA_HSTART
= 1ul << channel
;
633 /* Pause a running channel - can be resumed */
634 void sdma_channel_pause(unsigned int channel
)
636 if (channel
== 0 || channel
>= CH_NUM
)
639 if (ccb_array
[channel
].status
.opened_init
== 0)
642 SDMA_STOP_STAT
= 1ul << channel
;
645 /* Stop a channel from executing - cannot be resumed */
646 void sdma_channel_stop(unsigned int channel
)
648 struct channel_control_block
*ccb_p
;
650 unsigned long intmsk
;
654 if (channel
== 0 || channel
>= CH_NUM
)
657 ccb_p
= &ccb_array
[channel
];
659 if (ccb_p
->status
.opened_init
== 0)
662 chmsk
= 1ul << channel
;
665 oldstatus
= disable_irq_save();
666 intmsk
= sdma_enabled_ints
;
667 sdma_enabled_ints
&= ~chmsk
;
668 restore_irq(oldstatus
);
671 for (i
= ccb_p
->channel_desc
->bd_count
- 1; i
>= 0; i
--)
672 ccb_p
->base_bd_ptr
[i
].mode
.status
&= ~BD_DONE
;
674 SDMA_STOP_STAT
= chmsk
;
675 while (SDMA_STOP_STAT
& chmsk
);
677 /* Unlock callback if it was set */
679 imx31_regset32(&sdma_enabled_ints
, chmsk
);
681 logf("SDMA ch closed: %d", channel
);
684 bool sdma_channel_init(unsigned int channel
,
685 struct channel_descriptor
*cd_p
,
686 struct buffer_descriptor
*base_bd_p
)
688 struct channel_control_block
*ccb_p
;
690 if (channel
== 0 || channel
>= CH_NUM
||
691 cd_p
== NULL
|| base_bd_p
== NULL
)
694 ccb_p
= &ccb_array
[channel
];
696 /* If initialized already, should close first then init. */
697 if (ccb_p
->status
.opened_init
!= 0)
700 /* Initialize channel control block. */
701 ccb_p
->curr_bd_ptr
= base_bd_p
;
702 ccb_p
->base_bd_ptr
= base_bd_p
;
703 ccb_p
->channel_desc
= cd_p
;
704 ccb_p
->status
.error
= 0;
705 ccb_p
->status
.opened_init
= 1;
706 ccb_p
->status
.state_direction
= 0;
707 ccb_p
->status
.execute
= 0;
709 /* Finish any channel descriptor inits. */
710 cd_p
->ccb_ptr
= ccb_p
;
713 /* Do an initial setup now. */
714 if (!setup_channel(ccb_p
))
716 logf("SDMA ch init failed: %d", channel
);
717 cd_p
->ccb_ptr
= NULL
;
718 memset(ccb_p
, 0x00, sizeof (struct channel_control_block
));
722 /* Enable interrupt if a callback is specified. */
723 if (cd_p
->callback
!= NULL
)
724 imx31_regset32(&sdma_enabled_ints
, 1ul << channel
);
726 /* Minimum schedulable = 1 */
727 sdma_channel_set_priority(channel
, 1);
729 logf("SDMA ch initialized: %d", channel
);
733 void sdma_channel_close(unsigned int channel
)
735 struct channel_control_block
*ccb_p
;
738 if (channel
== 0 || channel
>= CH_NUM
)
741 ccb_p
= &ccb_array
[channel
];
743 /* Block callbacks (if not initialized, it won't be set). */
744 imx31_regclr32(&sdma_enabled_ints
, 1ul << channel
);
746 if (ccb_p
->status
.opened_init
== 0)
749 /* Stop the channel if running */
750 for (i
= ccb_p
->channel_desc
->bd_count
- 1; i
>= 0; i
--)
751 ccb_p
->base_bd_ptr
[i
].mode
.status
&= ~BD_DONE
;
753 sdma_channel_stop(channel
);
756 set_channel_ownership(channel
, 0);
758 /* Cannot schedule it again */
759 sdma_channel_set_priority(channel
, 0);
761 /* Reset channel control block entry */
762 memset(ccb_p
, 0x00, sizeof (struct channel_control_block
));
765 /* Check channel-wide error flag */
766 bool sdma_channel_is_error(unsigned int channel
)
768 return channel
< CH_NUM
&& ccb_array
[channel
].status
.error
;
771 /* Write 32-bit words to SDMA core memory. Host endian->SDMA endian. */
772 void sdma_write_words(const unsigned long *buf
, unsigned long start
, int count
)
774 /* Setup buffer descriptor with channel 0 command */
775 set_buffer_descriptor(&c0_buffer_desc
.bd
,
777 BD_DONE
| BD_WRAP
| BD_EXTD
,
779 (void *)addr_virt_to_phys((unsigned long)buf
),
783 sdma_channel_wait_nonblocking(0);
786 /* Read 32-bit words from SDMA core memory. SDMA endian->host endian. */
787 void sdma_read_words(unsigned long *buf
, unsigned long start
, int count
)
789 /* Setup buffer descriptor with channel 0 command */
790 set_buffer_descriptor(&c0_buffer_desc
.bd
,
792 BD_DONE
| BD_WRAP
| BD_EXTD
,
794 (void *)addr_virt_to_phys((unsigned long)buf
),
798 sdma_channel_wait_nonblocking(0);