aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/ipu-v3
diff options
context:
space:
mode:
authorSteve Longerbeam <slongerbeam@gmail.com>2014-06-25 21:05:42 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2014-09-02 08:55:49 -0400
commite7268c699bbe578e6dcf02e9f7f5a267837bc18f (patch)
treed01f02172f258ea722460b3bb246d2907dc5902f /drivers/gpu/ipu-v3
parentbce6f087a958a21500c51a9e63a5f578f5b0510c (diff)
gpu: ipu-v3: Add __ipu_idmac_reset_current_buffer()
Adds __ipu_idmac_reset_current_buffer() that resets a channel's internal current buffer pointer so that transfers start from buffer 0 on the next channel enable. This operation is required for channel linking to work correctly, for instance video capture pipelines that carry out image rotations will fail after the first streaming unless this function is called for each channel before re-enabling the channels. Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/ipu-v3')
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 773a2fc8fed4..985a7508af3a 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -234,6 +234,25 @@ EXPORT_SYMBOL_GPL(ipu_idmac_put);
234 234
235#define idma_mask(ch) (1 << ((ch) & 0x1f)) 235#define idma_mask(ch) (1 << ((ch) & 0x1f))
236 236
237/*
238 * This is an undocumented feature, a write one to a channel bit in
239 * IPU_CHA_CUR_BUF and IPU_CHA_TRIPLE_CUR_BUF will reset the channel's
240 * internal current buffer pointer so that transfers start from buffer
241 * 0 on the next channel enable (that's the theory anyway, the imx6 TRM
242 * only says these are read-only registers). This operation is required
243 * for channel linking to work correctly, for instance video capture
244 * pipelines that carry out image rotations will fail after the first
245 * streaming unless this function is called for each channel before
246 * re-enabling the channels.
247 */
248static void __ipu_idmac_reset_current_buffer(struct ipuv3_channel *channel)
249{
250 struct ipu_soc *ipu = channel->ipu;
251 unsigned int chno = channel->num;
252
253 ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_CUR_BUF(chno));
254}
255
237void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel, 256void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
238 bool doublebuffer) 257 bool doublebuffer)
239{ 258{
@@ -250,6 +269,8 @@ void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
250 reg &= ~idma_mask(channel->num); 269 reg &= ~idma_mask(channel->num);
251 ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num)); 270 ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num));
252 271
272 __ipu_idmac_reset_current_buffer(channel);
273
253 spin_unlock_irqrestore(&ipu->lock, flags); 274 spin_unlock_irqrestore(&ipu->lock, flags);
254} 275}
255EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer); 276EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer);
@@ -455,6 +476,8 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
455 val &= ~idma_mask(channel->num); 476 val &= ~idma_mask(channel->num);
456 ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num)); 477 ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
457 478
479 __ipu_idmac_reset_current_buffer(channel);
480
458 /* Set channel buffers NOT to be ready */ 481 /* Set channel buffers NOT to be ready */
459 ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */ 482 ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */
460 483