0001
0002 #ifndef __NVKM_MM_H__
0003 #define __NVKM_MM_H__
0004 #include <core/os.h>
0005
0006 struct nvkm_mm_node {
0007 struct list_head nl_entry;
0008 struct list_head fl_entry;
0009 struct nvkm_mm_node *next;
0010
0011 #define NVKM_MM_HEAP_ANY 0x00
0012 u8 heap;
0013 #define NVKM_MM_TYPE_NONE 0x00
0014 #define NVKM_MM_TYPE_HOLE 0xff
0015 u8 type;
0016 u32 offset;
0017 u32 length;
0018 };
0019
0020 struct nvkm_mm {
0021 struct list_head nodes;
0022 struct list_head free;
0023
0024 u32 block_size;
0025 int heap_nodes;
0026 };
0027
0028 static inline bool
0029 nvkm_mm_initialised(struct nvkm_mm *mm)
0030 {
0031 return mm->heap_nodes;
0032 }
0033
0034 int nvkm_mm_init(struct nvkm_mm *, u8 heap, u32 offset, u32 length, u32 block);
0035 int nvkm_mm_fini(struct nvkm_mm *);
0036 int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
0037 u32 size_min, u32 align, struct nvkm_mm_node **);
0038 int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
0039 u32 size_min, u32 align, struct nvkm_mm_node **);
0040 void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **);
0041 void nvkm_mm_dump(struct nvkm_mm *, const char *);
0042
0043 static inline u32
0044 nvkm_mm_heap_size(struct nvkm_mm *mm, u8 heap)
0045 {
0046 struct nvkm_mm_node *node;
0047 u32 size = 0;
0048 list_for_each_entry(node, &mm->nodes, nl_entry) {
0049 if (node->heap == heap)
0050 size += node->length;
0051 }
0052 return size;
0053 }
0054
0055 static inline bool
0056 nvkm_mm_contiguous(struct nvkm_mm_node *node)
0057 {
0058 return !node->next;
0059 }
0060
0061 static inline u32
0062 nvkm_mm_addr(struct nvkm_mm_node *node)
0063 {
0064 if (WARN_ON(!nvkm_mm_contiguous(node)))
0065 return 0;
0066 return node->offset;
0067 }
0068
0069 static inline u32
0070 nvkm_mm_size(struct nvkm_mm_node *node)
0071 {
0072 u32 size = 0;
0073 do {
0074 size += node->length;
0075 } while ((node = node->next));
0076 return size;
0077 }
0078 #endif