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
;
78 nouveau_mem_vram(struct ttm_mem_reg
*reg
, bool contig
, u8 page
)
80 struct nouveau_mem
*mem
= nouveau_mem(reg
);
81 struct nouveau_cli
*cli
= mem
->cli
;
82 struct nvkm_device
*device
= nvxx_device(&cli
->device
);
83 struct nvkm_ram
*ram
= nvxx_fb(&cli
->device
)->ram
;
84 u64 size
= ALIGN(reg
->num_pages
<< PAGE_SHIFT
, 1 << page
);
88 mem
->_mem
->memory
= &mem
->memory
;
90 if (cli
->device
.info
.chipset
< 0xc0 && mem
->comp
) {
92 ret
= nvkm_memory_tags_get(mem
->_mem
->memory
, device
,
97 if (!mem
->tags
|| !mem
->tags
->mn
)
100 if (cli
->device
.info
.chipset
>= 0xc0 &&
101 gf100_pte_storage_type_map
[mem
->kind
] != mem
->kind
) {
103 ret
= nvkm_memory_tags_get(mem
->_mem
->memory
, device
,
109 if (!mem
->tags
|| !mem
->tags
->mn
)
110 mem
->kind
= gf100_pte_storage_type_map
[mem
->kind
];
113 ret
= ram
->func
->get(ram
, size
, 1 << page
, contig
? 0 : 1 << page
,
114 (mem
->comp
<< 8) | mem
->kind
, &mem
->_mem
);
116 nvkm_memory_tags_put(mem
->_mem
->memory
, device
, &mem
->tags
);
120 if (mem
->tags
&& mem
->tags
->mn
)
121 mem
->_mem
->tag
= mem
->tags
->mn
;
123 reg
->start
= mem
->_mem
->offset
>> PAGE_SHIFT
;
128 nouveau_mem_del(struct ttm_mem_reg
*reg
)
130 struct nouveau_mem
*mem
= nouveau_mem(reg
);
131 nouveau_mem_fini(mem
);
136 static enum nvkm_memory_target
137 nouveau_mem_memory_target(struct nvkm_memory
*memory
)
139 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
141 return NVKM_MEM_TARGET_VRAM
;
142 return NVKM_MEM_TARGET_HOST
;
146 nouveau_mem_memory_page(struct nvkm_memory
*memory
)
148 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
149 return mem
->mem
.page
;
153 nouveau_mem_memory_size(struct nvkm_memory
*memory
)
155 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
156 return mem
->_mem
->size
<< 12;
159 static const struct nvkm_memory_func
160 nouveau_mem_memory
= {
161 .target
= nouveau_mem_memory_target
,
162 .page
= nouveau_mem_memory_page
,
163 .size
= nouveau_mem_memory_size
,
167 nouveau_mem_new(struct nouveau_cli
*cli
, u8 kind
, u8 comp
,
168 struct ttm_mem_reg
*reg
)
170 struct nouveau_mem
*mem
;
172 if (!(mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
)))
177 nvkm_memory_ctor(&nouveau_mem_memory
, &mem
->memory
);