UAPI: (Scripted) Convert #include "..." to #include <path/...> in drivers/gpu/
[pandora-kernel.git] / drivers / gpu / drm / nouveau / nv20_fb.c
1 #include <drm/drmP.h>
2 #include "nouveau_drv.h"
3 #include <drm/nouveau_drm.h>
4
5 static struct drm_mm_node *
6 nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size)
7 {
8         struct drm_nouveau_private *dev_priv = dev->dev_private;
9         struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
10         struct drm_mm_node *mem;
11         int ret;
12
13         ret = drm_mm_pre_get(&pfb->tag_heap);
14         if (ret)
15                 return NULL;
16
17         spin_lock(&dev_priv->tile.lock);
18         mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0);
19         if (mem)
20                 mem = drm_mm_get_block_atomic(mem, size, 0);
21         spin_unlock(&dev_priv->tile.lock);
22
23         return mem;
24 }
25
26 static void
27 nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem)
28 {
29         struct drm_nouveau_private *dev_priv = dev->dev_private;
30         struct drm_mm_node *mem = *pmem;
31         if (mem) {
32                 spin_lock(&dev_priv->tile.lock);
33                 drm_mm_put_block(mem);
34                 spin_unlock(&dev_priv->tile.lock);
35                 *pmem = NULL;
36         }
37 }
38
39 void
40 nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
41                          uint32_t size, uint32_t pitch, uint32_t flags)
42 {
43         struct drm_nouveau_private *dev_priv = dev->dev_private;
44         struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
45         int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16);
46
47         tile->addr  = 0x00000001 | addr;
48         tile->limit = max(1u, addr + size) - 1;
49         tile->pitch = pitch;
50
51         /* Allocate some of the on-die tag memory, used to store Z
52          * compression meta-data (most likely just a bitmap determining
53          * if a given tile is compressed or not).
54          */
55         if (flags & NOUVEAU_GEM_TILE_ZETA) {
56                 tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256);
57                 if (tile->tag_mem) {
58                         /* Enable Z compression */
59                         tile->zcomp = tile->tag_mem->start;
60                         if (dev_priv->chipset >= 0x25) {
61                                 if (bpp == 16)
62                                         tile->zcomp |= NV25_PFB_ZCOMP_MODE_16;
63                                 else
64                                         tile->zcomp |= NV25_PFB_ZCOMP_MODE_32;
65                         } else {
66                                 tile->zcomp |= NV20_PFB_ZCOMP_EN;
67                                 if (bpp != 16)
68                                         tile->zcomp |= NV20_PFB_ZCOMP_MODE_32;
69                         }
70                 }
71
72                 tile->addr |= 2;
73         }
74 }
75
76 void
77 nv20_fb_free_tile_region(struct drm_device *dev, int i)
78 {
79         struct drm_nouveau_private *dev_priv = dev->dev_private;
80         struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
81
82         tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
83         nv20_fb_free_tag(dev, &tile->tag_mem);
84 }
85
86 void
87 nv20_fb_set_tile_region(struct drm_device *dev, int i)
88 {
89         struct drm_nouveau_private *dev_priv = dev->dev_private;
90         struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
91
92         nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
93         nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
94         nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
95         nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp);
96 }
97
98 int
99 nv20_fb_vram_init(struct drm_device *dev)
100 {
101         struct drm_nouveau_private *dev_priv = dev->dev_private;
102         u32 mem_size = nv_rd32(dev, 0x10020c);
103         u32 pbus1218 = nv_rd32(dev, 0x001218);
104
105         dev_priv->vram_size = mem_size & 0xff000000;
106         switch (pbus1218 & 0x00000300) {
107         case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break;
108         case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
109         case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
110         case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break;
111         }
112
113         return 0;
114 }
115
116 int
117 nv20_fb_init(struct drm_device *dev)
118 {
119         struct drm_nouveau_private *dev_priv = dev->dev_private;
120         struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
121         int i;
122
123         if (dev_priv->chipset >= 0x25)
124                 drm_mm_init(&pfb->tag_heap, 0, 64 * 1024);
125         else
126                 drm_mm_init(&pfb->tag_heap, 0, 32 * 1024);
127
128         /* Turn all the tiling regions off. */
129         pfb->num_tiles = NV10_PFB_TILE__SIZE;
130         for (i = 0; i < pfb->num_tiles; i++)
131                 pfb->set_tile_region(dev, i);
132
133         return 0;
134 }
135
136 void
137 nv20_fb_takedown(struct drm_device *dev)
138 {
139         struct drm_nouveau_private *dev_priv = dev->dev_private;
140         struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
141         int i;
142
143         for (i = 0; i < pfb->num_tiles; i++)
144                 pfb->free_tile_region(dev, i);
145
146         drm_mm_takedown(&pfb->tag_heap);
147 }