2 * Copyright 2010 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.
27 #include "nouveau_drv.h"
28 #include "nouveau_vm.h"
30 struct nvc0_instmem_priv
{
31 struct nouveau_gpuobj
*bar1_pgd
;
32 struct nouveau_channel
*bar1
;
33 struct nouveau_gpuobj
*bar3_pgd
;
34 struct nouveau_channel
*bar3
;
38 nvc0_instmem_suspend(struct drm_device
*dev
)
40 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
42 dev_priv
->ramin_available
= false;
47 nvc0_instmem_resume(struct drm_device
*dev
)
49 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
50 struct nvc0_instmem_priv
*priv
= dev_priv
->engine
.instmem
.priv
;
52 nv_mask(dev
, 0x100c80, 0x00000001, 0x00000000);
53 nv_wr32(dev
, 0x001704, 0x80000000 | priv
->bar1
->ramin
->vinst
>> 12);
54 nv_wr32(dev
, 0x001714, 0xc0000000 | priv
->bar3
->ramin
->vinst
>> 12);
55 dev_priv
->ramin_available
= true;
59 nvc0_channel_del(struct nouveau_channel
**pchan
)
61 struct nouveau_channel
*chan
;
68 nouveau_vm_ref(NULL
, &chan
->vm
, NULL
);
69 if (drm_mm_initialized(&chan
->ramin_heap
))
70 drm_mm_takedown(&chan
->ramin_heap
);
71 nouveau_gpuobj_ref(NULL
, &chan
->ramin
);
76 nvc0_channel_new(struct drm_device
*dev
, u32 size
, struct nouveau_vm
*vm
,
77 struct nouveau_channel
**pchan
,
78 struct nouveau_gpuobj
*pgd
, u64 vm_size
)
80 struct nouveau_channel
*chan
;
83 chan
= kzalloc(sizeof(*chan
), GFP_KERNEL
);
88 ret
= nouveau_gpuobj_new(dev
, NULL
, size
, 0x1000, 0, &chan
->ramin
);
90 nvc0_channel_del(&chan
);
94 ret
= drm_mm_init(&chan
->ramin_heap
, 0x1000, size
- 0x1000);
96 nvc0_channel_del(&chan
);
100 ret
= nouveau_vm_ref(vm
, &chan
->vm
, NULL
);
102 nvc0_channel_del(&chan
);
106 nv_wo32(chan
->ramin
, 0x0200, lower_32_bits(pgd
->vinst
));
107 nv_wo32(chan
->ramin
, 0x0204, upper_32_bits(pgd
->vinst
));
108 nv_wo32(chan
->ramin
, 0x0208, lower_32_bits(vm_size
- 1));
109 nv_wo32(chan
->ramin
, 0x020c, upper_32_bits(vm_size
- 1));
116 nvc0_instmem_init(struct drm_device
*dev
)
118 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
119 struct nouveau_instmem_engine
*pinstmem
= &dev_priv
->engine
.instmem
;
120 struct pci_dev
*pdev
= dev
->pdev
;
121 struct nvc0_instmem_priv
*priv
;
122 struct nouveau_vm
*vm
= NULL
;
125 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
128 pinstmem
->priv
= priv
;
131 ret
= nouveau_vm_new(dev
, 0, pci_resource_len(pdev
, 3), 0,
136 ret
= nouveau_gpuobj_new(dev
, NULL
,
137 (pci_resource_len(pdev
, 3) >> 12) * 8, 0,
138 NVOBJ_FLAG_DONT_MAP
|
139 NVOBJ_FLAG_ZERO_ALLOC
,
140 &dev_priv
->bar3_vm
->pgt
[0].obj
[0]);
143 dev_priv
->bar3_vm
->pgt
[0].refcount
[0] = 1;
145 nv50_instmem_map(dev_priv
->bar3_vm
->pgt
[0].obj
[0]);
147 ret
= nouveau_gpuobj_new(dev
, NULL
, 0x8000, 4096,
148 NVOBJ_FLAG_ZERO_ALLOC
, &priv
->bar3_pgd
);
152 ret
= nouveau_vm_ref(dev_priv
->bar3_vm
, &vm
, priv
->bar3_pgd
);
155 nouveau_vm_ref(NULL
, &vm
, NULL
);
157 ret
= nvc0_channel_new(dev
, 8192, dev_priv
->bar3_vm
, &priv
->bar3
,
158 priv
->bar3_pgd
, pci_resource_len(dev
->pdev
, 3));
163 ret
= nouveau_vm_new(dev
, 0, pci_resource_len(pdev
, 1), 0, &vm
);
167 ret
= nouveau_gpuobj_new(dev
, NULL
, 0x8000, 4096,
168 NVOBJ_FLAG_ZERO_ALLOC
, &priv
->bar1_pgd
);
172 ret
= nouveau_vm_ref(vm
, &dev_priv
->bar1_vm
, priv
->bar1_pgd
);
175 nouveau_vm_ref(NULL
, &vm
, NULL
);
177 ret
= nvc0_channel_new(dev
, 8192, dev_priv
->bar1_vm
, &priv
->bar1
,
178 priv
->bar1_pgd
, pci_resource_len(dev
->pdev
, 1));
183 ret
= nouveau_vm_new(dev
, 0, (1ULL << 40), 0x0008000000ULL
,
188 nvc0_instmem_resume(dev
);
191 nvc0_instmem_takedown(dev
);
196 nvc0_instmem_takedown(struct drm_device
*dev
)
198 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
199 struct nvc0_instmem_priv
*priv
= dev_priv
->engine
.instmem
.priv
;
200 struct nouveau_vm
*vm
= NULL
;
202 nvc0_instmem_suspend(dev
);
204 nv_wr32(dev
, 0x1704, 0x00000000);
205 nv_wr32(dev
, 0x1714, 0x00000000);
207 nouveau_vm_ref(NULL
, &dev_priv
->chan_vm
, NULL
);
209 nvc0_channel_del(&priv
->bar1
);
210 nouveau_vm_ref(NULL
, &dev_priv
->bar1_vm
, priv
->bar1_pgd
);
211 nouveau_gpuobj_ref(NULL
, &priv
->bar1_pgd
);
213 nvc0_channel_del(&priv
->bar3
);
214 nouveau_vm_ref(dev_priv
->bar3_vm
, &vm
, NULL
);
215 nouveau_vm_ref(NULL
, &vm
, priv
->bar3_pgd
);
216 nouveau_gpuobj_ref(NULL
, &priv
->bar3_pgd
);
217 nouveau_gpuobj_ref(NULL
, &dev_priv
->bar3_vm
->pgt
[0].obj
[0]);
218 nouveau_vm_ref(NULL
, &dev_priv
->bar3_vm
, NULL
);
220 dev_priv
->engine
.instmem
.priv
= NULL
;