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
*mem
)
30 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
32 spin_lock(&dev_priv
->tile
.lock
);
33 drm_mm_put_block(mem
);
34 spin_unlock(&dev_priv
->tile
.lock
);
38 nv10_fb_init_tile_region(struct drm_device
*dev
, int i
, uint32_t addr
,
39 uint32_t size
, uint32_t pitch
, uint32_t flags
)
41 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
42 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
43 int bpp
= (flags
& NOUVEAU_GEM_TILE_32BPP
? 32 : 16);
46 tile
->limit
= max(1u, addr
+ size
) - 1;
49 if (dev_priv
->card_type
== NV_20
) {
50 if (flags
& NOUVEAU_GEM_TILE_ZETA
) {
52 * Allocate some of the on-die tag memory,
53 * used to store Z compression meta-data (most
54 * likely just a bitmap determining if a given
55 * tile is compressed or not).
57 tile
->tag_mem
= nv20_fb_alloc_tag(dev
, size
/ 256);
60 /* Enable Z compression */
61 if (dev_priv
->chipset
>= 0x25)
62 tile
->zcomp
= tile
->tag_mem
->start
|
64 NV25_PFB_ZCOMP_MODE_16
:
65 NV25_PFB_ZCOMP_MODE_32
);
67 tile
->zcomp
= tile
->tag_mem
->start
|
70 NV20_PFB_ZCOMP_MODE_32
);
79 tile
->addr
|= 1 << 31;
84 nv10_fb_free_tile_region(struct drm_device
*dev
, int i
)
86 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
87 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
90 nv20_fb_free_tag(dev
, tile
->tag_mem
);
94 tile
->addr
= tile
->limit
= tile
->pitch
= tile
->zcomp
= 0;
98 nv10_fb_set_tile_region(struct drm_device
*dev
, int i
)
100 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
101 struct nouveau_tile_reg
*tile
= &dev_priv
->tile
.reg
[i
];
103 nv_wr32(dev
, NV10_PFB_TLIMIT(i
), tile
->limit
);
104 nv_wr32(dev
, NV10_PFB_TSIZE(i
), tile
->pitch
);
105 nv_wr32(dev
, NV10_PFB_TILE(i
), tile
->addr
);
107 if (dev_priv
->card_type
== NV_20
)
108 nv_wr32(dev
, NV20_PFB_ZCOMP(i
), tile
->zcomp
);
112 nv10_fb_init(struct drm_device
*dev
)
114 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
115 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
118 pfb
->num_tiles
= NV10_PFB_TILE__SIZE
;
120 if (dev_priv
->card_type
== NV_20
)
121 drm_mm_init(&pfb
->tag_heap
, 0,
122 (dev_priv
->chipset
>= 0x25 ?
123 64 * 1024 : 32 * 1024));
125 /* Turn all the tiling regions off. */
126 for (i
= 0; i
< pfb
->num_tiles
; i
++)
127 pfb
->set_tile_region(dev
, i
);
133 nv10_fb_takedown(struct drm_device
*dev
)
135 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
136 struct nouveau_fb_engine
*pfb
= &dev_priv
->engine
.fb
;
139 for (i
= 0; i
< pfb
->num_tiles
; i
++)
140 pfb
->free_tile_region(dev
, i
);
142 if (dev_priv
->card_type
== NV_20
)
143 drm_mm_takedown(&pfb
->tag_heap
);