forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/arch/hexagon/kernel/dma.c
....@@ -1,49 +1,23 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * DMA implementation for Hexagon
34 *
45 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 and
8
- * only version 2 as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
- * 02110-1301, USA.
196 */
207
21
-#include <linux/dma-mapping.h>
22
-#include <linux/dma-direct.h>
23
-#include <linux/bootmem.h>
8
+#include <linux/dma-map-ops.h>
9
+#include <linux/memblock.h>
2410 #include <linux/genalloc.h>
25
-#include <asm/dma-mapping.h>
2611 #include <linux/module.h>
2712 #include <asm/page.h>
28
-
29
-#define HEXAGON_MAPPING_ERROR 0
30
-
31
-const struct dma_map_ops *dma_ops;
32
-EXPORT_SYMBOL(dma_ops);
33
-
34
-static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
35
-{
36
- return phys_to_virt((unsigned long) dma_addr);
37
-}
3813
3914 static struct gen_pool *coherent_pool;
4015
4116
4217 /* Allocates from a pool of uncached memory that was reserved at boot time */
4318
44
-static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
45
- dma_addr_t *dma_addr, gfp_t flag,
46
- unsigned long attrs)
19
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
20
+ gfp_t flag, unsigned long attrs)
4721 {
4822 void *ret;
4923
....@@ -75,58 +49,17 @@
7549 return ret;
7650 }
7751
78
-static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr,
79
- dma_addr_t dma_addr, unsigned long attrs)
52
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
53
+ dma_addr_t dma_addr, unsigned long attrs)
8054 {
8155 gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
8256 }
8357
84
-static int check_addr(const char *name, struct device *hwdev,
85
- dma_addr_t bus, size_t size)
58
+void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
59
+ enum dma_data_direction dir)
8660 {
87
- if (hwdev && hwdev->dma_mask && !dma_capable(hwdev, bus, size)) {
88
- if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
89
- printk(KERN_ERR
90
- "%s: overflow %Lx+%zu of device mask %Lx\n",
91
- name, (long long)bus, size,
92
- (long long)*hwdev->dma_mask);
93
- return 0;
94
- }
95
- return 1;
96
-}
61
+ void *addr = phys_to_virt(paddr);
9762
98
-static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg,
99
- int nents, enum dma_data_direction dir,
100
- unsigned long attrs)
101
-{
102
- struct scatterlist *s;
103
- int i;
104
-
105
- WARN_ON(nents == 0 || sg[0].length == 0);
106
-
107
- for_each_sg(sg, s, nents, i) {
108
- s->dma_address = sg_phys(s);
109
- if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
110
- return 0;
111
-
112
- s->dma_length = s->length;
113
-
114
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
115
- continue;
116
-
117
- flush_dcache_range(dma_addr_to_virt(s->dma_address),
118
- dma_addr_to_virt(s->dma_address + s->length));
119
- }
120
-
121
- return nents;
122
-}
123
-
124
-/*
125
- * address is virtual
126
- */
127
-static inline void dma_sync(void *addr, size_t size,
128
- enum dma_data_direction dir)
129
-{
13063 switch (dir) {
13164 case DMA_TO_DEVICE:
13265 hexagon_clean_dcache_range((unsigned long) addr,
....@@ -143,77 +76,4 @@
14376 default:
14477 BUG();
14578 }
146
-}
147
-
148
-/**
149
- * hexagon_map_page() - maps an address for device DMA
150
- * @dev: pointer to DMA device
151
- * @page: pointer to page struct of DMA memory
152
- * @offset: offset within page
153
- * @size: size of memory to map
154
- * @dir: transfer direction
155
- * @attrs: pointer to DMA attrs (not used)
156
- *
157
- * Called to map a memory address to a DMA address prior
158
- * to accesses to/from device.
159
- *
160
- * We don't particularly have many hoops to jump through
161
- * so far. Straight translation between phys and virtual.
162
- *
163
- * DMA is not cache coherent so sync is necessary; this
164
- * seems to be a convenient place to do it.
165
- *
166
- */
167
-static dma_addr_t hexagon_map_page(struct device *dev, struct page *page,
168
- unsigned long offset, size_t size,
169
- enum dma_data_direction dir,
170
- unsigned long attrs)
171
-{
172
- dma_addr_t bus = page_to_phys(page) + offset;
173
- WARN_ON(size == 0);
174
-
175
- if (!check_addr("map_single", dev, bus, size))
176
- return HEXAGON_MAPPING_ERROR;
177
-
178
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
179
- dma_sync(dma_addr_to_virt(bus), size, dir);
180
-
181
- return bus;
182
-}
183
-
184
-static void hexagon_sync_single_for_cpu(struct device *dev,
185
- dma_addr_t dma_handle, size_t size,
186
- enum dma_data_direction dir)
187
-{
188
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
189
-}
190
-
191
-static void hexagon_sync_single_for_device(struct device *dev,
192
- dma_addr_t dma_handle, size_t size,
193
- enum dma_data_direction dir)
194
-{
195
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
196
-}
197
-
198
-static int hexagon_mapping_error(struct device *dev, dma_addr_t dma_addr)
199
-{
200
- return dma_addr == HEXAGON_MAPPING_ERROR;
201
-}
202
-
203
-const struct dma_map_ops hexagon_dma_ops = {
204
- .alloc = hexagon_dma_alloc_coherent,
205
- .free = hexagon_free_coherent,
206
- .map_sg = hexagon_map_sg,
207
- .map_page = hexagon_map_page,
208
- .sync_single_for_cpu = hexagon_sync_single_for_cpu,
209
- .sync_single_for_device = hexagon_sync_single_for_device,
210
- .mapping_error = hexagon_mapping_error,
211
-};
212
-
213
-void __init hexagon_dma_init(void)
214
-{
215
- if (dma_ops)
216
- return;
217
-
218
- dma_ops = &hexagon_dma_ops;
21979 }