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.
26 #include "nouveau_drv.h"
27 #include "nouveau_mm.h"
29 static int types
[0x80] = {
30 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
32 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
35 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
37 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
41 nv50_vram_flags_valid(struct drm_device
*dev
, u32 tile_flags
)
43 int type
= (tile_flags
& NOUVEAU_GEM_TILE_LAYOUT_MASK
) >> 8;
45 if (likely(type
< ARRAY_SIZE(types
) && types
[type
]))
51 nv50_vram_del(struct drm_device
*dev
, struct nouveau_mem
**pmem
)
53 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
54 struct ttm_bo_device
*bdev
= &dev_priv
->ttm
.bdev
;
55 struct ttm_mem_type_manager
*man
= &bdev
->man
[TTM_PL_VRAM
];
56 struct nouveau_mm
*mm
= man
->priv
;
57 struct nouveau_mm_node
*this;
58 struct nouveau_mem
*mem
;
62 if (unlikely(mem
== NULL
))
65 mutex_lock(&mm
->mutex
);
66 while (!list_empty(&mem
->regions
)) {
67 this = list_first_entry(&mem
->regions
, struct nouveau_mm_node
, rl_entry
);
69 list_del(&this->rl_entry
);
70 nouveau_mm_put(mm
, this);
74 drm_mm_put_block(mem
->tag
);
77 mutex_unlock(&mm
->mutex
);
83 nv50_vram_new(struct drm_device
*dev
, u64 size
, u32 align
, u32 size_nc
,
84 u32 memtype
, struct nouveau_mem
**pmem
)
86 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
87 struct ttm_bo_device
*bdev
= &dev_priv
->ttm
.bdev
;
88 struct ttm_mem_type_manager
*man
= &bdev
->man
[TTM_PL_VRAM
];
89 struct nouveau_mm
*mm
= man
->priv
;
90 struct nouveau_mm_node
*r
;
91 struct nouveau_mem
*mem
;
92 int comp
= (memtype
& 0x300) >> 8;
93 int type
= (memtype
& 0x07f);
102 mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
);
106 mutex_lock(&mm
->mutex
);
109 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
110 int n
= (size
>> 4) * comp
;
112 mem
->tag
= drm_mm_search_free(&pfb
->tag_heap
, n
, 0, 0);
114 mem
->tag
= drm_mm_get_block(mem
->tag
, n
, 0);
117 if (unlikely(!mem
->tag
))
121 INIT_LIST_HEAD(&mem
->regions
);
122 mem
->dev
= dev_priv
->dev
;
123 mem
->memtype
= (comp
<< 7) | type
;
127 ret
= nouveau_mm_get(mm
, types
[type
], size
, size_nc
, align
, &r
);
129 mutex_unlock(&mm
->mutex
);
130 nv50_vram_del(dev
, &mem
);
134 list_add_tail(&r
->rl_entry
, &mem
->regions
);
137 mutex_unlock(&mm
->mutex
);
139 r
= list_first_entry(&mem
->regions
, struct nouveau_mm_node
, rl_entry
);
140 mem
->offset
= (u64
)r
->offset
<< 12;
146 nv50_vram_rblock(struct drm_device
*dev
)
148 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
149 int i
, parts
, colbits
, rowbitsa
, rowbitsb
, banks
;
150 u64 rowsize
, predicted
;
151 u32 r0
, r4
, rt
, ru
, rblock_size
;
153 r0
= nv_rd32(dev
, 0x100200);
154 r4
= nv_rd32(dev
, 0x100204);
155 rt
= nv_rd32(dev
, 0x100250);
156 ru
= nv_rd32(dev
, 0x001540);
157 NV_DEBUG(dev
, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0
, r4
, rt
, ru
);
159 for (i
= 0, parts
= 0; i
< 8; i
++) {
160 if (ru
& (0x00010000 << i
))
164 colbits
= (r4
& 0x0000f000) >> 12;
165 rowbitsa
= ((r4
& 0x000f0000) >> 16) + 8;
166 rowbitsb
= ((r4
& 0x00f00000) >> 20) + 8;
167 banks
= ((r4
& 0x01000000) ? 8 : 4);
169 rowsize
= parts
* banks
* (1 << colbits
) * 8;
170 predicted
= rowsize
<< rowbitsa
;
172 predicted
+= rowsize
<< rowbitsb
;
174 if (predicted
!= dev_priv
->vram_size
) {
175 NV_WARN(dev
, "memory controller reports %dMiB VRAM\n",
176 (u32
)(dev_priv
->vram_size
>> 20));
177 NV_WARN(dev
, "we calculated %dMiB VRAM\n",
178 (u32
)(predicted
>> 20));
181 rblock_size
= rowsize
;
185 NV_DEBUG(dev
, "rblock %d bytes\n", rblock_size
);
190 nv50_vram_init(struct drm_device
*dev
)
192 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
194 dev_priv
->vram_size
= nv_rd32(dev
, 0x10020c);
195 dev_priv
->vram_size
|= (dev_priv
->vram_size
& 0xff) << 32;
196 dev_priv
->vram_size
&= 0xffffffff00ULL
;
198 switch (dev_priv
->chipset
) {
202 dev_priv
->vram_sys_base
= (u64
)nv_rd32(dev
, 0x100e10) << 12;
203 dev_priv
->vram_rblock_size
= 4096;
206 dev_priv
->vram_rblock_size
= nv50_vram_rblock(dev
);