diff options
author | Nikhil Devshatwar | 2014-04-11 12:46:48 -0500 |
---|---|---|
committer | Rakesh Movva | 2014-05-01 14:30:18 -0500 |
commit | 4933345da3fd96db02d5762f6dfa64f1e6971579 (patch) | |
tree | f6d13e66802d10f4ff74b1c2947370a49ac95353 | |
parent | 16ed08f272cc6cedc7f425367231bf0f089f7f29 (diff) | |
download | kernel-video-4933345da3fd96db02d5762f6dfa64f1e6971579.tar.gz kernel-video-4933345da3fd96db02d5762f6dfa64f1e6971579.tar.xz kernel-video-4933345da3fd96db02d5762f6dfa64f1e6971579.zip |
v4l: ti-vps: vpdma: Use write desciptor bit in dtd
VPDMA can create a descriptor after an outbound descriptor is processed.
The output descriptor contains useful information like the width height
of the DMA transfer, Also it contains field id of the data.
update_dma_addr function changes the descriptor so that, every time the
write descriptor bit is set allowing the driver to read these properties.
Change-Id: I69db45fe86b79f00dbd6d0ab4ed42bd86a166782
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
-rw-r--r-- | drivers/media/platform/ti-vps/vip.c | 11 | ||||
-rw-r--r-- | drivers/media/platform/ti-vps/vip.h | 1 | ||||
-rw-r--r-- | drivers/media/platform/ti-vps/vpdma.c | 28 | ||||
-rw-r--r-- | drivers/media/platform/ti-vps/vpdma.h | 5 | ||||
-rw-r--r-- | drivers/media/platform/ti-vps/vpdma_priv.h | 2 |
5 files changed, 29 insertions, 18 deletions
diff --git a/drivers/media/platform/ti-vps/vip.c b/drivers/media/platform/ti-vps/vip.c index 5ed03269818..0c07cc21157 100644 --- a/drivers/media/platform/ti-vps/vip.c +++ b/drivers/media/platform/ti-vps/vip.c | |||
@@ -52,7 +52,7 @@ MODULE_VERSION("0.1"); | |||
52 | 52 | ||
53 | /* | 53 | /* |
54 | * Need a descriptor entry for each of up to 15 outputs, | 54 | * Need a descriptor entry for each of up to 15 outputs, |
55 | * and up to 2 control transfers. | 55 | * and up to 2 write descriptor. |
56 | */ | 56 | */ |
57 | #define VIP_DESC_LIST_SIZE (17 * sizeof(struct vpdma_dtd)) | 57 | #define VIP_DESC_LIST_SIZE (17 * sizeof(struct vpdma_dtd)) |
58 | 58 | ||
@@ -891,6 +891,7 @@ static void populate_desc_list(struct vip_stream *stream) | |||
891 | static void start_dma(struct vip_dev *dev, struct vip_buffer *buf) | 891 | static void start_dma(struct vip_dev *dev, struct vip_buffer *buf) |
892 | { | 892 | { |
893 | struct vpdma_data *vpdma = dev->shared->vpdma; | 893 | struct vpdma_data *vpdma = dev->shared->vpdma; |
894 | struct vpdma_dtd *write_dtd; | ||
894 | dma_addr_t dma_addr; | 895 | dma_addr_t dma_addr; |
895 | int drop_data; | 896 | int drop_data; |
896 | 897 | ||
@@ -912,8 +913,12 @@ static void start_dma(struct vip_dev *dev, struct vip_buffer *buf) | |||
912 | 913 | ||
913 | enable_irqs(dev, dev->slice_id); | 914 | enable_irqs(dev, dev->slice_id); |
914 | 915 | ||
916 | vpdma_buf_unmap(dev->shared->vpdma, &dev->desc_list.buf); | ||
917 | |||
915 | vpdma_update_dma_addr(dev->shared->vpdma, &dev->desc_list, | 918 | vpdma_update_dma_addr(dev->shared->vpdma, &dev->desc_list, |
916 | dma_addr, drop_data); | 919 | dma_addr, dev->write_desc, drop_data); |
920 | vpdma_buf_map(dev->shared->vpdma, &dev->desc_list.buf); | ||
921 | |||
917 | vpdma_submit_descs(dev->shared->vpdma, &dev->desc_list, dev->slice_id); | 922 | vpdma_submit_descs(dev->shared->vpdma, &dev->desc_list, dev->slice_id); |
918 | } | 923 | } |
919 | 924 | ||
@@ -1607,6 +1612,8 @@ static int vip_init_dev(struct vip_dev *dev) | |||
1607 | if (ret != 0) | 1612 | if (ret != 0) |
1608 | return ret; | 1613 | return ret; |
1609 | 1614 | ||
1615 | dev->write_desc = (struct vpdma_dtd *)dev->desc_list.buf.addr | ||
1616 | + 15; | ||
1610 | vip_set_clock_enable(dev, 1); | 1617 | vip_set_clock_enable(dev, 1); |
1611 | done: | 1618 | done: |
1612 | dev->num_ports++; | 1619 | dev->num_ports++; |
diff --git a/drivers/media/platform/ti-vps/vip.h b/drivers/media/platform/ti-vps/vip.h index 801b2279c1a..8cf04ef770d 100644 --- a/drivers/media/platform/ti-vps/vip.h +++ b/drivers/media/platform/ti-vps/vip.h | |||
@@ -92,6 +92,7 @@ struct vip_dev { | |||
92 | void __iomem *base; | 92 | void __iomem *base; |
93 | 93 | ||
94 | struct vpdma_desc_list desc_list; /* DMA descriptor list */ | 94 | struct vpdma_desc_list desc_list; /* DMA descriptor list */ |
95 | struct vpdma_dtd *write_desc; | ||
95 | void *desc_next; /* next unused desc_list addr */ | 96 | void *desc_next; /* next unused desc_list addr */ |
96 | struct list_head vip_bufs; /* vip_bufs to be DMAed */ | 97 | struct list_head vip_bufs; /* vip_bufs to be DMAed */ |
97 | struct vb2_alloc_ctx *alloc_ctx; | 98 | struct vb2_alloc_ctx *alloc_ctx; |
diff --git a/drivers/media/platform/ti-vps/vpdma.c b/drivers/media/platform/ti-vps/vpdma.c index 8e2340f616f..deb3193ffcc 100644 --- a/drivers/media/platform/ti-vps/vpdma.c +++ b/drivers/media/platform/ti-vps/vpdma.c | |||
@@ -313,7 +313,7 @@ void vpdma_buf_map(struct vpdma_data *vpdma, struct vpdma_buf *buf) | |||
313 | 313 | ||
314 | WARN_ON(buf->mapped != 0); | 314 | WARN_ON(buf->mapped != 0); |
315 | buf->dma_addr = dma_map_single(dev, buf->addr, buf->size, | 315 | buf->dma_addr = dma_map_single(dev, buf->addr, buf->size, |
316 | DMA_TO_DEVICE); | 316 | DMA_BIDIRECTIONAL); |
317 | buf->mapped = 1; | 317 | buf->mapped = 1; |
318 | WARN_ON(dma_mapping_error(dev, buf->dma_addr)); | 318 | WARN_ON(dma_mapping_error(dev, buf->dma_addr)); |
319 | } | 319 | } |
@@ -333,7 +333,8 @@ void vpdma_buf_unmap(struct vpdma_data *vpdma, struct vpdma_buf *buf) | |||
333 | } | 333 | } |
334 | 334 | ||
335 | if (buf->mapped) | 335 | if (buf->mapped) |
336 | dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE); | 336 | dma_unmap_single(dev, buf->dma_addr, buf->size, |
337 | DMA_BIDIRECTIONAL); | ||
337 | 338 | ||
338 | buf->mapped = 0; | 339 | buf->mapped = 0; |
339 | } | 340 | } |
@@ -420,24 +421,25 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, | |||
420 | EXPORT_SYMBOL(vpdma_submit_descs); | 421 | EXPORT_SYMBOL(vpdma_submit_descs); |
421 | 422 | ||
422 | void vpdma_update_dma_addr(struct vpdma_data *vpdma, | 423 | void vpdma_update_dma_addr(struct vpdma_data *vpdma, |
423 | struct vpdma_desc_list *list, dma_addr_t dma_addr, int drop) | 424 | struct vpdma_desc_list *list, dma_addr_t dma_addr, |
425 | struct vpdma_dtd *write_dtd, int drop) | ||
424 | { | 426 | { |
425 | struct vpdma_dtd *dtd = list->buf.addr; | 427 | struct vpdma_dtd *dtd = list->buf.addr; |
426 | unsigned int write_desc_addr; | 428 | dma_addr_t write_desc_addr; |
427 | 429 | int offset; | |
428 | vpdma_buf_unmap(vpdma, &list->buf); | ||
429 | 430 | ||
430 | dtd_set_start_addr(dtd, dma_addr); | 431 | dtd_set_start_addr(dtd, dma_addr); |
431 | 432 | ||
432 | if (drop) { | 433 | /* Calculate write address from the offset of write_dtd from start |
433 | write_desc_addr = virt_to_phys( | 434 | * of the list->buf |
434 | (struct vpdma_dtd *)list->buf.dma_addr + 2); | 435 | */ |
436 | offset = (void *)write_dtd - list->buf.addr; | ||
437 | write_desc_addr = list->buf.dma_addr + offset; | ||
435 | 438 | ||
439 | if (drop) | ||
436 | dtd_set_desc_write_addr(dtd, write_desc_addr, 1, 1, 0); | 440 | dtd_set_desc_write_addr(dtd, write_desc_addr, 1, 1, 0); |
437 | } else | 441 | else |
438 | dtd_set_desc_write_addr(dtd, 0, 0, 0, 0); | 442 | dtd_set_desc_write_addr(dtd, write_desc_addr, 1, 0, 0); |
439 | |||
440 | vpdma_buf_map(vpdma, &list->buf); | ||
441 | } | 443 | } |
442 | EXPORT_SYMBOL(vpdma_update_dma_addr); | 444 | EXPORT_SYMBOL(vpdma_update_dma_addr); |
443 | 445 | ||
diff --git a/drivers/media/platform/ti-vps/vpdma.h b/drivers/media/platform/ti-vps/vpdma.h index 30c1fc41a42..016f30a248e 100644 --- a/drivers/media/platform/ti-vps/vpdma.h +++ b/drivers/media/platform/ti-vps/vpdma.h | |||
@@ -28,7 +28,7 @@ struct vpdma_buf { | |||
28 | 28 | ||
29 | struct vpdma_desc_list { | 29 | struct vpdma_desc_list { |
30 | struct vpdma_buf buf; | 30 | struct vpdma_buf buf; |
31 | void *next; | 31 | void *next, *current_desc; |
32 | int type; | 32 | int type; |
33 | }; | 33 | }; |
34 | 34 | ||
@@ -203,7 +203,8 @@ void vpdma_free_desc_list(struct vpdma_desc_list *list); | |||
203 | int vpdma_submit_descs(struct vpdma_data *vpdma, | 203 | int vpdma_submit_descs(struct vpdma_data *vpdma, |
204 | struct vpdma_desc_list *list, int list_num); | 204 | struct vpdma_desc_list *list, int list_num); |
205 | void vpdma_update_dma_addr(struct vpdma_data *vpdma, | 205 | void vpdma_update_dma_addr(struct vpdma_data *vpdma, |
206 | struct vpdma_desc_list *list, dma_addr_t dma_addr, int drop); | 206 | struct vpdma_desc_list *list, dma_addr_t dma_addr, |
207 | struct vpdma_dtd *write_dtd, int drop); | ||
207 | 208 | ||
208 | void vpdma_enable_channel_3_irq(struct vpdma_data *vpdma, bool enable); | 209 | void vpdma_enable_channel_3_irq(struct vpdma_data *vpdma, bool enable); |
209 | void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr, | 210 | void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr, |
diff --git a/drivers/media/platform/ti-vps/vpdma_priv.h b/drivers/media/platform/ti-vps/vpdma_priv.h index a576463e2d0..3b949aec0b3 100644 --- a/drivers/media/platform/ti-vps/vpdma_priv.h +++ b/drivers/media/platform/ti-vps/vpdma_priv.h | |||
@@ -219,7 +219,7 @@ struct vpdma_dtd { | |||
219 | #define DTD_V_START_MASK 0xffff | 219 | #define DTD_V_START_MASK 0xffff |
220 | #define DTD_V_START_SHFT 0 | 220 | #define DTD_V_START_SHFT 0 |
221 | 221 | ||
222 | #define DTD_DESC_START_MASK 0xffe0 | 222 | #define DTD_DESC_START_MASK 0xffffffe0 |
223 | #define DTD_DESC_START_SHIFT 5 | 223 | #define DTD_DESC_START_SHIFT 5 |
224 | #define DTD_WRITE_DESC_MASK 0x01 | 224 | #define DTD_WRITE_DESC_MASK 0x01 |
225 | #define DTD_WRITE_DESC_SHIFT 2 | 225 | #define DTD_WRITE_DESC_SHIFT 2 |