Skip to content

Commit

Permalink
[media] marvell-cam: fix the green screen of death
Browse files Browse the repository at this point in the history
I had learned through hard experience that dinking around with the DMA
descriptors while the C1_DESC_ENA enable bit was set is a recipe for all
kinds of truly malicious behavior on the hardware's part, regardless of
whether the DMA engine is actually operating at the time.  That
notwithstanding, the driver did so dink, resulting in "green frame"
captures and the death of the system in random, spectacular ways.

Move the tweaking of C1_DESC_ENA to the same function that sets the
descriptor so we know that we'll never try to set a descriptor while that
bit is set.

Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Jonathan Corbet authored and Mauro Carvalho Chehab committed Mar 20, 2012
1 parent 482d35c commit 121bbe2
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions drivers/media/video/marvell-ccic/mcam-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,17 @@ static void mcam_sg_next_buffer(struct mcam_camera *cam)

buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
list_del_init(&buf->queue);
/*
* Very Bad Not Good Things happen if you don't clear
* C1_DESC_ENA before making any descriptor changes.
*/
mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
mcam_reg_write(cam, REG_DESC_LEN_Y,
buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
mcam_reg_write(cam, REG_DESC_LEN_U, 0);
mcam_reg_write(cam, REG_DESC_LEN_V, 0);
mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
cam->vb_bufs[0] = buf;
}

Expand All @@ -533,7 +539,6 @@ static void mcam_ctlr_dma_sg(struct mcam_camera *cam)

mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD);
mcam_sg_next_buffer(cam);
mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
cam->nbufs = 3;
}

Expand All @@ -560,18 +565,12 @@ static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
*/
if (cam->state != S_STREAMING)
return;
/*
* Very Bad Not Good Things happen if you don't clear
* C1_DESC_ENA before making any descriptor changes.
*/
mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
/*
* If we have another buffer available, put it in and
* restart the engine.
*/
if (!list_empty(&cam->buffers)) {
mcam_sg_next_buffer(cam);
mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
mcam_ctlr_start(cam);
/*
* Otherwise set CF_SG_RESTART and the controller will
Expand Down

0 comments on commit 121bbe2

Please sign in to comment.