2 * Copyright 2015 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
24 #define nvkm_vram(p) container_of((p), struct nvkm_vram, memory)
27 #include <core/memory.h>
28 #include <subdev/mmu.h>
31 struct nvkm_memory memory
;
34 struct nvkm_mm_node
*mn
;
38 nvkm_vram_map(struct nvkm_memory
*memory
, u64 offset
, struct nvkm_vmm
*vmm
,
39 struct nvkm_vma
*vma
, void *argv
, u32 argc
)
41 struct nvkm_vram
*vram
= nvkm_vram(memory
);
42 struct nvkm_vmm_map map
= {
43 .memory
= &vram
->memory
,
48 return nvkm_vmm_map(vmm
, vma
, argv
, argc
, &map
);
52 nvkm_vram_size(struct nvkm_memory
*memory
)
54 return (u64
)nvkm_mm_size(nvkm_vram(memory
)->mn
) << NVKM_RAM_MM_SHIFT
;
58 nvkm_vram_addr(struct nvkm_memory
*memory
)
60 struct nvkm_vram
*vram
= nvkm_vram(memory
);
61 if (!nvkm_mm_contiguous(vram
->mn
))
63 return (u64
)nvkm_mm_addr(vram
->mn
) << NVKM_RAM_MM_SHIFT
;
67 nvkm_vram_page(struct nvkm_memory
*memory
)
69 return nvkm_vram(memory
)->page
;
72 static enum nvkm_memory_target
73 nvkm_vram_target(struct nvkm_memory
*memory
)
75 return NVKM_MEM_TARGET_VRAM
;
79 nvkm_vram_dtor(struct nvkm_memory
*memory
)
81 struct nvkm_vram
*vram
= nvkm_vram(memory
);
82 struct nvkm_mm_node
*next
= vram
->mn
;
83 struct nvkm_mm_node
*node
;
84 mutex_lock(&vram
->ram
->fb
->subdev
.mutex
);
85 while ((node
= next
)) {
87 nvkm_mm_free(&vram
->ram
->vram
, &node
);
89 mutex_unlock(&vram
->ram
->fb
->subdev
.mutex
);
93 static const struct nvkm_memory_func
95 .dtor
= nvkm_vram_dtor
,
96 .target
= nvkm_vram_target
,
97 .page
= nvkm_vram_page
,
98 .addr
= nvkm_vram_addr
,
99 .size
= nvkm_vram_size
,
100 .map
= nvkm_vram_map
,
104 nvkm_ram_get(struct nvkm_device
*device
, u8 heap
, u8 type
, u8 rpage
, u64 size
,
105 bool contig
, bool back
, struct nvkm_memory
**pmemory
)
107 struct nvkm_ram
*ram
;
109 struct nvkm_mm_node
**node
, *r
;
110 struct nvkm_vram
*vram
;
111 u8 page
= max(rpage
, (u8
)NVKM_RAM_MM_SHIFT
);
112 u32 align
= (1 << page
) >> NVKM_RAM_MM_SHIFT
;
113 u32 max
= ALIGN(size
, 1 << page
) >> NVKM_RAM_MM_SHIFT
;
114 u32 min
= contig
? max
: align
;
117 if (!device
->fb
|| !(ram
= device
->fb
->ram
))
119 ram
= device
->fb
->ram
;
122 if (!(vram
= kzalloc(sizeof(*vram
), GFP_KERNEL
)))
124 nvkm_memory_ctor(&nvkm_vram
, &vram
->memory
);
127 *pmemory
= &vram
->memory
;
129 mutex_lock(&ram
->fb
->subdev
.mutex
);
133 ret
= nvkm_mm_tail(mm
, heap
, type
, max
, min
, align
, &r
);
135 ret
= nvkm_mm_head(mm
, heap
, type
, max
, min
, align
, &r
);
137 mutex_unlock(&ram
->fb
->subdev
.mutex
);
138 nvkm_memory_unref(pmemory
);
146 mutex_unlock(&ram
->fb
->subdev
.mutex
);
151 nvkm_ram_init(struct nvkm_ram
*ram
)
154 return ram
->func
->init(ram
);
159 nvkm_ram_del(struct nvkm_ram
**pram
)
161 struct nvkm_ram
*ram
= *pram
;
162 if (ram
&& !WARN_ON(!ram
->func
)) {
164 *pram
= ram
->func
->dtor(ram
);
165 nvkm_mm_fini(&ram
->vram
);
172 nvkm_ram_ctor(const struct nvkm_ram_func
*func
, struct nvkm_fb
*fb
,
173 enum nvkm_ram_type type
, u64 size
, struct nvkm_ram
*ram
)
175 static const char *name
[] = {
176 [NVKM_RAM_TYPE_UNKNOWN
] = "of unknown memory type",
177 [NVKM_RAM_TYPE_STOLEN
] = "stolen system memory",
178 [NVKM_RAM_TYPE_SGRAM
] = "SGRAM",
179 [NVKM_RAM_TYPE_SDRAM
] = "SDRAM",
180 [NVKM_RAM_TYPE_DDR1
] = "DDR1",
181 [NVKM_RAM_TYPE_DDR2
] = "DDR2",
182 [NVKM_RAM_TYPE_DDR3
] = "DDR3",
183 [NVKM_RAM_TYPE_GDDR2
] = "GDDR2",
184 [NVKM_RAM_TYPE_GDDR3
] = "GDDR3",
185 [NVKM_RAM_TYPE_GDDR4
] = "GDDR4",
186 [NVKM_RAM_TYPE_GDDR5
] = "GDDR5",
187 [NVKM_RAM_TYPE_GDDR5X
] = "GDDR5X",
188 [NVKM_RAM_TYPE_GDDR6
] = "GDDR6",
189 [NVKM_RAM_TYPE_HBM2
] = "HBM2",
191 struct nvkm_subdev
*subdev
= &fb
->subdev
;
194 nvkm_info(subdev
, "%d MiB %s\n", (int)(size
>> 20), name
[type
]);
200 if (!nvkm_mm_initialised(&ram
->vram
)) {
201 ret
= nvkm_mm_init(&ram
->vram
, NVKM_RAM_MM_NORMAL
, 0,
202 size
>> NVKM_RAM_MM_SHIFT
, 1);
211 nvkm_ram_new_(const struct nvkm_ram_func
*func
, struct nvkm_fb
*fb
,
212 enum nvkm_ram_type type
, u64 size
, struct nvkm_ram
**pram
)
214 if (!(*pram
= kzalloc(sizeof(**pram
), GFP_KERNEL
)))
216 return nvkm_ram_ctor(func
, fb
, type
, size
, *pram
);