summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c329
1 files changed, 0 insertions, 329 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c b/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c
deleted file mode 100644
index c5d47705ec..0000000000
--- a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/**
- * @file
- *
- * @ingroup mpc55xx
- *
- * @brief Enhanced Direct Memory Access (eDMA).
- */
-
-/*
- * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <mpc55xx/edma.h>
-#include <mpc55xx/mpc55xx.h>
-
-#include <assert.h>
-
-#include <bsp.h>
-#include <bsp/fatal.h>
-#include <bsp/irq.h>
-
-#define EDMA_CHANNELS_PER_GROUP 32U
-
-#define EDMA_GROUP_COUNT ((EDMA_CHANNEL_COUNT + 31U) / 32U)
-
-#define EDMA_GROUP_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_GROUP)
-
-#define EDMA_GROUP_BIT(channel) (1U << ((channel) % EDMA_CHANNELS_PER_GROUP))
-
-#define EDMA_MODULE_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_MODULE)
-
-static uint32_t edma_channel_occupation [EDMA_GROUP_COUNT];
-
-static RTEMS_CHAIN_DEFINE_EMPTY(edma_channel_chain);
-
-static unsigned edma_channel_index_of_tcd(volatile struct tcd_t *edma_tcd)
-{
- volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
- unsigned channel = edma_tcd - &edma->TCD[0];
-
-#if EDMA_MODULE_COUNT == 1
- return channel;
-#elif EDMA_MODULE_COUNT == 2
- return channel + (&EDMA_A == edma ? 0 : EDMA_CHANNELS_PER_MODULE);
-#else
- #error "unsupported module count"
-#endif
-}
-
-static volatile struct EDMA_tag *edma_get_regs_by_module(unsigned module)
-{
-#if EDMA_MODULE_COUNT == 1
- return &EDMA;
-#elif EDMA_MODULE_COUNT == 2
- return module == 0 ? &EDMA_A : &EDMA_B;
-#else
- #error "unsupported module count"
-#endif
-}
-
-static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array)
-{
- unsigned array = channel / 32;
- uint32_t bit = 1U << (channel % 32);
- uint32_t previous = bit_array [array];
-
- bit_array [array] = previous | bit;
-
- return previous;
-}
-
-static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array)
-{
- unsigned array = channel / 32;
- uint32_t bit = 1U << (channel % 32);
- uint32_t previous = bit_array [array];
-
- bit_array [array] = previous & ~bit;
-
- return previous;
-}
-
-static void edma_interrupt_handler(void *arg)
-{
- edma_channel_context *ctx = arg;
-
- mpc55xx_edma_clear_interrupts(ctx->edma_tcd);
-
- (*ctx->done)(ctx, 0);
-}
-
-static void edma_interrupt_error_handler(void *arg)
-{
- rtems_chain_control *chain = &edma_channel_chain;
- rtems_chain_node *node = rtems_chain_first(chain);
- uint32_t error_channels [] = {
-#if EDMA_GROUP_COUNT >= 1
- EDMA.ERL.R
-#endif
-#if EDMA_GROUP_COUNT >= 2
- , EDMA.ERH.R
-#endif
-#if EDMA_GROUP_COUNT >= 3
- , EDMA_B.ERL.R
-#endif
- };
- uint32_t error_status [] = {
-#if EDMA_GROUP_COUNT >= 1
- EDMA.ESR.R
-#endif
-#if EDMA_GROUP_COUNT >= 3
- , EDMA_B.ESR.R
-#endif
- };
-
-#if EDMA_GROUP_COUNT >= 1
- EDMA.ERL.R = error_channels [0];
-#endif
-#if EDMA_GROUP_COUNT >= 2
- EDMA.ERH.R = error_channels [1];
-#endif
-#if EDMA_GROUP_COUNT >= 3
- EDMA_B.ERL.R = error_channels [2];
-#endif
-
- while (!rtems_chain_is_tail(chain, node)) {
- edma_channel_context *ctx = (edma_channel_context *) node;
- unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
- unsigned group_index = EDMA_GROUP_INDEX(channel_index);
- unsigned group_bit = EDMA_GROUP_BIT(channel_index);
-
- if ((error_channels [group_index] & group_bit) != 0) {
- unsigned module_index = EDMA_MODULE_INDEX(channel_index);
-
- (*ctx->done)(ctx, error_status [module_index]);
- }
-
- node = rtems_chain_next(node);
- }
-}
-
-void mpc55xx_edma_init(void)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- unsigned channel_remaining = EDMA_CHANNEL_COUNT;
- unsigned module = 0;
- unsigned group = 0;
-
- for (module = 0; module < EDMA_MODULE_COUNT; ++module) {
- volatile struct EDMA_tag *edma = edma_get_regs_by_module(module);
- unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ?
- channel_remaining : EDMA_CHANNELS_PER_MODULE;
- unsigned channel = 0;
-
- channel_remaining -= channel_count;
-
- /* Disable requests */
- edma->CERQR.B.CERQ = 0x40;
-
- /* Arbitration mode: group round robin, channel fixed */
- edma->CR.B.ERGA = 1;
- edma->CR.B.ERCA = 0;
- for (channel = 0; channel < channel_count; ++channel) {
- volatile struct tcd_t *tcd = &edma->TCD [channel];
- edma->CPR [channel].R = 0x80U | (channel & 0xfU);
-
- /* Initialize TCD, stop channel first */
- tcd->BMF.R = 0;
- tcd->SADDR = 0;
- tcd->SDF.R = 0;
- tcd->NBYTES = 0;
- tcd->SLAST = 0;
- tcd->DADDR = 0;
- tcd->CDF.R = 0;
- tcd->DLAST_SGA = 0;
- }
-
- /* Clear interrupt requests */
- edma->CIRQR.B.CINT = 0x40;
- edma->CER.B.CERR = 0x40;
- }
-
- for (group = 0; group < EDMA_GROUP_COUNT; ++group) {
- sc = mpc55xx_interrupt_handler_install(
- MPC55XX_IRQ_EDMA_ERROR(group),
- "eDMA Error",
- RTEMS_INTERRUPT_UNIQUE,
- MPC55XX_INTC_DEFAULT_PRIORITY,
- edma_interrupt_error_handler,
- NULL
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL);
- }
- }
-}
-
-rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
- volatile struct tcd_t *edma_tcd
-)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
- rtems_interrupt_level level;
- uint32_t channel_occupation;
-
- rtems_interrupt_disable(level);
- channel_occupation = edma_bit_array_set(
- channel_index,
- &edma_channel_occupation [0]
- );
- rtems_interrupt_enable(level);
-
- if ((channel_occupation & EDMA_GROUP_BIT(channel_index)) != 0) {
- sc = RTEMS_RESOURCE_IN_USE;
- }
-
- return sc;
-}
-
-void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd)
-{
- unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- edma_bit_array_clear(channel_index, &edma_channel_occupation [0]);
- rtems_interrupt_enable(level);
-
- mpc55xx_edma_disable_hardware_requests(edma_tcd);
- mpc55xx_edma_disable_error_interrupts(edma_tcd);
-}
-
-rtems_status_code mpc55xx_edma_obtain_channel(
- edma_channel_context *ctx,
- unsigned irq_priority
-)
-{
- rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd);
- if (sc == RTEMS_SUCCESSFUL) {
- unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
-
- sc = mpc55xx_interrupt_handler_install(
- MPC55XX_IRQ_EDMA(channel_index),
- "eDMA Channel",
- RTEMS_INTERRUPT_SHARED,
- irq_priority,
- edma_interrupt_handler,
- ctx
- );
- if (sc == RTEMS_SUCCESSFUL) {
- rtems_chain_prepend(&edma_channel_chain, &ctx->node);
- mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd);
- } else {
- mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
- sc = RTEMS_IO_ERROR;
- }
- }
-
- return sc;
-}
-
-void mpc55xx_edma_release_channel(edma_channel_context *ctx)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
-
- mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
- rtems_chain_extract(&ctx->node);
-
- sc = rtems_interrupt_handler_remove(
- MPC55XX_IRQ_EDMA(channel_index),
- edma_interrupt_handler,
- ctx
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_REMOVE);
- }
-}
-
-void mpc55xx_edma_copy(
- volatile struct tcd_t *edma_tcd,
- const struct tcd_t *source_tcd
-)
-{
- /* Clear DONE flag */
- edma_tcd->BMF.R = 0;
-
- edma_tcd->SADDR = source_tcd->SADDR;
- edma_tcd->SDF.R = source_tcd->SDF.R;
- edma_tcd->NBYTES = source_tcd->NBYTES;
- edma_tcd->SLAST = source_tcd->SLAST;
- edma_tcd->DADDR = source_tcd->DADDR;
- edma_tcd->CDF.R = source_tcd->CDF.R;
- edma_tcd->DLAST_SGA = source_tcd->DLAST_SGA;
- edma_tcd->BMF.R = source_tcd->BMF.R;
-}
-
-void mpc55xx_edma_copy_and_enable_hardware_requests(
- volatile struct tcd_t *edma_tcd,
- const struct tcd_t *source_tcd
-)
-{
- mpc55xx_edma_copy(edma_tcd, source_tcd);
- mpc55xx_edma_enable_hardware_requests(edma_tcd);
-}
-
-void mpc55xx_edma_sg_link(
- volatile struct tcd_t *edma_tcd,
- const struct tcd_t *source_tcd
-)
-{
- edma_tcd->DLAST_SGA = (int32_t) source_tcd;
- edma_tcd->BMF.B.E_SG = 1;
-
- if (!edma_tcd->BMF.B.E_SG) {
- mpc55xx_edma_copy(edma_tcd, source_tcd);
- }
-}