blob: 27d92e826bac530b0309ffd2635374e2327749f1 [file] [log] [blame]
Lee Leahyeef40eb2017-03-23 10:54:57 -07001/*
2 * Generic bounce buffer implementation
3 *
4 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
5 * Copyright 2013 Google Inc. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Lee Leahy48dbc662017-05-08 16:56:03 -070018#ifndef __COMMONLIB_STORAGE_BOUNCEBUF_H__
19#define __COMMONLIB_STORAGE_BOUNCEBUF_H__
Lee Leahyeef40eb2017-03-23 10:54:57 -070020
21#include <stddef.h>
22#include <stdint.h>
23#include <stdlib.h>
24
25/*
26 * GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware.
27 * The source buffer is copied into the bounce buffer (if unaligned, otherwise
28 * the source buffer is used directly) upon start() call, then the operation
29 * requiring the aligned transfer happens, then the bounce buffer is lost upon
30 * stop() call.
31 */
32#define GEN_BB_READ (1 << 0)
33/*
34 * GEN_BB_WRITE -- Data are written into the buffer eg. by DMA hardware.
35 * The source buffer starts in an undefined state upon start() call, then the
36 * operation requiring the aligned transfer happens, then the bounce buffer is
37 * copied into the destination buffer (if unaligned, otherwise destination
38 * buffer is used directly) upon stop() call.
39 */
40#define GEN_BB_WRITE (1 << 1)
41/*
42 * GEN_BB_RW -- Data are read and written into the buffer eg. by DMA hardware.
43 * The source buffer is copied into the bounce buffer (if unaligned, otherwise
44 * the source buffer is used directly) upon start() call, then the operation
45 * requiring the aligned transfer happens, then the bounce buffer is copied
46 * into the destination buffer (if unaligned, otherwise destination buffer is
47 * used directly) upon stop() call.
48 */
49#define GEN_BB_RW (GEN_BB_READ | GEN_BB_WRITE)
50
51struct bounce_buffer {
52 /* Copy of data parameter passed to start() */
53 void *user_buffer;
54 /*
55 * DMA-aligned buffer. This field is always set to the value that
56 * should be used for DMA; either equal to .user_buffer, or to a
57 * freshly allocated aligned buffer.
58 */
59 void *bounce_buffer;
60 /* Copy of len parameter passed to start() */
61 size_t len;
62 /* DMA-aligned buffer length */
63 size_t len_aligned;
64 /* Copy of flags parameter passed to start() */
65 unsigned int flags;
66};
67
68/**
69 * bounce_buffer_start() -- Start the bounce buffer session
70 * state: stores state passed between bounce_buffer_{start,stop}
71 * data: pointer to buffer to be aligned
72 * len: length of the buffer
73 * flags: flags describing the transaction, see above.
74 */
75int bounce_buffer_start(struct bounce_buffer *state, void *data,
76 size_t len, unsigned int flags);
77/**
78 * bounce_buffer_stop() -- Finish the bounce buffer session
79 * state: stores state passed between bounce_buffer_{start,stop}
80 */
81int bounce_buffer_stop(struct bounce_buffer *state);
82
83// TODO(hungte) Eliminate the alignment stuff below and replace them with a
84// better and centralized way to handler non-cache/aligned memory.
85// Helper macros for alignment.
86#define DMA_MINALIGN (64)
87#define ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1))
88#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
89 char __##name[ROUND(size * sizeof(type), DMA_MINALIGN) + \
90 DMA_MINALIGN - 1]; \
91 type *name = (type *) ALIGN((uintptr_t)__##name, DMA_MINALIGN)
92#ifndef ARCH_DMA_MINALIGN
93#define ARCH_DMA_MINALIGN (DMA_MINALIGN)
94#endif
95
Lee Leahy48dbc662017-05-08 16:56:03 -070096#endif // __COMMONLIB_STORAGE_BOUNCEBUF_H__