summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaranjeiro2008-08-25 15:56:12 +0000
committerlaranjeiro2008-08-25 15:56:12 +0000
commitf17bd61947c3e9325c858a8866725fa28c0f1528 (patch)
treef08c1a0058371987c0aec1eea998f52b215a31b3
parentf3c26d7ec8b3b12fc00493165f7222bd48fddf17 (diff)
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
-rw-r--r--cesar/hal/phy/bridgedma.h12
-rw-r--r--cesar/hal/phy/src/bridgedma.c94
-rw-r--r--cesar/hal/phy/src/bridgedma_soft.c18
3 files changed, 84 insertions, 40 deletions
diff --git a/cesar/hal/phy/bridgedma.h b/cesar/hal/phy/bridgedma.h
index 02cea04f88..c85924ac41 100644
--- a/cesar/hal/phy/bridgedma.h
+++ b/cesar/hal/phy/bridgedma.h
@@ -143,6 +143,18 @@ phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
phy_bridgedma_job_t *job_last);
+/**
+ * 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);
+
END_DECLS
#endif /* hal_phy_bridgedma_h */
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;
+}
+
diff --git a/cesar/hal/phy/src/bridgedma_soft.c b/cesar/hal/phy/src/bridgedma_soft.c
index a351629c1f..3a64471a09 100644
--- a/cesar/hal/phy/src/bridgedma_soft.c
+++ b/cesar/hal/phy/src/bridgedma_soft.c
@@ -443,3 +443,21 @@ phy_bridgedma_proto_process (cyg_addrword_t data)
}
}
}
+
+/**
+ * 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;
+}
+