2 * Copyright 2017 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 #include "nouveau_mem.h"
23 #include "nouveau_drv.h"
24 #include "nouveau_bo.h"
26 #include <subdev/ltc.h>
28 #include <drm/ttm/ttm_bo_driver.h>
31 nouveau_mem_map(struct nouveau_mem
*mem
,
32 struct nvkm_vmm
*vmm
, struct nvkm_vma
*vma
)
34 nvkm_vm_map(vma
, mem
->_mem
);
39 nouveau_mem_fini(struct nouveau_mem
*mem
)
41 if (mem
->vma
[1].node
) {
42 nvkm_vm_unmap(&mem
->vma
[1]);
43 nvkm_vm_put(&mem
->vma
[1]);
45 if (mem
->vma
[0].node
) {
46 nvkm_vm_unmap(&mem
->vma
[0]);
47 nvkm_vm_put(&mem
->vma
[0]);
49 nvkm_memory_tags_put(&mem
->memory
, nvxx_device(&mem
->cli
->device
),
54 nouveau_mem_host(struct ttm_mem_reg
*reg
, struct ttm_dma_tt
*tt
)
56 struct nouveau_mem
*mem
= nouveau_mem(reg
);
57 struct nouveau_cli
*cli
= mem
->cli
;
59 if (mem
->kind
&& cli
->device
.info
.chipset
== 0x50)
60 mem
->comp
= mem
->kind
= 0;
62 if (cli
->device
.info
.chipset
>= 0xc0)
63 mem
->kind
= gf100_pte_storage_type_map
[mem
->kind
];
67 mem
->__mem
.size
= (reg
->num_pages
<< PAGE_SHIFT
) >> 12;
68 mem
->__mem
.memtype
= (mem
->comp
<< 7) | mem
->kind
;
69 if (tt
->ttm
.sg
) mem
->__mem
.sg
= tt
->ttm
.sg
;
70 else mem
->__mem
.pages
= tt
->dma_address
;
71 mem
->_mem
= &mem
->__mem
;
73 mem
->_mem
->memory
= &mem
->memory
;
77 #include <subdev/fb/nv50.h>
80 struct nvkm_memory memory
;
83 struct nvkm_mm_node
*mn
;
87 nouveau_mem_vram(struct ttm_mem_reg
*reg
, bool contig
, u8 page
)
89 struct nouveau_mem
*mem
= nouveau_mem(reg
);
90 struct nouveau_cli
*cli
= mem
->cli
;
91 struct nvkm_device
*device
= nvxx_device(&cli
->device
);
92 u64 size
= ALIGN(reg
->num_pages
<< PAGE_SHIFT
, 1 << page
);
97 mem
->_mem
= &mem
->__mem
;
99 if (cli
->device
.info
.chipset
< 0xc0) {
100 type
= nv50_fb_memtype
[mem
->kind
];
103 mem
->kind
= gf100_pte_storage_type_map
[mem
->kind
];
108 ret
= nvkm_ram_get(device
, NVKM_RAM_MM_NORMAL
, type
, page
, size
,
109 contig
, false, &mem
->_mem
->memory
);
113 mem
->_mem
->size
= size
>> NVKM_RAM_MM_SHIFT
;
114 mem
->_mem
->offset
= nvkm_memory_addr(mem
->_mem
->memory
);
116 if (cli
->device
.info
.chipset
< 0xc0 && mem
->comp
) {
118 ret
= nvkm_memory_tags_get(mem
->_mem
->memory
, device
,
123 if (!mem
->tags
|| !mem
->tags
->mn
)
126 if (cli
->device
.info
.chipset
>= 0xc0 &&
127 gf100_pte_storage_type_map
[mem
->kind
] != mem
->kind
) {
129 ret
= nvkm_memory_tags_get(mem
->_mem
->memory
, device
,
135 if (!mem
->tags
|| !mem
->tags
->mn
)
136 mem
->kind
= gf100_pte_storage_type_map
[mem
->kind
];
139 if (mem
->tags
&& mem
->tags
->mn
)
140 mem
->_mem
->tag
= mem
->tags
->mn
;
141 mem
->_mem
->mem
= ((struct nvkm_vram
*)mem
->_mem
->memory
)->mn
;
142 mem
->_mem
->memtype
= (mem
->comp
<< 7) | mem
->kind
;
144 reg
->start
= mem
->_mem
->offset
>> PAGE_SHIFT
;
149 nouveau_mem_del(struct ttm_mem_reg
*reg
)
151 struct nouveau_mem
*mem
= nouveau_mem(reg
);
152 nouveau_mem_fini(mem
);
157 static enum nvkm_memory_target
158 nouveau_mem_memory_target(struct nvkm_memory
*memory
)
160 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
162 return NVKM_MEM_TARGET_VRAM
;
163 return NVKM_MEM_TARGET_HOST
;
167 nouveau_mem_memory_page(struct nvkm_memory
*memory
)
169 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
170 return mem
->mem
.page
;
174 nouveau_mem_memory_size(struct nvkm_memory
*memory
)
176 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
177 return mem
->_mem
->size
<< 12;
180 static const struct nvkm_memory_func
181 nouveau_mem_memory
= {
182 .target
= nouveau_mem_memory_target
,
183 .page
= nouveau_mem_memory_page
,
184 .size
= nouveau_mem_memory_size
,
188 nouveau_mem_new(struct nouveau_cli
*cli
, u8 kind
, u8 comp
,
189 struct ttm_mem_reg
*reg
)
191 struct nouveau_mem
*mem
;
193 if (!(mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
)))
198 nvkm_memory_ctor(&nouveau_mem_memory
, &mem
->memory
);