3 #include "nouveau_drv.h"
4 #include "nouveau_drm.h"
6 static struct drm_mm_node
*
7 nv20_fb_alloc_tag(struct drm_device
*dev
, uint32_t size
)
9 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
10 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
11 struct drm_mm_node
*mem
;
14 ret
= drm_mm_pre_get(&pfb
->tag_heap
);
18 spin_lock(&dev_priv
->tile
.lock
);
19 mem
= drm_mm_search_free(&pfb
->tag_heap
, size
, 0, 0);
21 mem
= drm_mm_get_block_atomic(mem
, size
, 0);
22 spin_unlock(&dev_priv
->tile
.lock
);
28 nv20_fb_free_tag(struct drm_device
*dev
, struct drm_mm_node
**pmem
)
30 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
31 struct drm_mm_node
*mem
= *pmem
;
33 spin_lock(&dev_priv
->tile
.lock
);
34 drm_mm_put_block(mem
);
35 spin_unlock(&dev_priv
->tile
.lock
);
41 nv20_fb_init_tile_region(struct drm_device
*dev
, int i
, uint32_t addr
,
42 uint32_t size
, uint32_t pitch
, uint32_t flags
)
44 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
45 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
46 int bpp
= (flags
& NOUVEAU_GEM_TILE_32BPP
? 32 : 16);
48 tile
->addr
= 0x00000001 | addr
;
49 tile
->limit
= max(1u, addr
+ size
) - 1;
52 /* Allocate some of the on-die tag memory, used to store Z
53 * compression meta-data (most likely just a bitmap determining
54 * if a given tile is compressed or not).
56 if (flags
& NOUVEAU_GEM_TILE_ZETA
) {
57 tile
->tag_mem
= nv20_fb_alloc_tag(dev
, size
/ 256);
59 /* Enable Z compression */
60 tile
->zcomp
= tile
->tag_mem
->start
;
61 if (dev_priv
->chipset
>= 0x25) {
63 tile
->zcomp
|= NV25_PFB_ZCOMP_MODE_16
;
65 tile
->zcomp
|= NV25_PFB_ZCOMP_MODE_32
;
67 tile
->zcomp
|= NV20_PFB_ZCOMP_EN
;
69 tile
->zcomp
|= NV20_PFB_ZCOMP_MODE_32
;
78 nv20_fb_free_tile_region(struct drm_device
*dev
, int i
)
80 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
81 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
83 tile
->addr
= tile
->limit
= tile
->pitch
= tile
->zcomp
= 0;
84 nv20_fb_free_tag(dev
, &tile
->tag_mem
);
88 nv20_fb_set_tile_region(struct drm_device
*dev
, int i
)
90 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
91 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
93 nv_wr32(dev
, NV10_PFB_TLIMIT(i
), tile
->limit
);
94 nv_wr32(dev
, NV10_PFB_TSIZE(i
), tile
->pitch
);
95 nv_wr32(dev
, NV10_PFB_TILE(i
), tile
->addr
);
96 nv_wr32(dev
, NV20_PFB_ZCOMP(i
), tile
->zcomp
);
100 nv20_fb_vram_init(struct drm_device
*dev
)
102 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
103 u32 mem_size
= nv_rd32(dev
, 0x10020c);
104 u32 pbus1218
= nv_rd32(dev
, 0x001218);
106 dev_priv
->vram_size
= mem_size
& 0xff000000;
107 switch (pbus1218
& 0x00000300) {
108 case 0x00000000: dev_priv
->vram_type
= NV_MEM_TYPE_SDRAM
; break;
109 case 0x00000100: dev_priv
->vram_type
= NV_MEM_TYPE_DDR1
; break;
110 case 0x00000200: dev_priv
->vram_type
= NV_MEM_TYPE_GDDR3
; break;
111 case 0x00000300: dev_priv
->vram_type
= NV_MEM_TYPE_GDDR2
; break;
118 nv20_fb_init(struct drm_device
*dev
)
120 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
121 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
124 if (dev_priv
->chipset
>= 0x25)
125 drm_mm_init(&pfb
->tag_heap
, 0, 64 * 1024);
127 drm_mm_init(&pfb
->tag_heap
, 0, 32 * 1024);
129 /* Turn all the tiling regions off. */
130 pfb
->num_tiles
= NV10_PFB_TILE__SIZE
;
131 for (i
= 0; i
< pfb
->num_tiles
; i
++)
132 pfb
->set_tile_region(dev
, i
);
138 nv20_fb_takedown(struct drm_device
*dev
)
140 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
141 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
144 for (i
= 0; i
< pfb
->num_tiles
; i
++)
145 pfb
->free_tile_region(dev
, i
);
147 drm_mm_takedown(&pfb
->tag_heap
);