UAPI: (Scripted) Convert #include "..." to #include <path/...> in drivers/gpu/
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / gpu / drm / nouveau / nvc0_vram.c
CommitLineData
8984e046
BS
1/*
2 * Copyright 2010 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
760285e7 25#include <drm/drmP.h>
8984e046
BS
26#include "nouveau_drv.h"
27#include "nouveau_mm.h"
28
b5e2f076
BS
29/* 0 = unsupported
30 * 1 = non-compressed
31 * 3 = compressed
32 */
33static const u8 types[256] = {
34 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
35 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
38 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
12b6d9d8 46 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
b5e2f076
BS
47 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
48 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
49 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
50};
51
8984e046
BS
52bool
53nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
54{
b5e2f076
BS
55 u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
56 return likely((types[memtype] == 1));
8984e046
BS
57}
58
59int
60nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
d5f42394 61 u32 type, struct nouveau_mem **pmem)
8984e046
BS
62{
63 struct drm_nouveau_private *dev_priv = dev->dev_private;
987eec10 64 struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
8984e046 65 struct nouveau_mm_node *r;
d5f42394 66 struct nouveau_mem *mem;
8984e046
BS
67 int ret;
68
69 size >>= 12;
70 align >>= 12;
71 ncmin >>= 12;
72
d5f42394
BS
73 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
74 if (!mem)
8984e046
BS
75 return -ENOMEM;
76
d5f42394
BS
77 INIT_LIST_HEAD(&mem->regions);
78 mem->dev = dev_priv->dev;
8f7286f8 79 mem->memtype = (type & 0xff);
d5f42394 80 mem->size = size;
8984e046
BS
81
82 mutex_lock(&mm->mutex);
83 do {
84 ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r);
85 if (ret) {
86 mutex_unlock(&mm->mutex);
d5f42394 87 nv50_vram_del(dev, &mem);
8984e046
BS
88 return ret;
89 }
90
d5f42394 91 list_add_tail(&r->rl_entry, &mem->regions);
8984e046
BS
92 size -= r->length;
93 } while (size);
94 mutex_unlock(&mm->mutex);
95
d5f42394
BS
96 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
97 mem->offset = (u64)r->offset << 12;
98 *pmem = mem;
8984e046
BS
99 return 0;
100}
101
102int
103nvc0_vram_init(struct drm_device *dev)
104{
105 struct drm_nouveau_private *dev_priv = dev->dev_private;
24f246ac
BS
106 struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
107 const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
108 const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
29181d2f
BS
109 u32 parts = nv_rd32(dev, 0x022438);
110 u32 pmask = nv_rd32(dev, 0x022554);
aa650096
BS
111 u32 bsize = nv_rd32(dev, 0x10f20c);
112 u32 offset, length;
113 bool uniform = true;
d4547ed8 114 int ret, part;
8984e046 115
aa650096 116 NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
29181d2f 117 NV_DEBUG(dev, "parts 0x%08x mask 0x%08x\n", parts, pmask);
24f246ac 118
f3298532 119 dev_priv->vram_type = nouveau_mem_vbios_type(dev);
950c44b6 120 dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x10f200) & 0x00000004);
f3298532 121
aa650096 122 /* read amount of vram attached to each memory controller */
29181d2f
BS
123 for (part = 0; part < parts; part++) {
124 if (!(pmask & (1 << part))) {
125 u32 psize = nv_rd32(dev, 0x11020c + (part * 0x1000));
126 if (psize != bsize) {
127 if (psize < bsize)
128 bsize = psize;
129 uniform = false;
130 }
131
132 NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
133 dev_priv->vram_size += (u64)psize << 20;
aa650096 134 }
aa650096
BS
135 }
136
137 /* if all controllers have the same amount attached, there's no holes */
138 if (uniform) {
139 offset = rsvd_head;
140 length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
141 return nouveau_mm_init(&vram->mm, offset, length, 1);
142 }
24f246ac 143
aa650096
BS
144 /* otherwise, address lowest common amount from 0GiB */
145 ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1);
146 if (ret)
147 return ret;
148
149 /* and the rest starting from (8GiB + common_size) */
150 offset = (0x0200000000ULL >> 12) + (bsize << 8);
151 length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail;
152
153 ret = nouveau_mm_init(&vram->mm, offset, length, 0);
154 if (ret) {
155 nouveau_mm_fini(&vram->mm);
156 return ret;
157 }
158
159 return 0;
8984e046 160}