Lines Matching +full:udma +full:- +full:c
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
6 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
7 Copyright (C) 2005-2007 Hans Verkuil <[email protected]>
11 #include "ivtv-driver.h"
12 #include "ivtv-udma.h"
16 dma_page->uaddr = first & PAGE_MASK; in ivtv_udma_get_page_info()
17 dma_page->offset = first & ~PAGE_MASK; in ivtv_udma_get_page_info()
18 dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK); in ivtv_udma_get_page_info()
19 dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT; in ivtv_udma_get_page_info()
20 dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT; in ivtv_udma_get_page_info()
21 dma_page->page_count = dma_page->last - dma_page->first + 1; in ivtv_udma_get_page_info()
22 if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset; in ivtv_udma_get_page_info()
33 offset = dma_page->offset; in ivtv_udma_fill_sg_list()
36 for (i = 0; i < dma_page->page_count; i++) { in ivtv_udma_fill_sg_list()
37 unsigned int len = (i == dma_page->page_count - 1) ? in ivtv_udma_fill_sg_list()
38 dma_page->tail : PAGE_SIZE - offset; in ivtv_udma_fill_sg_list()
40 if (PageHighMem(dma->map[map_offset])) { in ivtv_udma_fill_sg_list()
43 if (dma->bouncemap[map_offset] == NULL) in ivtv_udma_fill_sg_list()
44 dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL); in ivtv_udma_fill_sg_list()
45 if (dma->bouncemap[map_offset] == NULL) in ivtv_udma_fill_sg_list()
46 return -1; in ivtv_udma_fill_sg_list()
48 src = kmap_atomic(dma->map[map_offset]) + offset; in ivtv_udma_fill_sg_list()
49 memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len); in ivtv_udma_fill_sg_list()
52 sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset); in ivtv_udma_fill_sg_list()
55 sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset); in ivtv_udma_fill_sg_list()
67 for_each_sg(dma->SGlist, sg, dma->SG_length, i) { in ivtv_udma_fill_sg_array()
68 dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg)); in ivtv_udma_fill_sg_array()
69 dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg)); in ivtv_udma_fill_sg_array()
70 dma->SGarray[i].dst = cpu_to_le32(buffer_offset); in ivtv_udma_fill_sg_array()
73 split -= sg_dma_len(sg); in ivtv_udma_fill_sg_array()
82 if (itv->udma.SG_handle == 0) { in ivtv_udma_alloc()
84 itv->udma.SG_handle = dma_map_single(&itv->pdev->dev, in ivtv_udma_alloc()
85 itv->udma.SGarray, in ivtv_udma_alloc()
86 sizeof(itv->udma.SGarray), in ivtv_udma_alloc()
96 struct ivtv_user_dma *dma = &itv->udma; in ivtv_udma_setup()
102 if (dma->SG_length || dma->page_count) { in ivtv_udma_setup()
104 dma->SG_length, dma->page_count); in ivtv_udma_setup()
105 return -EBUSY; in ivtv_udma_setup()
113 return -EINVAL; in ivtv_udma_setup()
118 dma->map, 0); in ivtv_udma_setup()
124 unpin_user_pages(dma->map, err); in ivtv_udma_setup()
125 return -EINVAL; in ivtv_udma_setup()
130 dma->page_count = user_dma.page_count; in ivtv_udma_setup()
136 unpin_user_pages(dma->map, dma->page_count); in ivtv_udma_setup()
137 dma->page_count = 0; in ivtv_udma_setup()
138 return -ENOMEM; in ivtv_udma_setup()
142 dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist, in ivtv_udma_setup()
143 dma->page_count, DMA_TO_DEVICE); in ivtv_udma_setup()
144 if (!dma->SG_length) { in ivtv_udma_setup()
146 unpin_user_pages(dma->map, dma->page_count); in ivtv_udma_setup()
147 dma->page_count = 0; in ivtv_udma_setup()
148 return -EINVAL; in ivtv_udma_setup()
152 ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); in ivtv_udma_setup()
155 dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000); in ivtv_udma_setup()
158 return dma->page_count; in ivtv_udma_setup()
163 struct ivtv_user_dma *dma = &itv->udma; in ivtv_udma_unmap()
168 if (dma->page_count == 0) in ivtv_udma_unmap()
172 if (dma->SG_length) { in ivtv_udma_unmap()
173 dma_unmap_sg(&itv->pdev->dev, dma->SGlist, dma->page_count, in ivtv_udma_unmap()
175 dma->SG_length = 0; in ivtv_udma_unmap()
180 unpin_user_pages(dma->map, dma->page_count); in ivtv_udma_unmap()
181 dma->page_count = 0; in ivtv_udma_unmap()
189 if (itv->udma.SG_handle) { in ivtv_udma_free()
190 dma_unmap_single(&itv->pdev->dev, itv->udma.SG_handle, in ivtv_udma_free()
191 sizeof(itv->udma.SGarray), DMA_TO_DEVICE); in ivtv_udma_free()
195 if (itv->udma.SG_length) { in ivtv_udma_free()
196 dma_unmap_sg(&itv->pdev->dev, itv->udma.SGlist, in ivtv_udma_free()
197 itv->udma.page_count, DMA_TO_DEVICE); in ivtv_udma_free()
201 if (itv->udma.bouncemap[i]) in ivtv_udma_free()
202 __free_page(itv->udma.bouncemap[i]); in ivtv_udma_free()
208 IVTV_DEBUG_DMA("start UDMA\n"); in ivtv_udma_start()
209 write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR); in ivtv_udma_start()
211 set_bit(IVTV_F_I_DMA, &itv->i_flags); in ivtv_udma_start()
212 set_bit(IVTV_F_I_UDMA, &itv->i_flags); in ivtv_udma_start()
213 clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); in ivtv_udma_start()
220 spin_lock_irqsave(&itv->dma_reg_lock, flags); in ivtv_udma_prepare()
221 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) in ivtv_udma_prepare()
224 set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags); in ivtv_udma_prepare()
225 spin_unlock_irqrestore(&itv->dma_reg_lock, flags); in ivtv_udma_prepare()