Skip to content

Commit ea2c11a

Browse files
yaroslavrospelwell
authored andcommitted
Ported pcie-brcmstb bounce buffer implementation to ARM64. (#3144)
Ported pcie-brcmstb bounce buffer implementation to ARM64. This enables full 4G RAM usage on Raspberry Pi in 64-bit mode. Signed-off-by: Yaroslav Rosomakho <[email protected]>
1 parent c0e4ca1 commit ea2c11a

File tree

6 files changed

+658
-24
lines changed

6 files changed

+658
-24
lines changed

arch/arm64/include/asm/dma-mapping.h

+21
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,27 @@
2424
#include <xen/xen.h>
2525
#include <asm/xen/hypervisor.h>
2626

27+
extern void *arm64_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
28+
gfp_t gfp, unsigned long attrs);
29+
extern void arm64_dma_free(struct device *dev, size_t size, void *cpu_addr,
30+
dma_addr_t handle, unsigned long attrs);
31+
extern int arm64_dma_mmap(struct device *dev, struct vm_area_struct *vma,
32+
void *cpu_addr, dma_addr_t dma_addr, size_t size,
33+
unsigned long attrs);
34+
extern int arm64_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
35+
void *cpu_addr, dma_addr_t dma_addr, size_t size,
36+
unsigned long attrs);
37+
extern int arm64_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nelems,
38+
enum dma_data_direction dir, unsigned long attrs);
39+
extern void arm64_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int,
40+
enum dma_data_direction dir, unsigned long attrs);
41+
extern void arm64_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nelems,
42+
enum dma_data_direction dir);
43+
extern void arm64_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nelems,
44+
enum dma_data_direction dir);
45+
46+
47+
2748
extern const struct dma_map_ops dummy_dma_ops;
2849

2950
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)

arch/arm64/mm/dma-mapping.c

+50
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ static void *__dma_alloc(struct device *dev, size_t size,
138138
return NULL;
139139
}
140140

141+
void *arm64_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
142+
gfp_t gfp, unsigned long attrs)
143+
{
144+
return __dma_alloc(dev, size, handle, gfp, attrs);
145+
}
146+
141147
static void __dma_free(struct device *dev, size_t size,
142148
void *vaddr, dma_addr_t dma_handle,
143149
unsigned long attrs)
@@ -154,6 +160,12 @@ static void __dma_free(struct device *dev, size_t size,
154160
swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs);
155161
}
156162

163+
void arm64_dma_free(struct device *dev, size_t size, void *cpu_addr,
164+
dma_addr_t handle, unsigned long attrs)
165+
{
166+
__dma_free(dev, size, cpu_addr, handle, attrs);
167+
}
168+
157169
static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
158170
unsigned long offset, size_t size,
159171
enum dma_data_direction dir,
@@ -197,6 +209,12 @@ static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
197209
return ret;
198210
}
199211

212+
int arm64_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nelems,
213+
enum dma_data_direction dir, unsigned long attrs)
214+
{
215+
return __swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
216+
}
217+
200218
static void __swiotlb_unmap_sg_attrs(struct device *dev,
201219
struct scatterlist *sgl, int nelems,
202220
enum dma_data_direction dir,
@@ -213,6 +231,12 @@ static void __swiotlb_unmap_sg_attrs(struct device *dev,
213231
swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs);
214232
}
215233

234+
void arm64_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nelems,
235+
enum dma_data_direction dir, unsigned long attrs)
236+
{
237+
__swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs);
238+
}
239+
216240
static void __swiotlb_sync_single_for_cpu(struct device *dev,
217241
dma_addr_t dev_addr, size_t size,
218242
enum dma_data_direction dir)
@@ -245,6 +269,12 @@ static void __swiotlb_sync_sg_for_cpu(struct device *dev,
245269
swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir);
246270
}
247271

272+
void arm64_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nelems,
273+
enum dma_data_direction dir)
274+
{
275+
__swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir);
276+
}
277+
248278
static void __swiotlb_sync_sg_for_device(struct device *dev,
249279
struct scatterlist *sgl, int nelems,
250280
enum dma_data_direction dir)
@@ -259,6 +289,12 @@ static void __swiotlb_sync_sg_for_device(struct device *dev,
259289
sg->length, dir);
260290
}
261291

292+
void arm64_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nelems,
293+
enum dma_data_direction dir)
294+
{
295+
__swiotlb_sync_sg_for_device(dev, sgl, nelems, dir);
296+
}
297+
262298
static int __swiotlb_mmap_pfn(struct vm_area_struct *vma,
263299
unsigned long pfn, size_t size)
264300
{
@@ -294,6 +330,13 @@ static int __swiotlb_mmap(struct device *dev,
294330
return __swiotlb_mmap_pfn(vma, pfn, size);
295331
}
296332

333+
int arm64_dma_mmap(struct device *dev, struct vm_area_struct *vma,
334+
void *cpu_addr, dma_addr_t dma_addr, size_t size,
335+
unsigned long attrs)
336+
{
337+
return __swiotlb_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
338+
}
339+
297340
static int __swiotlb_get_sgtable_page(struct sg_table *sgt,
298341
struct page *page, size_t size)
299342
{
@@ -314,6 +357,13 @@ static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
314357
return __swiotlb_get_sgtable_page(sgt, page, size);
315358
}
316359

360+
int arm64_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
361+
void *cpu_addr, dma_addr_t dma_addr, size_t size,
362+
unsigned long attrs)
363+
{
364+
return __swiotlb_get_sgtable(dev, sgt, cpu_addr, dma_addr, size, attrs);
365+
}
366+
317367
static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
318368
{
319369
if (swiotlb)

drivers/pci/controller/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
3232
ifdef CONFIG_ARM
3333
obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce.o
3434
endif
35+
ifdef CONFIG_ARM64
36+
obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce64.o
37+
endif
3538

3639
obj-$(CONFIG_VMD) += vmd.o
3740
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW

drivers/pci/controller/pcie-brcmstb-bounce.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#ifndef _PCIE_BRCMSTB_BOUNCE_H
77
#define _PCIE_BRCMSTB_BOUNCE_H
88

9-
#ifdef CONFIG_ARM
9+
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
1010

1111
int brcm_pcie_bounce_init(struct device *dev, unsigned long buffer_size,
1212
dma_addr_t threshold);

0 commit comments

Comments
 (0)