17a7d9a89SMauro Carvalho Chehab /*
20705135eSGuennadi Liakhovetski  * helper functions for SG DMA video4linux capture buffers
37a7d9a89SMauro Carvalho Chehab  *
45d6aaf50SMagnus Damm  * The functions expect the hardware being able to scatter gather
57a7d9a89SMauro Carvalho Chehab  * (i.e. the buffers are not linear in physical memory, but fragmented
67a7d9a89SMauro Carvalho Chehab  * into PAGE_SIZE chunks).  They also assume the driver does not need
77a7d9a89SMauro Carvalho Chehab  * to touch the video data.
87a7d9a89SMauro Carvalho Chehab  *
97a7d9a89SMauro Carvalho Chehab  * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
107a7d9a89SMauro Carvalho Chehab  *
117a7d9a89SMauro Carvalho Chehab  * Highly based on video-buf written originally by:
127a7d9a89SMauro Carvalho Chehab  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
137a7d9a89SMauro Carvalho Chehab  * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
147a7d9a89SMauro Carvalho Chehab  * (c) 2006 Ted Walther and John Sokol
157a7d9a89SMauro Carvalho Chehab  *
167a7d9a89SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or modify
177a7d9a89SMauro Carvalho Chehab  * it under the terms of the GNU General Public License as published by
187a7d9a89SMauro Carvalho Chehab  * the Free Software Foundation; either version 2
197a7d9a89SMauro Carvalho Chehab  */
207a02264cSPawel Osciak #ifndef _VIDEOBUF_DMA_SG_H
217a02264cSPawel Osciak #define _VIDEOBUF_DMA_SG_H
227a7d9a89SMauro Carvalho Chehab 
237a7d9a89SMauro Carvalho Chehab #include <media/videobuf-core.h>
247a7d9a89SMauro Carvalho Chehab 
257a7d9a89SMauro Carvalho Chehab /* --------------------------------------------------------------------- */
267a7d9a89SMauro Carvalho Chehab 
277a7d9a89SMauro Carvalho Chehab /*
287a7d9a89SMauro Carvalho Chehab  * A small set of helper functions to manage buffers (both userland
297a7d9a89SMauro Carvalho Chehab  * and kernel) for DMA.
307a7d9a89SMauro Carvalho Chehab  *
317a7d9a89SMauro Carvalho Chehab  * videobuf_dma_init_*()
327a7d9a89SMauro Carvalho Chehab  *	creates a buffer.  The userland version takes a userspace
337a7d9a89SMauro Carvalho Chehab  *	pointer + length.  The kernel version just wants the size and
347a7d9a89SMauro Carvalho Chehab  *	does memory allocation too using vmalloc_32().
357a7d9a89SMauro Carvalho Chehab  *
367a7d9a89SMauro Carvalho Chehab  * videobuf_dma_*()
375872fb94SRandy Dunlap  *	see Documentation/PCI/PCI-DMA-mapping.txt, these functions to
387a7d9a89SMauro Carvalho Chehab  *	basically the same.  The map function does also build a
397a7d9a89SMauro Carvalho Chehab  *	scatterlist for the buffer (and unmap frees it ...)
407a7d9a89SMauro Carvalho Chehab  *
417a7d9a89SMauro Carvalho Chehab  * videobuf_dma_free()
427a7d9a89SMauro Carvalho Chehab  *	no comment ...
437a7d9a89SMauro Carvalho Chehab  *
447a7d9a89SMauro Carvalho Chehab  */
457a7d9a89SMauro Carvalho Chehab 
467a7d9a89SMauro Carvalho Chehab struct videobuf_dmabuf {
477a7d9a89SMauro Carvalho Chehab 	u32                 magic;
487a7d9a89SMauro Carvalho Chehab 
497a7d9a89SMauro Carvalho Chehab 	/* for userland buffer */
507a7d9a89SMauro Carvalho Chehab 	int                 offset;
512fc11536SHans Verkuil 	size_t		    size;
527a7d9a89SMauro Carvalho Chehab 	struct page         **pages;
537a7d9a89SMauro Carvalho Chehab 
547a7d9a89SMauro Carvalho Chehab 	/* for kernel buffers */
55bb6dbe74SLaurent Pinchart 	void                *vaddr;
567a7d9a89SMauro Carvalho Chehab 
577a7d9a89SMauro Carvalho Chehab 	/* for overlay buffers (pci-pci dma) */
587a7d9a89SMauro Carvalho Chehab 	dma_addr_t          bus_addr;
597a7d9a89SMauro Carvalho Chehab 
607a7d9a89SMauro Carvalho Chehab 	/* common */
617a7d9a89SMauro Carvalho Chehab 	struct scatterlist  *sglist;
627a7d9a89SMauro Carvalho Chehab 	int                 sglen;
637a7d9a89SMauro Carvalho Chehab 	int                 nr_pages;
647a7d9a89SMauro Carvalho Chehab 	int                 direction;
657a7d9a89SMauro Carvalho Chehab };
667a7d9a89SMauro Carvalho Chehab 
677a02264cSPawel Osciak struct videobuf_dma_sg_memory {
687a7d9a89SMauro Carvalho Chehab 	u32                 magic;
697a7d9a89SMauro Carvalho Chehab 
707a7d9a89SMauro Carvalho Chehab 	/* for mmap'ed buffers */
717a7d9a89SMauro Carvalho Chehab 	struct videobuf_dmabuf  dma;
727a7d9a89SMauro Carvalho Chehab };
737a7d9a89SMauro Carvalho Chehab 
7495268403SLaurent Pinchart /*
7595268403SLaurent Pinchart  * Scatter-gather DMA buffer API.
7695268403SLaurent Pinchart  *
7795268403SLaurent Pinchart  * These functions provide a simple way to create a page list and a
7895268403SLaurent Pinchart  * scatter-gather list from a kernel, userspace of physical address and map the
7995268403SLaurent Pinchart  * memory for DMA operation.
8095268403SLaurent Pinchart  *
8195268403SLaurent Pinchart  * Despite the name, this is totally unrelated to videobuf, except that
8295268403SLaurent Pinchart  * videobuf-dma-sg uses the same API internally.
8395268403SLaurent Pinchart  */
847a7d9a89SMauro Carvalho Chehab void videobuf_dma_init(struct videobuf_dmabuf *dma);
857a7d9a89SMauro Carvalho Chehab int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
867a7d9a89SMauro Carvalho Chehab 			   unsigned long data, unsigned long size);
877a7d9a89SMauro Carvalho Chehab int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
887a7d9a89SMauro Carvalho Chehab 			     int nr_pages);
897a7d9a89SMauro Carvalho Chehab int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
907a7d9a89SMauro Carvalho Chehab 			      dma_addr_t addr, int nr_pages);
917a7d9a89SMauro Carvalho Chehab int videobuf_dma_free(struct videobuf_dmabuf *dma);
927a7d9a89SMauro Carvalho Chehab 
9395268403SLaurent Pinchart int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma);
9495268403SLaurent Pinchart int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma);
957a7d9a89SMauro Carvalho Chehab struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
967a7d9a89SMauro Carvalho Chehab 
970705135eSGuennadi Liakhovetski void *videobuf_sg_alloc(size_t size);
987a7d9a89SMauro Carvalho Chehab 
990705135eSGuennadi Liakhovetski void videobuf_queue_sg_init(struct videobuf_queue *q,
10038a54f35SJonathan Corbet 			 const struct videobuf_queue_ops *ops,
1010705135eSGuennadi Liakhovetski 			 struct device *dev,
1027a7d9a89SMauro Carvalho Chehab 			 spinlock_t *irqlock,
1037a7d9a89SMauro Carvalho Chehab 			 enum v4l2_buf_type type,
1047a7d9a89SMauro Carvalho Chehab 			 enum v4l2_field field,
1057a7d9a89SMauro Carvalho Chehab 			 unsigned int msize,
1067a7d9a89SMauro Carvalho Chehab 			 void *priv);
1077a7d9a89SMauro Carvalho Chehab 
1087a02264cSPawel Osciak #endif /* _VIDEOBUF_DMA_SG_H */
1097a02264cSPawel Osciak 
110