UAPI: (Scripted) Convert #include "..." to #include <path/...> in drivers/gpu/
[GitHub/mt8127/android_kernel_alcatel_ttab.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 }