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 <drm/ttm/ttm_bo_driver.h>
29 nouveau_mem_map(struct nouveau_mem
*mem
,
30 struct nvkm_vmm
*vmm
, struct nvkm_vma
*vma
)
32 nvkm_vm_map(vma
, mem
->_mem
);
37 nouveau_mem_fini(struct nouveau_mem
*mem
)
39 if (mem
->vma
[1].node
) {
40 nvkm_vm_unmap(&mem
->vma
[1]);
41 nvkm_vm_put(&mem
->vma
[1]);
43 if (mem
->vma
[0].node
) {
44 nvkm_vm_unmap(&mem
->vma
[0]);
45 nvkm_vm_put(&mem
->vma
[0]);
50 nouveau_mem_host(struct ttm_mem_reg
*reg
, struct ttm_dma_tt
*tt
)
52 struct nouveau_mem
*mem
= nouveau_mem(reg
);
53 struct nouveau_cli
*cli
= mem
->cli
;
55 if (mem
->kind
&& cli
->device
.info
.chipset
== 0x50)
56 mem
->comp
= mem
->kind
= 0;
58 if (cli
->device
.info
.chipset
>= 0xc0)
59 mem
->kind
= gf100_pte_storage_type_map
[mem
->kind
];
63 mem
->__mem
.size
= (reg
->num_pages
<< PAGE_SHIFT
) >> 12;
64 mem
->__mem
.memtype
= (mem
->comp
<< 7) | mem
->kind
;
65 if (tt
->ttm
.sg
) mem
->__mem
.sg
= tt
->ttm
.sg
;
66 else mem
->__mem
.pages
= tt
->dma_address
;
67 mem
->_mem
= &mem
->__mem
;
69 mem
->_mem
->memory
= &mem
->memory
;
74 nouveau_mem_vram(struct ttm_mem_reg
*reg
, bool contig
, u8 page
)
76 struct nouveau_mem
*mem
= nouveau_mem(reg
);
77 struct nvkm_ram
*ram
= nvxx_fb(&mem
->cli
->device
)->ram
;
78 u64 size
= ALIGN(reg
->num_pages
<< PAGE_SHIFT
, 1 << page
);
82 mem
->_mem
->memory
= &mem
->memory
;
84 ret
= ram
->func
->get(ram
, size
, 1 << page
, contig
? 0 : 1 << page
,
85 (mem
->comp
<< 8) | mem
->kind
, &mem
->_mem
);
89 reg
->start
= mem
->_mem
->offset
>> PAGE_SHIFT
;
94 nouveau_mem_del(struct ttm_mem_reg
*reg
)
96 struct nouveau_mem
*mem
= nouveau_mem(reg
);
97 nouveau_mem_fini(mem
);
102 static enum nvkm_memory_target
103 nouveau_mem_memory_target(struct nvkm_memory
*memory
)
105 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
107 return NVKM_MEM_TARGET_VRAM
;
108 return NVKM_MEM_TARGET_HOST
;
112 nouveau_mem_memory_page(struct nvkm_memory
*memory
)
114 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
115 return mem
->mem
.page
;
119 nouveau_mem_memory_size(struct nvkm_memory
*memory
)
121 struct nouveau_mem
*mem
= container_of(memory
, typeof(*mem
), memory
);
122 return mem
->_mem
->size
<< 12;
125 static const struct nvkm_memory_func
126 nouveau_mem_memory
= {
127 .target
= nouveau_mem_memory_target
,
128 .page
= nouveau_mem_memory_page
,
129 .size
= nouveau_mem_memory_size
,
133 nouveau_mem_new(struct nouveau_cli
*cli
, u8 kind
, u8 comp
,
134 struct ttm_mem_reg
*reg
)
136 struct nouveau_mem
*mem
;
138 if (!(mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
)))
143 nvkm_memory_ctor(&nouveau_mem_memory
, &mem
->memory
);