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"
30 nvc0_instmem_populate(struct drm_device
*dev
, struct nouveau_gpuobj
*gpuobj
,
35 *size
= ALIGN(*size
, 4096);
39 ret
= nouveau_bo_new(dev
, NULL
, *size
, 0, TTM_PL_FLAG_VRAM
, 0, 0x0000,
40 true, false, &gpuobj
->im_backing
);
42 NV_ERROR(dev
, "error getting PRAMIN backing pages: %d\n", ret
);
46 ret
= nouveau_bo_pin(gpuobj
->im_backing
, TTM_PL_FLAG_VRAM
);
48 NV_ERROR(dev
, "error pinning PRAMIN backing VRAM: %d\n", ret
);
49 nouveau_bo_ref(NULL
, &gpuobj
->im_backing
);
53 gpuobj
->im_backing_start
= gpuobj
->im_backing
->bo
.mem
.mm_node
->start
;
54 gpuobj
->im_backing_start
<<= PAGE_SHIFT
;
59 nvc0_instmem_clear(struct drm_device
*dev
, struct nouveau_gpuobj
*gpuobj
)
61 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
63 if (gpuobj
&& gpuobj
->im_backing
) {
65 dev_priv
->engine
.instmem
.unbind(dev
, gpuobj
);
66 nouveau_bo_unpin(gpuobj
->im_backing
);
67 nouveau_bo_ref(NULL
, &gpuobj
->im_backing
);
68 gpuobj
->im_backing
= NULL
;
73 nvc0_instmem_bind(struct drm_device
*dev
, struct nouveau_gpuobj
*gpuobj
)
75 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
76 uint32_t pte
, pte_end
;
79 if (!gpuobj
->im_backing
|| !gpuobj
->im_pramin
|| gpuobj
->im_bound
)
82 NV_DEBUG(dev
, "st=0x%lx sz=0x%lx\n",
83 gpuobj
->im_pramin
->start
, gpuobj
->im_pramin
->size
);
85 pte
= gpuobj
->im_pramin
->start
>> 12;
86 pte_end
= (gpuobj
->im_pramin
->size
>> 12) + pte
;
87 vram
= gpuobj
->im_backing_start
;
89 NV_DEBUG(dev
, "pramin=0x%lx, pte=%d, pte_end=%d\n",
90 gpuobj
->im_pramin
->start
, pte
, pte_end
);
91 NV_DEBUG(dev
, "first vram page: 0x%08x\n", gpuobj
->im_backing_start
);
93 while (pte
< pte_end
) {
94 nv_wr32(dev
, 0x702000 + (pte
* 8), (vram
>> 8) | 1);
95 nv_wr32(dev
, 0x702004 + (pte
* 8), 0);
99 dev_priv
->engine
.instmem
.flush(dev
);
102 u32 chan
= nv_rd32(dev
, 0x1700) << 16;
103 nv_wr32(dev
, 0x100cb8, (chan
+ 0x1000) >> 8);
104 nv_wr32(dev
, 0x100cbc, 0x80000005);
107 gpuobj
->im_bound
= 1;
112 nvc0_instmem_unbind(struct drm_device
*dev
, struct nouveau_gpuobj
*gpuobj
)
114 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
115 uint32_t pte
, pte_end
;
117 if (gpuobj
->im_bound
== 0)
120 pte
= gpuobj
->im_pramin
->start
>> 12;
121 pte_end
= (gpuobj
->im_pramin
->size
>> 12) + pte
;
122 while (pte
< pte_end
) {
123 nv_wr32(dev
, 0x702000 + (pte
* 8), 0);
124 nv_wr32(dev
, 0x702004 + (pte
* 8), 0);
127 dev_priv
->engine
.instmem
.flush(dev
);
129 gpuobj
->im_bound
= 0;
134 nvc0_instmem_flush(struct drm_device
*dev
)
136 nv_wr32(dev
, 0x070000, 1);
137 if (!nv_wait(0x070000, 0x00000002, 0x00000000))
138 NV_ERROR(dev
, "PRAMIN flush timeout\n");
142 nvc0_instmem_suspend(struct drm_device
*dev
)
144 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
147 dev_priv
->susres
.ramin_copy
= vmalloc(65536);
148 if (!dev_priv
->susres
.ramin_copy
)
151 for (i
= 0x700000; i
< 0x710000; i
+= 4)
152 dev_priv
->susres
.ramin_copy
[i
/4] = nv_rd32(dev
, i
);
157 nvc0_instmem_resume(struct drm_device
*dev
)
159 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
163 chan
= dev_priv
->vram_size
- dev_priv
->ramin_rsvd_vram
;
164 nv_wr32(dev
, 0x001700, chan
>> 16);
166 for (i
= 0x700000; i
< 0x710000; i
+= 4)
167 nv_wr32(dev
, i
, dev_priv
->susres
.ramin_copy
[i
/4]);
168 vfree(dev_priv
->susres
.ramin_copy
);
169 dev_priv
->susres
.ramin_copy
= NULL
;
171 nv_wr32(dev
, 0x001714, 0xc0000000 | (chan
>> 12));
175 nvc0_instmem_init(struct drm_device
*dev
)
177 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
178 u64 chan
, pgt3
, imem
, lim3
= dev_priv
->ramin_size
- 1;
181 dev_priv
->ramin_rsvd_vram
= 1 * 1024 * 1024;
182 chan
= dev_priv
->vram_size
- dev_priv
->ramin_rsvd_vram
;
183 imem
= 4096 + 4096 + 32768;
185 nv_wr32(dev
, 0x001700, chan
>> 16);
188 nv_wr32(dev
, 0x700200, lower_32_bits(chan
+ 0x1000));
189 nv_wr32(dev
, 0x700204, upper_32_bits(chan
+ 0x1000));
190 nv_wr32(dev
, 0x700208, lower_32_bits(lim3
));
191 nv_wr32(dev
, 0x70020c, upper_32_bits(lim3
));
193 /* point pgd -> pgt */
194 nv_wr32(dev
, 0x701000, 0);
195 nv_wr32(dev
, 0x701004, ((chan
+ 0x2000) >> 8) | 1);
197 /* point pgt -> physical vram for channel */
199 for (i
= 0; i
< dev_priv
->ramin_rsvd_vram
; i
+= 4096, pgt3
+= 8) {
200 nv_wr32(dev
, 0x700000 + pgt3
, ((chan
+ i
) >> 8) | 1);
201 nv_wr32(dev
, 0x700004 + pgt3
, 0);
204 /* clear rest of pgt */
205 for (; i
< dev_priv
->ramin_size
; i
+= 4096, pgt3
+= 8) {
206 nv_wr32(dev
, 0x700000 + pgt3
, 0);
207 nv_wr32(dev
, 0x700004 + pgt3
, 0);
210 /* point bar3 at the channel */
211 nv_wr32(dev
, 0x001714, 0xc0000000 | (chan
>> 12));
213 /* Global PRAMIN heap */
214 ret
= drm_mm_init(&dev_priv
->ramin_heap
, imem
,
215 dev_priv
->ramin_size
- imem
);
217 NV_ERROR(dev
, "Failed to init RAMIN heap\n");
221 /*XXX: incorrect, but needed to make hash func "work" */
222 dev_priv
->ramht_offset
= 0x10000;
223 dev_priv
->ramht_bits
= 9;
224 dev_priv
->ramht_size
= (1 << dev_priv
->ramht_bits
);
229 nvc0_instmem_takedown(struct drm_device
*dev
)
This page took 0.053731 seconds and 5 git commands to generate.