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);