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 "clkctl-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
] DEVBSS_ATTR
;
44 /* Channel 0 (command channel) data */
45 static struct buffer_descriptor_extd c0_buffer_desc DEVBSS_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_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
;
169 #if 0 /* Not using this */
171 switch (transfer_type
)
173 case SDMA_TRAN_EMI_2_DSP
:
174 res
= script_info
.ap_2_bp_addr
;
176 case SDMA_TRAN_DSP_2_EMI
:
177 res
= script_info
.bp_2_ap_addr
;
179 case SDMA_TRAN_DSP_2_EMI_LOOP
:
180 res
= script_info
.loopback_on_dsp_side_addr
;
182 case SDMA_TRAN_EMI_2_DSP_LOOP
:
183 res
= script_info
.mcu_interrupt_only_addr
;
191 #if 0 /* Not using this */
193 switch (transfer_type
)
195 case SDMA_TRAN_PER_2_INT
:
196 res
= script_info
.firi_2_per_addr
;
198 case SDMA_TRAN_PER_2_EMI
:
199 res
= script_info
.firi_2_mcu_addr
;
201 case SDMA_TRAN_INT_2_PER
:
202 res
= script_info
.per_2_firi_addr
;
204 case SDMA_TRAN_EMI_2_PER
:
205 res
= script_info
.mcu_2_firi_addr
;
213 #if 0 /* Not using this */
215 switch (transfer_type
)
217 case SDMA_TRAN_PER_2_INT
:
218 res
= script_info
.uart_2_per_addr
;
220 case SDMA_TRAN_PER_2_EMI
:
221 res
= script_info
.uart_2_mcu_addr
;
223 case SDMA_TRAN_INT_2_PER
:
224 res
= script_info
.per_2_app_addr
;
226 case SDMA_TRAN_EMI_2_PER
:
227 res
= script_info
.mcu_2_app_addr
;
235 #if 0 /* Not using this */
236 case SDMA_PER_UART_SP
:
237 switch (transfer_type
)
239 case SDMA_TRAN_PER_2_INT
:
240 res
= script_info
.uartsh_2_per_addr
;
242 case SDMA_TRAN_PER_2_EMI
:
243 res
= script_info
.uartsh_2_mcu_addr
;
245 case SDMA_TRAN_INT_2_PER
:
246 res
= script_info
.per_2_shp_addr
;
248 case SDMA_TRAN_EMI_2_PER
:
249 res
= script_info
.mcu_2_shp_addr
;
258 switch (transfer_type
)
260 case SDMA_TRAN_PER_2_EMI
:
261 res
= script_info
.ata_2_mcu_addr
;
263 case SDMA_TRAN_EMI_2_PER
:
264 res
= script_info
.mcu_2_ata_addr
;
274 switch (transfer_type
)
276 case SDMA_TRAN_PER_2_INT
:
277 res
= script_info
.app_2_per_addr
;
279 case SDMA_TRAN_PER_2_EMI
:
280 res
= script_info
.app_2_mcu_addr
;
282 case SDMA_TRAN_INT_2_PER
:
283 res
= script_info
.per_2_app_addr
;
285 case SDMA_TRAN_EMI_2_PER
:
286 res
= script_info
.mcu_2_app_addr
;
293 #if 0 /* Not using this */
297 case SDMA_PER_SSI_SP
:
298 case SDMA_PER_CSPI_SP
:
299 switch (transfer_type
)
301 case SDMA_TRAN_PER_2_INT
:
302 res
= script_info
.shp_2_per_addr
;
304 case SDMA_TRAN_PER_2_EMI
:
305 res
= script_info
.shp_2_mcu_addr
;
307 case SDMA_TRAN_INT_2_PER
:
308 res
= script_info
.per_2_shp_addr
;
310 case SDMA_TRAN_EMI_2_PER
:
311 res
= script_info
.mcu_2_shp_addr
;
318 switch (transfer_type
)
320 case SDMA_TRAN_PER_2_EMI
:
321 res
= script_info
.mshc_2_mcu_addr
;
323 case SDMA_TRAN_EMI_2_PER
:
324 res
= script_info
.mcu_2_mshc_addr
;
331 switch (transfer_type
)
333 case SDMA_TRAN_PER_2_EMI
:
334 res
= script_info
.dptc_dvfs_addr
;
341 if (res
== (unsigned short)-1)
343 logf("SDMA script not found\n");
349 static unsigned int get_config(unsigned int transfer_type
)
351 unsigned int res
= -1;
353 switch (transfer_type
)
355 case SDMA_TRAN_PER_2_INT
:
356 case SDMA_TRAN_PER_2_EMI
:
357 case SDMA_TRAN_INT_2_PER
:
358 case SDMA_TRAN_EMI_2_PER
:
360 * Peripheral <------> Memory
361 * evtOvr = 0 mcuOvr = 0 dspOvr = 1
363 res
= CH_OWNSHP_MCU
| CH_OWNSHP_EVT
;
366 #if 0 /* Not using this */
367 case SDMA_TRAN_DSP_2_PER
:
370 case SDMA_TRAN_EMI_2_DSP
:
371 case SDMA_TRAN_INT_2_DSP
:
372 case SDMA_TRAN_DSP_2_INT
:
373 case SDMA_TRAN_DSP_2_EMI
:
374 case SDMA_TRAN_DSP_2_DSP
:
376 * DSP <-----------> Memory
377 * evtOvr = 1 mcuOvr = 0 dspOvr = 0
379 res
= CH_OWNSHP_MCU
| CH_OWNSHP_DSP
;
383 case SDMA_TRAN_EMI_2_INT
:
384 case SDMA_TRAN_EMI_2_EMI
:
385 case SDMA_TRAN_INT_2_INT
:
386 case SDMA_TRAN_INT_2_EMI
:
387 #if 0 /* Not using this */
388 case SDMA_TRAN_DSP_2_EMI_LOOP
:
389 case SDMA_TRAN_EMI_2_DSP_LOOP
:
391 /* evtOvr = 1 mcuOvr = 0 dspOvr = 1 */
395 #if 0 /* Not using this */
396 case SDMA_TRAN_PER_2_DSP
:
397 /* evtOvr = 0 mcuOvr = 1 dspOvr = 0 */
398 res
= CH_OWNSHP_DSP
| CH_OWNSHP_EVT
;
409 /* Fill the buffer descriptor with the values given in parameter.
410 * Expects physical addresses. */
411 static inline void set_buffer_descriptor(
412 struct buffer_descriptor
*bd_p
,
413 unsigned int command
, /* C0_* command or transfer size */
414 unsigned int status
, /* BD_* flags */
415 unsigned int count
, /* Size of buffer to transfer */
416 void *buf_addr
, /* Buffer to transfer */
419 bd_p
->mode
.command
= command
;
420 bd_p
->mode
.status
= status
;
421 bd_p
->mode
.count
= count
;
422 bd_p
->buf_addr
= buf_addr
;
423 if (status
& BD_EXTD
)
424 ((struct buffer_descriptor_extd
*)bd_p
)->buf_addr_ext
= buf_addr_ext
;
427 /* Configure channel ownership */
428 static void set_channel_ownership(unsigned int channel
, unsigned int config
)
430 unsigned long bit
= 1ul << channel
;
433 #if 0 /* Not using this */
434 imx31_regmod32(&SDMA_DSPOVR
, (config
& CH_OWNSHP_DSP
) ? 0 : bit
, bit
);
437 imx31_regmod32(&SDMA_EVTOVR
, (config
& CH_OWNSHP_EVT
) ? 0 : bit
, bit
);
439 imx31_regmod32(&SDMA_HOSTOVR
, (config
& CH_OWNSHP_MCU
) ? 0 : bit
, bit
);
442 static bool setup_channel(struct channel_control_block
*ccb_p
)
444 struct context_data context_buffer
;
445 struct channel_descriptor
*cd_p
;
446 unsigned int channel_cfg
;
447 unsigned int channel
;
450 memset(&context_buffer
, 0x00, sizeof (context_buffer
));
452 channel
= ccb_p
- ccb_array
;
453 cd_p
= ccb_p
->channel_desc
;
455 /* Obtain script start address for perihperal and transfer type */
456 pc
= get_script_pc(cd_p
->per_type
, cd_p
->tran_type
);
458 if (pc
== (unsigned short)-1)
459 return false; /* Failed to find a script */
461 context_buffer
.channel_state
.pc
= pc
;
463 if (cd_p
->per_type
!= SDMA_PER_MEMORY
&& cd_p
->per_type
!= SDMA_PER_DSP
)
465 /* Set peripheral DMA request mask for this channel */
466 context_buffer
.event_mask1
= 1ul << cd_p
->event_id1
;
468 if (cd_p
->per_type
== SDMA_PER_ATA
)
471 context_buffer
.event_mask2
= 1ul << cd_p
->event_id2
;
474 context_buffer
.shp_addr
= cd_p
->shp_addr
;
475 context_buffer
.wml
= cd_p
->wml
;
479 context_buffer
.wml
= SDMA_PER_ADDR_SDRAM
;
482 /* Send channel context to SDMA core */
483 clean_dcache_range(&context_buffer
, sizeof (context_buffer
));
484 sdma_write_words((unsigned long *)&context_buffer
,
485 CHANNEL_CONTEXT_ADDR(channel
),
486 sizeof (context_buffer
)/4);
488 if (cd_p
->is_setup
!= 0)
489 return true; /* No more to do */
491 /* Obtain channel ownership configuration */
492 channel_cfg
= get_config(cd_p
->tran_type
);
494 if (channel_cfg
== (unsigned int)-1)
497 /* Set who owns it and thus can activate it */
498 set_channel_ownership(channel
, channel_cfg
);
500 if (channel_cfg
& CH_OWNSHP_EVT
)
502 /* Set event ID to channel activation bitmapping */
503 imx31_regset32(&SDMA_CHNENBL(cd_p
->event_id1
), 1ul << channel
);
505 if (cd_p
->per_type
== SDMA_PER_ATA
)
508 imx31_regset32(&SDMA_CHNENBL(cd_p
->event_id2
), 1ul << channel
);
517 /** Public routines **/
520 imx31_clkctl_module_clock_gating(CG_SDMA
, CGM_ON_RUN_WAIT
);
524 /* Reset the controller */
525 SDMA_RESET
|= SDMA_RESET_RESET
;
526 while (SDMA_RESET
& SDMA_RESET_RESET
);
530 /* No channel enabled, all priorities 0 */
531 for (i
= 0; i
< CH_NUM
; i
++)
537 /* Ensure no ints pending */
538 SDMA_INTR
= 0xffffffff;
540 /* Nobody owns any channel (yet) */
541 SDMA_HOSTOVR
= 0xffffffff;
542 SDMA_DSPOVR
= 0xffffffff;
543 SDMA_EVTOVR
= 0xffffffff;
545 SDMA_MC0PTR
= 0x00000000;
547 /* 32-word channel contexts, use default bootscript address */
548 SDMA_CHN0ADDR
= SDMA_CHN0ADDR_SMSZ
| 0x0050;
550 avic_enable_int(SDMA
, IRQ
, 8, SDMA_HANDLER
);
552 /* SDMA core must run at the proper frequency based upon the AHB/IPG ratio */
553 acr
= (imx31_clkctl_get_ahb_clk() / imx31_clkctl_get_ipg_clk()) < 2 ?
557 * Static context switching - TLSbo86520L SW Workaround for SDMA Chnl0
561 /* Tell SDMA where the host channel table is */
562 SDMA_MC0PTR
= (unsigned long)ccb_array
;
564 ccb_array
[0].status
.opened_init
= 1;
565 ccb_array
[0].curr_bd_ptr
= &c0_buffer_desc
.bd
;
566 ccb_array
[0].base_bd_ptr
= &c0_buffer_desc
.bd
;
567 ccb_array
[0].channel_desc
= NULL
; /* No channel descriptor */
569 /* Command channel owned by AP */
570 set_channel_ownership(0, CH_OWNSHP_MCU
);
572 sdma_channel_set_priority(0, 1);
574 /* Load SDMA script code */
575 set_buffer_descriptor(&c0_buffer_desc
.bd
,
577 BD_DONE
| BD_WRAP
| BD_EXTD
,
578 script_info
.ram_code_size
,
579 (void *)addr_virt_to_phys(script_info
.mcu_start_addr
),
580 (void *)(unsigned long)script_info
.ram_code_start_addr
);
583 sdma_channel_wait_nonblocking(0);
585 /* No dsp, no debug, dynamic context switching */
586 SDMA_CONFIG
= acr
| SDMA_CONFIG_CSM_DYNAMIC
;
589 /* Busy wait for a channel to complete */
590 void sdma_channel_wait_nonblocking(unsigned int channel
)
594 if (channel
>= CH_NUM
)
597 if (ccb_array
[channel
].status
.opened_init
== 0)
600 mask
= 1ul << channel
;
601 while (SDMA_STOP_STAT
& mask
);
604 /* Set a new channel priority */
605 void sdma_channel_set_priority(unsigned int channel
, unsigned int priority
)
607 if (channel
>= CH_NUM
|| priority
> MAX_CH_PRIORITY
)
610 if (ccb_array
[channel
].status
.opened_init
== 0)
613 SDMA_CHNPRI(channel
) = priority
;
616 /* Resets a channel to start of script next time it runs. */
617 bool sdma_channel_reset(unsigned int channel
)
619 struct channel_control_block
*ccb_p
;
621 if (channel
== 0 || channel
>= CH_NUM
)
624 ccb_p
= &ccb_array
[channel
];
626 if (ccb_p
->status
.opened_init
== 0)
629 if (!setup_channel(ccb_p
))
635 /* Resume or start execution on a channel */
636 void sdma_channel_run(unsigned int channel
)
638 if (channel
== 0 || channel
>= CH_NUM
)
641 if (ccb_array
[channel
].status
.opened_init
== 0)
644 SDMA_HSTART
= 1ul << channel
;
647 /* Pause a running channel - can be resumed */
648 void sdma_channel_pause(unsigned int channel
)
650 if (channel
== 0 || channel
>= CH_NUM
)
653 if (ccb_array
[channel
].status
.opened_init
== 0)
656 SDMA_STOP_STAT
= 1ul << channel
;
659 /* Stop a channel from executing - cannot be resumed */
660 void sdma_channel_stop(unsigned int channel
)
662 struct channel_control_block
*ccb_p
;
664 unsigned long intmsk
;
668 if (channel
== 0 || channel
>= CH_NUM
)
671 ccb_p
= &ccb_array
[channel
];
673 if (ccb_p
->status
.opened_init
== 0)
676 chmsk
= 1ul << channel
;
679 oldstatus
= disable_irq_save();
680 intmsk
= sdma_enabled_ints
;
681 sdma_enabled_ints
&= ~chmsk
;
682 restore_irq(oldstatus
);
685 for (i
= ccb_p
->channel_desc
->bd_count
- 1; i
>= 0; i
--)
686 ccb_p
->base_bd_ptr
[i
].mode
.status
&= ~BD_DONE
;
688 SDMA_STOP_STAT
= chmsk
;
689 while (SDMA_STOP_STAT
& chmsk
);
691 /* Unlock callback if it was set */
693 imx31_regset32(&sdma_enabled_ints
, chmsk
);
695 logf("SDMA ch closed: %d", channel
);
698 bool sdma_channel_init(unsigned int channel
,
699 struct channel_descriptor
*cd_p
,
700 struct buffer_descriptor
*base_bd_p
)
702 struct channel_control_block
*ccb_p
;
704 if (channel
== 0 || channel
>= CH_NUM
||
705 cd_p
== NULL
|| base_bd_p
== NULL
)
708 ccb_p
= &ccb_array
[channel
];
710 /* If initialized already, should close first then init. */
711 if (ccb_p
->status
.opened_init
!= 0)
714 /* Initialize channel control block. */
715 ccb_p
->curr_bd_ptr
= base_bd_p
;
716 ccb_p
->base_bd_ptr
= base_bd_p
;
717 ccb_p
->channel_desc
= cd_p
;
718 ccb_p
->status
.error
= 0;
719 ccb_p
->status
.opened_init
= 1;
720 ccb_p
->status
.state_direction
= 0;
721 ccb_p
->status
.execute
= 0;
723 /* Finish any channel descriptor inits. */
724 cd_p
->ccb_ptr
= ccb_p
;
727 /* Do an initial setup now. */
728 if (!setup_channel(ccb_p
))
730 logf("SDMA ch init failed: %d", channel
);
731 cd_p
->ccb_ptr
= NULL
;
732 memset(ccb_p
, 0x00, sizeof (struct channel_control_block
));
736 /* Enable interrupt if a callback is specified. */
737 if (cd_p
->callback
!= NULL
)
738 imx31_regset32(&sdma_enabled_ints
, 1ul << channel
);
740 /* Minimum schedulable = 1 */
741 sdma_channel_set_priority(channel
, 1);
743 logf("SDMA ch initialized: %d", channel
);
747 void sdma_channel_close(unsigned int channel
)
749 struct channel_control_block
*ccb_p
;
752 if (channel
== 0 || channel
>= CH_NUM
)
755 ccb_p
= &ccb_array
[channel
];
757 /* Block callbacks (if not initialized, it won't be set). */
758 imx31_regclr32(&sdma_enabled_ints
, 1ul << channel
);
760 if (ccb_p
->status
.opened_init
== 0)
763 /* Stop the channel if running */
764 for (i
= ccb_p
->channel_desc
->bd_count
- 1; i
>= 0; i
--)
765 ccb_p
->base_bd_ptr
[i
].mode
.status
&= ~BD_DONE
;
767 sdma_channel_stop(channel
);
770 set_channel_ownership(channel
, 0);
772 /* Cannot schedule it again */
773 sdma_channel_set_priority(channel
, 0);
775 /* Reset channel control block entry */
776 memset(ccb_p
, 0x00, sizeof (struct channel_control_block
));
779 /* Write 32-bit words to SDMA core memory. Host endian->SDMA endian. */
780 void sdma_write_words(const unsigned long *buf
, unsigned long start
, int count
)
782 /* Setup buffer descriptor with channel 0 command */
783 set_buffer_descriptor(&c0_buffer_desc
.bd
,
785 BD_DONE
| BD_WRAP
| BD_EXTD
,
787 (void *)addr_virt_to_phys((unsigned long)buf
),
791 sdma_channel_wait_nonblocking(0);
794 /* Read 32-bit words from SDMA core memory. SDMA endian->host endian. */
795 void sdma_read_words(unsigned long *buf
, unsigned long start
, int count
)
797 /* Setup buffer descriptor with channel 0 command */
798 set_buffer_descriptor(&c0_buffer_desc
.bd
,
800 BD_DONE
| BD_WRAP
| BD_EXTD
,
802 (void *)addr_virt_to_phys((unsigned long)buf
),
806 sdma_channel_wait_nonblocking(0);