Changeset db21e1d in rtems


Ignore:
Timestamp:
Apr 3, 2013, 10:05:49 AM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
6cb3567
Parents:
4e3deaf7
git-author:
Sebastian Huber <sebastian.huber@…> (04/03/13 10:05:49)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/08/13 14:42:38)
Message:

bsp/mpc55xx: eDMA API changes

Location:
c/src/lib
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c

    r4e3deaf7 rdb21e1d  
    147147  rtems_id receive_task;
    148148  rtems_id transmit_task;
    149   mpc55xx_edma_channel_entry edma_receive;
    150   mpc55xx_edma_channel_entry edma_transmit;
     149  edma_channel_context edma_receive;
     150  edma_channel_context edma_transmit;
    151151  unsigned phy_interrupts;
    152152  unsigned received_frames;
     
    206206
    207207static void smsc9218i_transmit_dma_done(
    208   mpc55xx_edma_channel_entry *channel_entry,
     208  edma_channel_context *ctx,
    209209  uint32_t error_status
    210210);
    211211
    212212static void smsc9218i_receive_dma_done(
    213   mpc55xx_edma_channel_entry *e,
     213  edma_channel_context *ctx,
    214214  uint32_t error_status
    215215);
     
    220220  .transmit_task = RTEMS_ID_NONE,
    221221  .edma_receive = {
    222     .channel = SMSC9218I_EDMA_RX_CHANNEL,
    223     .done = smsc9218i_receive_dma_done,
    224     .id = RTEMS_ID_NONE
     222    .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(SMSC9218I_EDMA_RX_CHANNEL),
     223    .done = smsc9218i_receive_dma_done
    225224  },
    226225  .edma_transmit = {
    227     .channel = SMSC9218I_EDMA_TX_CHANNEL,
    228     .done = smsc9218i_transmit_dma_done,
    229     .id = RTEMS_ID_NONE
     226    .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(SMSC9218I_EDMA_TX_CHANNEL),
     227    .done = smsc9218i_transmit_dma_done
    230228  }
    231229};
     
    605603
    606604  if (last != NULL) {
    607     volatile struct tcd_t *channel = &EDMA.TCD [e->edma_receive.channel];
     605    volatile struct tcd_t *channel = e->edma_receive.edma_tcd;
    608606
    609607    /* Setup last TCD */
     
    626624
    627625static void smsc9218i_receive_dma_done(
    628   mpc55xx_edma_channel_entry *channel_entry,
     626  edma_channel_context *ctx,
    629627  uint32_t error_status
    630628)
     
    645643  }
    646644
    647   sc = rtems_bsdnet_event_send(channel_entry->id, SMSC9218I_EVENT_DMA);
     645  sc = rtems_bsdnet_event_send(e->receive_task, SMSC9218I_EVENT_DMA);
    648646  ASSERT_SC(sc);
    649647
     
    652650
    653651static void smsc9218i_transmit_dma_done(
    654   mpc55xx_edma_channel_entry *channel_entry,
     652  edma_channel_context *ctx,
    655653  uint32_t error_status
    656654)
     
    669667  ++e->transmit_dma_interrupts;
    670668
    671   sc = rtems_bsdnet_event_send(channel_entry->id, event);
     669  sc = rtems_bsdnet_event_send(e->transmit_task, event);
    672670  ASSERT_SC(sc);
    673671}
     
    867865
    868866  /* Obtain receive eDMA channel */
    869   e->edma_receive.id = e->receive_task;
    870867  sc = mpc55xx_edma_obtain_channel(
    871868    &e->edma_receive,
     
    12711268
    12721269    if (i > 0) {
    1273       volatile struct tcd_t *channel = &EDMA.TCD [e->edma_transmit.channel];
     1270      volatile struct tcd_t *channel = e->edma_transmit.edma_tcd;
    12741271      struct tcd_t *start = &jc->command_tcd_table [jc->transfer_index];
    12751272      struct tcd_t *last = &jc->data_tcd_table [last_index];
     
    14281425
    14291426  /* Obtain transmit eDMA channel */
    1430   e->edma_transmit.id = e->transmit_task;
    14311427  sc = mpc55xx_edma_obtain_channel(
    14321428    &e->edma_transmit,
  • c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c

    r4e3deaf7 rdb21e1d  
    114114};
    115115
    116 static void mpc55xx_dspi_edma_done( mpc55xx_edma_channel_entry *e, uint32_t error_status)
    117 {
     116static void mpc55xx_dspi_edma_done( edma_channel_context *ctx, uint32_t error_status)
     117{
     118        const mpc55xx_dspi_edma_entry *e = (const mpc55xx_dspi_edma_entry *) ctx;
    118119        rtems_semaphore_release( e->id);
    119120
     
    176177        RTEMS_CHECK_SC( sc, "create receive update semaphore");
    177178
    178         sc = mpc55xx_edma_obtain_channel( &e->edma_receive, MPC55XX_INTC_DEFAULT_PRIORITY);
     179        sc = mpc55xx_edma_obtain_channel( &e->edma_receive.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
    179180        RTEMS_CHECK_SC( sc, "obtain receive eDMA channel");
    180181
     
    189190        RTEMS_CHECK_SC( sc, "create transmit update semaphore");
    190191
    191         sc = mpc55xx_edma_obtain_channel( &e->edma_transmit, MPC55XX_INTC_DEFAULT_PRIORITY);
     192        sc = mpc55xx_edma_obtain_channel( &e->edma_transmit.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
    192193        RTEMS_CHECK_SC( sc, "obtain transmit eDMA channel");
    193194
    194         sc = mpc55xx_edma_obtain_channel( &e->edma_push, MPC55XX_INTC_DEFAULT_PRIORITY);
     195        sc = mpc55xx_edma_obtain_channel( &e->edma_push.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
    195196        RTEMS_CHECK_SC( sc, "obtain push eDMA channel");
    196197
     
    205206        tcd_push.BMF.B.BITER = 1;
    206207
    207         EDMA.TCD [e->edma_push.channel] = tcd_push;
     208        *e->edma_push.edma.edma_tcd = tcd_push;
    208209
    209210        /* Module Control Register */
     
    249250        }
    250251
    251         /* DMA/Interrupt Request Select and Enable Register */
     252        /* DMA/Interrupt Request Select and Enable Register */
    252253        rser.B.TFFFRE = 1;
    253254        rser.B.TFFFDIRS = 1;
     
    548549                        tcd_transmit.BMF.B.BITER = n_c;
    549550                } else {
    550                         EDMA.CDSBR.R = e->edma_transmit.channel;
     551                        unsigned push_channel = mpc55xx_edma_channel_by_tcd( e->edma_push.edma.edma_tcd);
     552                        mpc55xx_edma_clear_done( e->edma_transmit.edma.edma_tcd);
    551553                        tcd_transmit.SADDR = (uint32_t) out_c;
    552554                        tcd_transmit.SDF.B.SSIZE = 0;
     
    558560                        tcd_transmit.CDF.B.CITERE_LINK = 1;
    559561                        tcd_transmit.BMF.B.BITERE_LINK = 1;
    560                         tcd_transmit.BMF.B.MAJORLINKCH = e->edma_push.channel;
    561                         tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( e->edma_push.channel, n_c);
    562                         tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( e->edma_push.channel, n_c);
     562                        tcd_transmit.BMF.B.MAJORLINKCH = push_channel;
     563                        tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c);
     564                        tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c);
    563565                        tcd_transmit.BMF.B.MAJORE_LINK = 1;
    564566                }
    565567                tcd_transmit.BMF.B.D_REQ = 1;
    566568                tcd_transmit.BMF.B.INT_MAJ = 1;
    567                 EDMA.TCD [e->edma_transmit.channel] = tcd_transmit;
     569                *e->edma_transmit.edma.edma_tcd = tcd_transmit;
    568570
    569571                /* Set receive TCD */
     
    584586                tcd_receive.CDF.B.CITER = n_c;
    585587                tcd_receive.BMF.B.BITER = n_c;
    586                 EDMA.TCD [e->edma_receive.channel] = tcd_receive;
     588                *e->edma_receive.edma.edma_tcd = tcd_receive;
    587589
    588590                /* Clear request flags */
     
    593595
    594596                /* Enable hardware requests */
    595                 mpc55xx_edma_enable_hardware_requests( e->edma_receive.channel, true);
    596                 mpc55xx_edma_enable_hardware_requests( e->edma_transmit.channel, true);
     597                mpc55xx_edma_enable_hardware_requests( e->edma_receive.edma.edma_tcd);
     598                mpc55xx_edma_enable_hardware_requests( e->edma_transmit.edma.edma_tcd);
    597599
    598600                /* Wait for transmit update */
     
    677679                .push_data = MPC55XX_ZERO_FLAGS,
    678680                .edma_transmit = {
    679                         .channel = 32,
    680                         .done = mpc55xx_dspi_edma_done,
     681                        .edma = {
     682                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_TFFF),
     683                                .done = mpc55xx_dspi_edma_done
     684                        },
    681685                        .id = RTEMS_ID_NONE
    682686                },
    683687                .edma_push = {
    684                         .channel = 43,
    685                         .done = mpc55xx_dspi_edma_done,
     688                        .edma = {
     689                                .edma_tcd = &EDMA.TCD [43],
     690                                .done = mpc55xx_dspi_edma_done
     691                        },
    686692                        .id = RTEMS_ID_NONE
    687693                },
    688694                .edma_receive = {
    689                         .channel = 33,
    690                         .done = mpc55xx_dspi_edma_done,
     695                        .edma = {
     696                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_RFDF),
     697                                .done = mpc55xx_dspi_edma_done
     698                        },
    691699                        .id = RTEMS_ID_NONE
    692700                },
     
    705713                .push_data = MPC55XX_ZERO_FLAGS,
    706714                .edma_transmit = {
    707                         .channel = 12,
    708                         .done = mpc55xx_dspi_edma_done,
     715                        .edma = {
     716                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_TFFF),
     717                                .done = mpc55xx_dspi_edma_done
     718                        },
    709719                        .id = RTEMS_ID_NONE
    710720                },
    711721                .edma_push = {
    712                         .channel = 10,
    713                         .done = mpc55xx_dspi_edma_done,
     722                        .edma = {
     723                                .edma_tcd = &EDMA.TCD [10],
     724                                .done = mpc55xx_dspi_edma_done
     725                        },
    714726                        .id = RTEMS_ID_NONE
    715727                },
    716728                .edma_receive = {
    717                         .channel = 13,
    718                         .done = mpc55xx_dspi_edma_done,
     729                        .edma = {
     730                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_RFDF),
     731                                .done = mpc55xx_dspi_edma_done
     732                        },
    719733                        .id = RTEMS_ID_NONE
    720734                },
     
    733747                .push_data = MPC55XX_ZERO_FLAGS,
    734748                .edma_transmit = {
    735                         .channel = 14,
    736                         .done = mpc55xx_dspi_edma_done,
     749                        .edma = {
     750                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_TFFF),
     751                                .done = mpc55xx_dspi_edma_done
     752                        },
    737753                        .id = RTEMS_ID_NONE
    738754                },
    739755                .edma_push = {
    740                         .channel = 11,
    741                         .done = mpc55xx_dspi_edma_done,
     756                        .edma = {
     757                                .edma_tcd = &EDMA.TCD [11],
     758                                .done = mpc55xx_dspi_edma_done
     759                        },
    742760                        .id = RTEMS_ID_NONE
    743761                },
    744762                .edma_receive = {
    745                         .channel = 15,
    746                         .done = mpc55xx_dspi_edma_done,
     763                        .edma = {
     764                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_RFDF),
     765                                .done = mpc55xx_dspi_edma_done
     766                        },
    747767                        .id = RTEMS_ID_NONE
    748768                },
     
    762782                .push_data = MPC55XX_ZERO_FLAGS,
    763783                .edma_transmit = {
    764                         .channel = 16,
    765                         .done = mpc55xx_dspi_edma_done,
     784                        .edma = {
     785                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_TFFF),
     786                                .done = mpc55xx_dspi_edma_done
     787                        },
    766788                        .id = RTEMS_ID_NONE
    767789                },
    768790                .edma_push = {
    769                         .channel = 18,
    770                         .done = mpc55xx_dspi_edma_done,
     791                        .edma = {
     792                                .edma_tcd = &EDMA.TCD [18],
     793                                .done = mpc55xx_dspi_edma_done
     794                        },
    771795                        .id = RTEMS_ID_NONE
    772796                },
    773797                .edma_receive = {
    774                         .channel = 17,
    775                         .done = mpc55xx_dspi_edma_done,
     798                        .edma = {
     799                                .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_RFDF),
     800                                .done = mpc55xx_dspi_edma_done
     801                        },
    776802                        .id = RTEMS_ID_NONE
    777803                },
  • c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c

    r4e3deaf7 rdb21e1d  
    88
    99/*
    10  * Copyright (c) 2008-2012 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2008-2013 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
    13  *  Obere Lagerstr. 30
     13 *  Dornierstr. 4
    1414 *  82178 Puchheim
    1515 *  Germany
     
    2121 */
    2222
    23 #include <mpc55xx/regs.h>
    2423#include <mpc55xx/edma.h>
    2524#include <mpc55xx/mpc55xx.h>
     
    3029#include <bsp/irq.h>
    3130
    32 #if MPC55XX_CHIP_FAMILY == 551
    33   #define EDMA_CHANNEL_COUNT 16U
    34 #elif MPC55XX_CHIP_FAMILY == 564
    35   #define EDMA_CHANNEL_COUNT 16U
    36 #elif MPC55XX_CHIP_FAMILY == 567
    37   #define EDMA_CHANNEL_COUNT 96U
    38 #else
    39   #define EDMA_CHANNEL_COUNT 64U
    40 #endif
    41 
    4231#define EDMA_CHANNELS_PER_GROUP 32U
    4332
    44 #define EDMA_CHANNELS_PER_MODULE 64U
    45 
    4633#define EDMA_GROUP_COUNT ((EDMA_CHANNEL_COUNT + 31U) / 32U)
    4734
    48 #define EDMA_MODULE_COUNT ((EDMA_CHANNEL_COUNT + 63U) / 64U)
    49 
    50 #define EDMA_INVALID_CHANNEL EDMA_CHANNEL_COUNT
    51 
    52 #define EDMA_IS_CHANNEL_INVALID(i) ((unsigned) (i) >= EDMA_CHANNEL_COUNT)
    53 
    54 #define EDMA_IS_CHANNEL_VALID(i) ((unsigned) (i) < EDMA_CHANNEL_COUNT)
    55 
    5635#define EDMA_GROUP_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_GROUP)
    5736
     
    6039#define EDMA_MODULE_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_MODULE)
    6140
    62 #define EDMA_MODULE_BIT(channel) (1U << ((channel) % EDMA_CHANNELS_PER_MODULE))
    63 
    6441static uint32_t edma_channel_occupation [EDMA_GROUP_COUNT];
    6542
    6643static RTEMS_CHAIN_DEFINE_EMPTY(edma_channel_chain);
    6744
    68 static volatile struct EDMA_tag *edma_get_regs_by_channel(unsigned channel)
    69 {
     45static unsigned edma_channel_index_of_tcd(volatile struct tcd_t *edma_tcd)
     46{
     47  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     48  unsigned channel = edma_tcd - &edma->TCD[0];
     49
    7050#if EDMA_MODULE_COUNT == 1
    71   return &EDMA;
     51  return channel;
    7252#elif EDMA_MODULE_COUNT == 2
    73   return channel < EDMA_CHANNELS_PER_MODULE ? &EDMA_A : &EDMA_B;
     53  return channel + (&EDMA_A == edma ? 0 : EDMA_CHANNELS_PER_MODULE);
    7454#else
    7555  #error "unsupported module count"
     
    11292static void edma_interrupt_handler(void *arg)
    11393{
    114   mpc55xx_edma_channel_entry *e = arg;
    115   unsigned channel = e->channel;
    116   volatile struct EDMA_tag *edma = edma_get_regs_by_channel(channel);
    117 
    118   edma->CIRQR.R = (uint8_t) channel;
    119 
    120   e->done(e, 0);
     94  edma_channel_context *ctx = arg;
     95
     96  mpc55xx_edma_clear_interrupts(ctx->edma_tcd);
     97
     98  (*ctx->done)(ctx, 0);
    12199}
    122100
     
    156134
    157135  while (!rtems_chain_is_tail(chain, node)) {
    158     mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) node;
    159     unsigned channel = e->channel;
    160     unsigned group_index = EDMA_GROUP_INDEX(channel);
    161     unsigned group_bit = EDMA_GROUP_BIT(channel);
     136    edma_channel_context *ctx = (edma_channel_context *) node;
     137    unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
     138    unsigned group_index = EDMA_GROUP_INDEX(channel_index);
     139    unsigned group_bit = EDMA_GROUP_BIT(channel_index);
    162140
    163141    if ((error_channels [group_index] & group_bit) != 0) {
    164       unsigned module_index = EDMA_MODULE_INDEX(channel);
    165 
    166       e->done(e, error_status [module_index]);
     142      unsigned module_index = EDMA_MODULE_INDEX(channel_index);
     143
     144      (*ctx->done)(ctx, error_status [module_index]);
    167145    }
    168146
    169147    node = rtems_chain_next(node);
    170   }
    171 }
    172 
    173 void mpc55xx_edma_enable_hardware_requests(unsigned channel, bool enable)
    174 {
    175   volatile struct EDMA_tag *edma = edma_get_regs_by_channel(channel);
    176 
    177   assert(EDMA_IS_CHANNEL_VALID(channel));
    178 
    179   if (enable) {
    180     edma->SERQR.R = (uint8_t) channel;
    181   } else {
    182     edma->CERQR.R = (uint8_t) channel;
    183   }
    184 }
    185 
    186 void mpc55xx_edma_enable_error_interrupts(unsigned channel, bool enable)
    187 {
    188   volatile struct EDMA_tag *edma = edma_get_regs_by_channel(channel);
    189 
    190   assert(EDMA_IS_CHANNEL_VALID(channel));
    191 
    192   if (enable) {
    193     edma->SEEIR.R = (uint8_t) channel;
    194   } else {
    195     edma->CEEIR.R = (uint8_t) channel;
    196148  }
    197149}
     
    253205}
    254206
    255 rtems_status_code mpc55xx_edma_obtain_channel(
    256   mpc55xx_edma_channel_entry *e,
    257   unsigned irq_priority
     207rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
     208  volatile struct tcd_t *edma_tcd
    258209)
    259210{
    260211  rtems_status_code sc = RTEMS_SUCCESSFUL;
     212  unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
    261213  rtems_interrupt_level level;
    262   unsigned channel = e->channel;
    263   uint32_t channel_occupation = 0;
    264 
    265   if (EDMA_IS_CHANNEL_INVALID(channel)) {
    266     return RTEMS_INVALID_ID;
    267   }
     214  uint32_t channel_occupation;
    268215
    269216  rtems_interrupt_disable(level);
    270217  channel_occupation = edma_bit_array_set(
    271     channel,
     218    channel_index,
    272219    &edma_channel_occupation [0]
    273220  );
    274221  rtems_interrupt_enable(level);
    275222
    276   if ((channel_occupation & EDMA_GROUP_BIT(channel))) {
    277     return RTEMS_RESOURCE_IN_USE;
    278   }
    279 
    280   sc = mpc55xx_interrupt_handler_install(
    281     MPC55XX_IRQ_EDMA(channel),
    282     "eDMA Channel",
    283     RTEMS_INTERRUPT_SHARED,
    284     irq_priority,
     223  if ((channel_occupation & EDMA_GROUP_BIT(channel_index)) != 0) {
     224    sc = RTEMS_RESOURCE_IN_USE;
     225  }
     226
     227  return sc;
     228}
     229
     230void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd)
     231{
     232  unsigned channel_index = edma_channel_index_of_tcd(edma_tcd);
     233  rtems_interrupt_level level;
     234
     235  rtems_interrupt_disable(level);
     236  edma_bit_array_clear(channel_index, &edma_channel_occupation [0]);
     237  rtems_interrupt_enable(level);
     238
     239  mpc55xx_edma_disable_hardware_requests(edma_tcd);
     240  mpc55xx_edma_disable_error_interrupts(edma_tcd);
     241}
     242
     243rtems_status_code mpc55xx_edma_obtain_channel(
     244  edma_channel_context *ctx,
     245  unsigned irq_priority
     246)
     247{
     248  rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd);
     249  if (sc == RTEMS_SUCCESSFUL) {
     250    unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
     251
     252    sc = mpc55xx_interrupt_handler_install(
     253      MPC55XX_IRQ_EDMA(channel_index),
     254      "eDMA Channel",
     255      RTEMS_INTERRUPT_SHARED,
     256      irq_priority,
     257      edma_interrupt_handler,
     258      ctx
     259    );
     260    if (sc == RTEMS_SUCCESSFUL) {
     261      rtems_chain_prepend(&edma_channel_chain, &ctx->node);
     262      mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd);
     263    } else {
     264      mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
     265      sc = RTEMS_IO_ERROR;
     266    }
     267  }
     268
     269  return sc;
     270}
     271
     272void mpc55xx_edma_release_channel(edma_channel_context *ctx)
     273{
     274  rtems_status_code sc = RTEMS_SUCCESSFUL;
     275  unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
     276
     277  mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
     278  rtems_chain_extract(&ctx->node);
     279
     280  sc = rtems_interrupt_handler_remove(
     281    MPC55XX_IRQ_EDMA(channel_index),
    285282    edma_interrupt_handler,
    286     e
    287   );
    288   if (sc != RTEMS_SUCCESSFUL) {
    289     rtems_interrupt_disable(level);
    290     edma_bit_array_clear(channel, &edma_channel_occupation [0]);
    291     rtems_interrupt_enable(level);
    292 
    293     return RTEMS_IO_ERROR;
    294   }
    295 
    296   rtems_chain_prepend(&edma_channel_chain, &e->node);
    297   mpc55xx_edma_enable_error_interrupts(channel, true);
    298 
    299   return RTEMS_SUCCESSFUL;
    300 }
    301 
    302 void mpc55xx_edma_release_channel(mpc55xx_edma_channel_entry *e)
    303 {
    304   rtems_status_code sc = RTEMS_SUCCESSFUL;
    305   rtems_interrupt_level level;
    306   unsigned channel = e->channel;
    307 
    308   rtems_interrupt_disable(level);
    309   edma_bit_array_clear(channel, &edma_channel_occupation [0]);
    310   rtems_interrupt_enable(level);
    311 
    312   mpc55xx_edma_enable_hardware_requests(channel, false);
    313   mpc55xx_edma_enable_error_interrupts(channel, false);
    314   rtems_chain_extract(&e->node);
    315 
    316   sc = rtems_interrupt_handler_remove(
    317     MPC55XX_IRQ_EDMA(e->channel),
    318     edma_interrupt_handler,
    319     e
     283    ctx
    320284  );
    321285  if (sc != RTEMS_SUCCESSFUL) {
    322286    mpc55xx_fatal(MPC55XX_FATAL_EDMA_IRQ_REMOVE);
    323287  }
    324 
    325   e->done(e, 0);
    326 }
     288}
     289
     290void mpc55xx_edma_copy(
     291  volatile struct tcd_t *edma_tcd,
     292  const struct tcd_t *source_tcd
     293)
     294{
     295  /* Clear DONE flag */
     296  edma_tcd->BMF.R = 0;
     297
     298  edma_tcd->SADDR = source_tcd->SADDR;
     299  edma_tcd->SDF.R = source_tcd->SDF.R;
     300  edma_tcd->NBYTES = source_tcd->NBYTES;
     301  edma_tcd->SLAST = source_tcd->SLAST;
     302  edma_tcd->DADDR = source_tcd->DADDR;
     303  edma_tcd->CDF.R = source_tcd->CDF.R;
     304  edma_tcd->DLAST_SGA = source_tcd->DLAST_SGA;
     305  edma_tcd->BMF.R = source_tcd->BMF.R;
     306}
     307
     308void mpc55xx_edma_copy_and_enable_hardware_requests(
     309  volatile struct tcd_t *edma_tcd,
     310  const struct tcd_t *source_tcd
     311)
     312{
     313  mpc55xx_edma_copy(edma_tcd, source_tcd);
     314  mpc55xx_edma_enable_hardware_requests(edma_tcd);
     315}
     316
     317void mpc55xx_edma_sg_link(
     318  volatile struct tcd_t *edma_tcd,
     319  const struct tcd_t *source_tcd
     320)
     321{
     322  edma_tcd->DLAST_SGA = (int32_t) source_tcd;
     323  edma_tcd->BMF.B.E_SG = 1;
     324
     325  if (!edma_tcd->BMF.B.E_SG) {
     326    mpc55xx_edma_copy(edma_tcd, source_tcd);
     327  }
     328}
  • c/src/lib/libcpu/powerpc/mpc55xx/include/dspi.h

    r4e3deaf7 rdb21e1d  
    3838
    3939struct DSPI_tag;
     40
     41typedef struct {
     42  edma_channel_context edma;
     43  rtems_id id;
     44} mpc55xx_dspi_edma_entry;
    4045
    4146/**
     
    8085         * The channel is fixed to a particular DSPI.
    8186         */
    82         mpc55xx_edma_channel_entry edma_transmit;
     87        mpc55xx_dspi_edma_entry edma_transmit;
    8388
    8489        /**
     
    8792         * You can choose every available channel.
    8893         */
    89         mpc55xx_edma_channel_entry edma_push;
     94        mpc55xx_dspi_edma_entry edma_push;
    9095
    9196        /**
     
    9499         * The channel is fixed to a particular DSPI.
    95100         */
    96         mpc55xx_edma_channel_entry edma_receive;
     101        mpc55xx_dspi_edma_entry edma_receive;
    97102
    98103        /**
  • c/src/lib/libcpu/powerpc/mpc55xx/include/edma.h

    r4e3deaf7 rdb21e1d  
    88
    99/*
    10  * Copyright (c) 2008
    11  * Embedded Brains GmbH
    12  * Obere Lagerstr. 30
    13  * D-82178 Puchheim
    14  * Germany
    15  * rtems@embedded-brains.de
     10 * Copyright (c) 2008-2013 embedded brains GmbH.  All rights reserved.
     11 *
     12 *  embedded brains GmbH
     13 *  Dornierstr. 4
     14 *  82178 Puchheim
     15 *  Germany
     16 *  <rtems@embedded-brains.de>
    1617 *
    1718 * The license and distribution terms for this file may be
     
    2324#define LIBCPU_POWERPC_MPC55XX_EDMA_H
    2425
    25 #include <stdbool.h>
    26 #include <stdint.h>
     26#include <mpc55xx/regs.h>
    2727
    2828#include <rtems.h>
     
    3333#endif /* __cplusplus */
    3434
    35 typedef struct mpc55xx_edma_channel_entry {
     35#if MPC55XX_CHIP_FAMILY == 551
     36  #define EDMA_CHANNEL_COUNT 16U
     37#elif MPC55XX_CHIP_FAMILY == 564
     38  #define EDMA_CHANNEL_COUNT 16U
     39#elif MPC55XX_CHIP_FAMILY == 567
     40  #define EDMA_CHANNEL_COUNT 96U
     41#else
     42  #define EDMA_CHANNEL_COUNT 64U
     43#endif
     44
     45#define EDMA_MODULE_COUNT ((EDMA_CHANNEL_COUNT + 63U) / 64U)
     46
     47#define EDMA_CHANNELS_PER_MODULE 64U
     48
     49#if EDMA_MODULE_COUNT == 1
     50  #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
     51    (&EDMA.TCD[(channel_index)])
     52#elif EDMA_MODULE_COUNT == 2
     53  #define EDMA_TCD_BY_CHANNEL_INDEX(channel_index) \
     54    ((channel_index) < EDMA_CHANNELS_PER_MODULE ? \
     55      &EDMA_A.TCD[(channel_index)] \
     56        : &EDMA_B.TCD[(channel_index) - EDMA_CHANNELS_PER_MODULE])
     57#else
     58  #error "unsupported module count"
     59#endif
     60
     61/* FIXME: These values are only valid for the MPC5566 and MPC5674F */
     62typedef enum {
     63  EDMA_EQADC_A_FISR0_CFFF0 = 0,
     64  EDMA_EQADC_A_FISR0_RFDF0 = 1,
     65  EDMA_EQADC_A_FISR1_CFFF1 = 2,
     66  EDMA_EQADC_A_FISR1_RFDF1 = 3,
     67  EDMA_EQADC_A_FISR2_CFFF2 = 4,
     68  EDMA_EQADC_A_FISR2_RFDF2 = 5,
     69  EDMA_EQADC_A_FISR3_CFFF3 = 6,
     70  EDMA_EQADC_A_FISR3_RFDF3 = 7,
     71  EDMA_EQADC_A_FISR4_CFFF4 = 8,
     72  EDMA_EQADC_A_FISR4_RFDF4 = 9,
     73  EDMA_EQADC_A_FISR5_CFFF5 = 10,
     74  EDMA_EQADC_A_FISR5_RFDF5 = 11,
     75  EDMA_DSPI_B_SR_TFFF = 12,
     76  EDMA_DSPI_B_SR_RFDF = 13,
     77  EDMA_DSPI_C_SR_TFFF = 14,
     78  EDMA_DSPI_C_SR_RFDF = 15,
     79  EDMA_DSPI_D_SR_TFFF = 16,
     80  EDMA_DSPI_D_SR_RFDF = 17,
     81  EDMA_ESCI_A_COMBTX = 18,
     82  EDMA_ESCI_A_COMBRX = 19,
     83  EDMA_EMIOS_GFR_F0 = 20,
     84  EDMA_EMIOS_GFR_F1 = 21,
     85  EDMA_EMIOS_GFR_F2 = 22,
     86  EDMA_EMIOS_GFR_F3 = 23,
     87  EDMA_EMIOS_GFR_F4 = 24,
     88  EDMA_EMIOS_GFR_F8 = 25,
     89  EDMA_EMIOS_GFR_F9 = 26,
     90  EDMA_ETPU_CDTRSR_A_DTRS0 = 27,
     91  EDMA_ETPU_CDTRSR_A_DTRS1 = 28,
     92  EDMA_ETPU_CDTRSR_A_DTRS2 = 29,
     93  EDMA_ETPU_CDTRSR_A_DTRS14 = 30,
     94  EDMA_ETPU_CDTRSR_A_DTRS15 = 31,
     95  EDMA_DSPI_A_SR_TFFF = 32,
     96  EDMA_DSPI_A_SR_RFDF = 33,
     97  EDMA_ESCI_B_COMBTX = 34,
     98  EDMA_ESCI_B_COMBRX = 35,
     99  EDMA_EMIOS_GFR_F6 = 36,
     100  EDMA_EMIOS_GFR_F7 = 37,
     101  EDMA_EMIOS_GFR_F10 = 38,
     102  EDMA_EMIOS_GFR_F11 = 39,
     103  EDMA_EMIOS_GFR_F16 = 40,
     104  EDMA_EMIOS_GFR_F17 = 41,
     105  EDMA_EMIOS_GFR_F18 = 42,
     106  EDMA_EMIOS_GFR_F19 = 43,
     107  EDMA_ETPU_CDTRSR_A_DTRS12 = 44,
     108  EDMA_ETPU_CDTRSR_A_DTRS13 = 45,
     109  EDMA_ETPU_CDTRSR_A_DTRS28 = 46,
     110  EDMA_ETPU_CDTRSR_A_DTRS29 = 47,
     111  EDMA_SIU_EISR_EIF0 = 48,
     112  EDMA_SIU_EISR_EIF1 = 49,
     113  EDMA_SIU_EISR_EIF2 = 50,
     114  EDMA_SIU_EISR_EIF3 = 51,
     115  EDMA_ETPU_CDTRSR_B_DTRS0 = 52,
     116  EDMA_ETPU_CDTRSR_B_DTRS1 = 53,
     117  EDMA_ETPU_CDTRSR_B_DTRS2 = 54,
     118  EDMA_ETPU_CDTRSR_B_DTRS3 = 55,
     119  EDMA_ETPU_CDTRSR_B_DTRS12 = 56,
     120  EDMA_ETPU_CDTRSR_B_DTRS13 = 57,
     121  EDMA_ETPU_CDTRSR_B_DTRS14 = 58,
     122  EDMA_ETPU_CDTRSR_B_DTRS15 = 59,
     123  EDMA_ETPU_CDTRSR_B_DTRS28 = 60,
     124  EDMA_ETPU_CDTRSR_B_DTRS29 = 61,
     125  EDMA_ETPU_CDTRSR_B_DTRS30 = 62,
     126  EDMA_ETPU_CDTRSR_B_DTRS31 = 63
     127  #if MPC55XX_CHIP_FAMILY == 567
     128    ,
     129    EDMA_EQADC_B_FISR0_CFFF0 = 64 + 0,
     130    EDMA_EQADC_B_FISR0_RFDF0 = 64 + 1,
     131    EDMA_EQADC_B_FISR1_CFFF1 = 64 + 2,
     132    EDMA_EQADC_B_FISR1_RFDF1 = 64 + 3,
     133    EDMA_EQADC_B_FISR2_CFFF2 = 64 + 4,
     134    EDMA_EQADC_B_FISR2_RFDF2 = 64 + 5,
     135    EDMA_EQADC_B_FISR3_CFFF3 = 64 + 6,
     136    EDMA_EQADC_B_FISR3_RFDF3 = 64 + 7,
     137    EDMA_EQADC_B_FISR4_CFFF4 = 64 + 8,
     138    EDMA_EQADC_B_FISR4_RFDF3 = 64 + 9,
     139    EDMA_EQADC_B_FISR5_CFFF5 = 64 + 10,
     140    EDMA_EQADC_B_FISR5_RFDF5 = 64 + 11,
     141    EDMA_DECFILTER_A_IB = 64 + 12,
     142    EDMA_DECFILTER_A_OB = 64 + 13,
     143    EDMA_DECFILTER_B_IB = 64 + 14,
     144    EDMA_DECFILTER_B_OB = 64 + 15,
     145    EDMA_DECFILTER_C_IB = 64 + 16,
     146    EDMA_DECFILTER_C_OB = 64 + 17,
     147    EDMA_DECFILTER_D_IB = 64 + 18,
     148    EDMA_DECFILTER_D_OB = 64 + 19,
     149    EDMA_DECFILTER_E_IB = 64 + 20,
     150    EDMA_DECFILTER_E_OB = 64 + 21,
     151    EDMA_DECFILTER_F_IB = 64 + 22,
     152    EDMA_DECFILTER_F_OB = 64 + 23,
     153    EDMA_DECFILTER_G_IB = 64 + 24,
     154    EDMA_DECFILTER_G_OB = 64 + 25,
     155    EDMA_DECFILTER_H_IB = 64 + 26,
     156    EDMA_DECFILTER_H_OB = 64 + 27
     157  #endif
     158} edma_channel;
     159
     160typedef struct edma_channel_context {
    36161  rtems_chain_node node;
    37   unsigned channel;
    38   void (*done)( struct mpc55xx_edma_channel_entry *, uint32_t);
    39   rtems_id id;
    40 } mpc55xx_edma_channel_entry;
     162  volatile struct tcd_t *edma_tcd;
     163  void (*done)(struct edma_channel_context *, uint32_t);
     164} edma_channel_context;
    41165
    42166void mpc55xx_edma_init(void);
    43167
    44 rtems_status_code mpc55xx_edma_obtain_channel( mpc55xx_edma_channel_entry *e, unsigned irq_priority);
    45 
    46 void mpc55xx_edma_release_channel( mpc55xx_edma_channel_entry *e);
    47 
    48 void mpc55xx_edma_enable_hardware_requests( unsigned channel, bool enable);
    49 
    50 void mpc55xx_edma_enable_error_interrupts( unsigned channel, bool enable);
     168/**
     169 * @brief Obtains an eDMA channel.
     170 *
     171 * @retval RTEMS_SUCCESSFUL Successful operation.
     172 * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
     173 */
     174rtems_status_code mpc55xx_edma_obtain_channel_by_tcd(
     175  volatile struct tcd_t *edma_tcd
     176);
     177
     178void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd);
     179
     180/**
     181 * @brief Obtains an eDMA channel and registers the channel context.
     182 *
     183 * The done handler of the channel context will be called
     184 * - during minor or major loop completions if interrupts are enabled in the
     185 *   corresponding TCD, or
     186 * - in case a channel error occurs.
     187 *
     188 * An error status value not equal to zero indicates an error.
     189 *
     190 * @retval RTEMS_SUCCESSFUL Successful operation.
     191 * @retval RTEMS_RESOURCE_IN_USE The channel is already in use.
     192 * @retval RTEMS_IO_ERROR Unable to install interrupt handler for this channel.
     193 */
     194rtems_status_code mpc55xx_edma_obtain_channel(
     195  edma_channel_context *ctx,
     196  unsigned irq_priority
     197);
     198
     199void mpc55xx_edma_release_channel(edma_channel_context *ctx);
     200
     201/**
     202 * @brief Copies a source TCD to an eDMA TCD.
     203 *
     204 * The DONE flag of the eDMA TCD is cleared before the actual copy operation.
     205 * This enables the setting of channel link or scatter/gather options.
     206 *
     207 * This function can be used to start the channel if the START flags is
     208 * set in the source TCD.
     209 */
     210void mpc55xx_edma_copy(
     211  volatile struct tcd_t *edma_tcd,
     212  const struct tcd_t *source_tcd
     213);
     214
     215/**
     216 * @brief Copies a source TCD to an eDMA TCD and enables hardware requests.
     217 *
     218 * The DONE flag of the eDMA TCD is cleared before the actual copy operation.
     219 * This enables the setting of channel link or scatter/gather options.
     220 */
     221void mpc55xx_edma_copy_and_enable_hardware_requests(
     222  volatile struct tcd_t *edma_tcd,
     223  const struct tcd_t *source_tcd
     224);
     225
     226void mpc55xx_edma_sg_link(
     227  volatile struct tcd_t *edma_tcd,
     228  const struct tcd_t *source_tcd
     229);
     230
     231static inline volatile struct EDMA_tag *mpc55xx_edma_by_tcd(
     232  volatile struct tcd_t *edma_tcd
     233)
     234{
     235  return (volatile struct EDMA_tag *)
     236    ((uintptr_t) edma_tcd & ~(uintptr_t) 0x1fff);
     237}
     238
     239static inline unsigned mpc55xx_edma_channel_by_tcd(
     240  volatile struct tcd_t *edma_tcd
     241)
     242{
     243  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     244
     245  return edma_tcd - &edma->TCD[0];
     246}
     247
     248static inline void mpc55xx_edma_enable_hardware_requests(
     249  volatile struct tcd_t *edma_tcd
     250)
     251{
     252  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     253  unsigned channel = edma_tcd - &edma->TCD[0];
     254
     255  edma->SERQR.R = (uint8_t) channel;
     256}
     257
     258static inline void mpc55xx_edma_disable_hardware_requests(
     259  volatile struct tcd_t *edma_tcd
     260)
     261{
     262  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     263  unsigned channel = edma_tcd - &edma->TCD[0];
     264
     265  edma->CERQR.R = (uint8_t) channel;
     266}
     267
     268static inline void mpc55xx_edma_enable_error_interrupts(
     269  volatile struct tcd_t *edma_tcd
     270)
     271{
     272  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     273  unsigned channel = edma_tcd - &edma->TCD[0];
     274
     275  edma->SEEIR.R = (uint8_t) channel;
     276}
     277
     278static inline void mpc55xx_edma_disable_error_interrupts(
     279  volatile struct tcd_t *edma_tcd
     280)
     281{
     282  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     283  unsigned channel = edma_tcd - &edma->TCD[0];
     284
     285  edma->CEEIR.R = (uint8_t) channel;
     286}
     287
     288static inline void mpc55xx_edma_set_start(
     289  volatile struct tcd_t *edma_tcd
     290)
     291{
     292  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     293  unsigned channel = edma_tcd - &edma->TCD[0];
     294
     295  edma->SSBR.R = (uint8_t) channel;
     296}
     297
     298static inline void mpc55xx_edma_clear_done(
     299  volatile struct tcd_t *edma_tcd
     300)
     301{
     302  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     303  unsigned channel = edma_tcd - &edma->TCD[0];
     304
     305  edma->CDSBR.R = (uint8_t) channel;
     306}
     307
     308static inline void mpc55xx_edma_clear_interrupts(
     309  volatile struct tcd_t *edma_tcd
     310)
     311{
     312  volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd);
     313  unsigned channel = edma_tcd - &edma->TCD[0];
     314
     315  edma->CIRQR.R = (uint8_t) channel;
     316}
     317
     318static inline bool mpc55xx_edma_is_done(
     319  volatile struct tcd_t *edma_tcd
     320)
     321{
     322  return edma_tcd->BMF.B.DONE;
     323}
    51324
    52325#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.