diff --git a/drivers/media/platform/ti/vpe/vpdma.c b/drivers/media/platform/ti/vpe/vpdma.c index bb8a8bd7980c..29ee1918bc1c 100644 --- a/drivers/media/platform/ti/vpe/vpdma.c +++ b/drivers/media/platform/ti/vpe/vpdma.c @@ -552,6 +552,54 @@ EXPORT_SYMBOL(vpdma_submit_descs); static void dump_dtd(struct vpdma_dtd *dtd); +/** + * vpdma_update_dma_addr() - update DMA address in a descriptor + * @vpdma: VPDMA device context + * @list: vpdma desc list to which we add this descriptor + * @dma_addr: new DMA address to program into the descriptor + * @write_dtd: descriptor pointer used to compute write-back address + * @drop: if true, set the drop bit in the write descriptor + * @idx: index of the descriptor in the list to update + * + * Updates dma addresses of the descriptor at @idx in @list. + * This allows reusing an existing descriptor list with a new buffer + * address, instead of rebuilding the list, which is needed when + * multiple clients share the same VPDMA engine. The list buffer is + * unmapped before the update and remapped after. + */ +void vpdma_update_dma_addr(struct vpdma_data *vpdma, + struct vpdma_desc_list *list, + dma_addr_t dma_addr, + void *write_dtd, int drop, int idx) +{ + struct vpdma_dtd *dtd = list->buf.addr; + dma_addr_t write_desc_addr; + int offset; + + dtd += idx; + vpdma_unmap_desc_buf(vpdma, &list->buf); + + dtd->start_addr = dma_addr; + + /* Calculate write address from the offset of write_dtd from start + * of the list->buf + */ + offset = (void *)write_dtd - list->buf.addr; + write_desc_addr = list->buf.dma_addr + offset; + + if (drop) + dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr, + 1, 1, 0); + else + dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr, + 1, 0, 0); + + vpdma_map_desc_buf(vpdma, &list->buf); + + dump_dtd(dtd); +} +EXPORT_SYMBOL_GPL(vpdma_update_dma_addr); + void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr, u32 width, u32 height) { diff --git a/drivers/media/platform/ti/vpe/vpdma.h b/drivers/media/platform/ti/vpe/vpdma.h index e4d7941c6207..5b3a0cd49a3c 100644 --- a/drivers/media/platform/ti/vpe/vpdma.h +++ b/drivers/media/platform/ti/vpe/vpdma.h @@ -222,6 +222,9 @@ void vpdma_free_desc_list(struct vpdma_desc_list *list); int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list, int list_num); bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num); +void vpdma_update_dma_addr(struct vpdma_data *vpdma, + struct vpdma_desc_list *list, dma_addr_t dma_addr, + void *write_dtd, int drop, int idx); /* VPDMA hardware list funcs */ int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);