From f17bd61947c3e9325c858a8866725fa28c0f1528 Mon Sep 17 00:00:00 2001 From: laranjeiro Date: Mon, 25 Aug 2008 15:56:12 +0000 Subject: hal/phy/bridgedma: Update the driver. * Modified the algorithm to start and chain jobs in the bridgedma. * Modified the interruption function to ack the IT and call the ISR. * Added a function to get the current job currently process by the bridge DMA. It allow the process thoses which are already been processed. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2754 017c9cb6-072f-447c-8318-d5b54f68fe89 --- cesar/hal/phy/src/bridgedma.c | 94 +++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 40 deletions(-) (limited to 'cesar/hal/phy/src/bridgedma.c') diff --git a/cesar/hal/phy/src/bridgedma.c b/cesar/hal/phy/src/bridgedma.c index 7d8ba501f2..f666692f41 100644 --- a/cesar/hal/phy/src/bridgedma.c +++ b/cesar/hal/phy/src/bridgedma.c @@ -33,13 +33,20 @@ static phy_bridgedma_t phy_bridgedma_global; static cyg_uint32 _bridgedma_ecos_isr(cyg_vector_t vector, cyg_addrword_t data) { + volatile u32* job_current = (u32 *) PHY_BRIDGEDMA_CURR_JOBD_PTR; /* nothing to do except calling the bridgedma callback */ phy_bridgedma_t *bridgedma_ctx; - cyg_interrupt_mask(PHY_BRIDGEDMA_END_INTERRUPT); + /* ACK and unmask. */ + cyg_interrupt_acknowledge(PHY_BRIDGEDMA_END_INTERRUPT); + cyg_interrupt_unmask(PHY_BRIDGEDMA_END_INTERRUPT); bridgedma_ctx = (phy_bridgedma_t *)data; + /* Remove the head of the bridgedma list. */ + arch_write_buffer_flush (); + bridgedma_ctx->job_current = (phy_bridgedma_job_t *) *job_current; + if((*bridgedma_ctx->bridgedma_cb)(bridgedma_ctx->user_data, *((u32 *)((void *)&bridgedma_ctx->status)))) return CYG_ISR_CALL_DSR; // Cause DSR to be run @@ -62,11 +69,6 @@ _bridgedma_ecos_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data phy_bridgedma_t *bridgedma_ctx; bridgedma_ctx = (phy_bridgedma_t *)data; (*bridgedma_ctx->deferred_cb)(bridgedma_ctx->user_data); - - /* ACK and unmask. */ - cyg_interrupt_acknowledge(PHY_BRIDGEDMA_END_INTERRUPT); - cyg_interrupt_unmask(PHY_BRIDGEDMA_END_INTERRUPT); - return; } @@ -139,54 +141,66 @@ void phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first, phy_bridgedma_job_t *job_last) { - volatile u32* control; - volatile u32* job_current; - volatile u32* bridge_job_first; - volatile u32* debug_reg_start; + u32 *control = (u32*) PHY_BRIDGEDMA_CONTROL; + dbg_assert (ctx); dbg_assert (job_first); dbg_assert (job_last); - control = (u32*) PHY_BRIDGEDMA_CONTROL; - job_current = (u32 *) PHY_BRIDGEDMA_CURR_JOBD_PTR; - bridge_job_first = (u32 *) PHY_BRIDGEDMA_JOBD_PTR; - debug_reg_start = (u32 *) PHY_BRIDGEDMA_STATUS_ERROR; - - arch_reorder_barrier (); - - ctx->job_last->next = job_first; - ctx->job_last->last = false; - - /* The bridge is not working, start it with the new chain. */ - if (*debug_reg_start == 0x0) + /* Bridge context is empty. */ + if (ctx->job_first == NULL) { - *bridge_job_first = (u32) job_first; + volatile u32 *job_desc = (u32*) PHY_BRIDGEDMA_JOBD_PTR; + + ctx->job_first = job_first; ctx->job_last = job_last; + + /* Set the last bit to true in the last job. */ job_last->last = true; + + /* Set the address to the bridgedma. */ + arch_write_buffer_flush (); + *job_desc = (u32) job_first; + + /* Start the bridgedma. */ ((phy_bridgedma_ctrl_t *) control)->start = true; } else { - /* If the bridge is working on a job which is not the last previously - * provided, chain the new jobs to the last one in the bridge DMA context. */ - if (((phy_bridgedma_job_t *) job_current) != ctx->job_last) - { - ctx->job_last->last = false; - ctx->job_last->next = job_first; - ctx->job_last = job_last; - job_last->last = true; + volatile u32 *job_config = (u32*) PHY_BRIDGEDMA_JOB_CONF; - if (!((phy_bridgedma_ctrl_t *) control)->start) - ((phy_bridgedma_ctrl_t *) control)->start = true; - } - /* If the current job is the last, it shall chain the new chain with - * this one and reset the last flag of the current job. */ - else if (!((phy_bridgedma_job_t *)job_current)->last) + ctx->job_last->last = false; + ctx->job_last->next = job_first; + job_last->last = true; + + arch_write_buffer_flush (); + /* last_job is loaded, but transfer will stop or is stopped. */ + if (BF_GET (PHY_BRIDGEDMA_JOB_CONF__LAST, *job_config)) { - ctx->job_last->next = job_first; - ctx->job_last = job_last; - job_last->last = true; + volatile u32* first_job_desc = (u32 *)PHY_BRIDGEDMA_JOBD_PTR; + + arch_write_buffer_flush (); + *first_job_desc = (u32) job_first; + /* Start the bridgedma. */ + ((phy_bridgedma_ctrl_t *) control)->start = true; } } } +/** + * Get the current job descriptor from the bridgedma. + * \param ctx the Bridge DMA context. + * \return the address of the current job descriptor beeing processed by the + * bridge DMA. + * + * It corresponds to the current job which is being processed by the + * bridgedma when the Interruption arrived. + */ +phy_bridgedma_job_t * +phy_bridgedma_current_job (phy_bridgedma_t *ctx) +{ + dbg_assert (ctx); + + return ctx->job_current; +} + -- cgit v1.2.3