aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-17 13:57:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-17 13:57:59 -0500
commit584ef2cd70acb0e473ba51e1073c2c5c95a2d27a (patch)
tree8cbed7283567438fda8aea75a2ad4761acc6d826
parente1288cd72f54e7fc16ae9ebb4d0647537ef848d4 (diff)
parent25b2ec5b643c9ea784e5a51e5e9602cd536965f2 (diff)
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm/radeon/kms: balance asic_reset functions drm/radeon/kms: remove duplicate card_posted() functions drm/radeon/kms: add module option for pcie gen2 drm/radeon/kms: fix typo in evergreen safe reg drm/nouveau: fix gpu page faults triggered by plymouthd drm/nouveau: greatly simplify mm, killing some bugs in the process drm/nvc0: enable protection of system-use-only structures in vm drm/nv40: initialise 0x17xx on all chipsets that have it drm/nv40: make detection of 0x4097-ful chipsets available everywhere
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c26
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mm.c182
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mm.h4
-rw-r--r--drivers/gpu/drm/nouveau/nv40_graph.c3
-rw-r--r--drivers/gpu/drm/nouveau/nv40_grctx.c21
-rw-r--r--drivers/gpu/drm/nouveau/nv40_mc.c14
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_vm.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c30
-rw-r--r--drivers/gpu/drm/radeon/r100.c11
-rw-r--r--drivers/gpu/drm/radeon/r300.c11
-rw-r--r--drivers/gpu/drm/radeon/r600.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c16
-rw-r--r--drivers/gpu/drm/radeon/rv770.c5
20 files changed, 124 insertions, 262 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 46e32573b3a3..01bffc4412d2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -160,6 +160,7 @@ enum nouveau_flags {
160#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) 160#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
161#define NVOBJ_FLAG_ZERO_FREE (1 << 2) 161#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
162#define NVOBJ_FLAG_VM (1 << 3) 162#define NVOBJ_FLAG_VM (1 << 3)
163#define NVOBJ_FLAG_VM_USER (1 << 4)
163 164
164#define NVOBJ_CINST_GLOBAL 0xdeadbeef 165#define NVOBJ_CINST_GLOBAL 0xdeadbeef
165 166
@@ -1576,6 +1577,20 @@ nv_match_device(struct drm_device *dev, unsigned device,
1576 dev->pdev->subsystem_device == sub_device; 1577 dev->pdev->subsystem_device == sub_device;
1577} 1578}
1578 1579
1580/* returns 1 if device is one of the nv4x using the 0x4497 object class,
1581 * helpful to determine a number of other hardware features
1582 */
1583static inline int
1584nv44_graph_class(struct drm_device *dev)
1585{
1586 struct drm_nouveau_private *dev_priv = dev->dev_private;
1587
1588 if ((dev_priv->chipset & 0xf0) == 0x60)
1589 return 1;
1590
1591 return !(0x0baf & (1 << (dev_priv->chipset & 0x0f)));
1592}
1593
1579/* memory type/access flags, do not match hardware values */ 1594/* memory type/access flags, do not match hardware values */
1580#define NV_MEM_ACCESS_RO 1 1595#define NV_MEM_ACCESS_RO 1
1581#define NV_MEM_ACCESS_WO 2 1596#define NV_MEM_ACCESS_WO 2
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 6d56a54b6e2e..60769d2f9a66 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -352,8 +352,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
352 FBINFO_HWACCEL_IMAGEBLIT; 352 FBINFO_HWACCEL_IMAGEBLIT;
353 info->flags |= FBINFO_CAN_FORCE_OUTPUT; 353 info->flags |= FBINFO_CAN_FORCE_OUTPUT;
354 info->fbops = &nouveau_fbcon_sw_ops; 354 info->fbops = &nouveau_fbcon_sw_ops;
355 info->fix.smem_start = dev->mode_config.fb_base + 355 info->fix.smem_start = nvbo->bo.mem.bus.base +
356 (nvbo->bo.mem.start << PAGE_SHIFT); 356 nvbo->bo.mem.bus.offset;
357 info->fix.smem_len = size; 357 info->fix.smem_len = size;
358 358
359 info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); 359 info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 69044eb104bb..26347b7cd872 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -742,30 +742,24 @@ nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
742{ 742{
743 struct nouveau_mm *mm = man->priv; 743 struct nouveau_mm *mm = man->priv;
744 struct nouveau_mm_node *r; 744 struct nouveau_mm_node *r;
745 u64 total = 0, ttotal[3] = {}, tused[3] = {}, tfree[3] = {}; 745 u32 total = 0, free = 0;
746 int i;
747 746
748 mutex_lock(&mm->mutex); 747 mutex_lock(&mm->mutex);
749 list_for_each_entry(r, &mm->nodes, nl_entry) { 748 list_for_each_entry(r, &mm->nodes, nl_entry) {
750 printk(KERN_DEBUG "%s %s-%d: 0x%010llx 0x%010llx\n", 749 printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n",
751 prefix, r->free ? "free" : "used", r->type, 750 prefix, r->type, ((u64)r->offset << 12),
752 ((u64)r->offset << 12),
753 (((u64)r->offset + r->length) << 12)); 751 (((u64)r->offset + r->length) << 12));
752
754 total += r->length; 753 total += r->length;
755 ttotal[r->type] += r->length; 754 if (!r->type)
756 if (r->free) 755 free += r->length;
757 tfree[r->type] += r->length;
758 else
759 tused[r->type] += r->length;
760 } 756 }
761 mutex_unlock(&mm->mutex); 757 mutex_unlock(&mm->mutex);
762 758
763 printk(KERN_DEBUG "%s total: 0x%010llx\n", prefix, total << 12); 759 printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n",
764 for (i = 0; i < 3; i++) { 760 prefix, (u64)total << 12, (u64)free << 12);
765 printk(KERN_DEBUG "%s type %d: 0x%010llx, " 761 printk(KERN_DEBUG "%s block: 0x%08x\n",
766 "used 0x%010llx, free 0x%010llx\n", prefix, 762 prefix, mm->block_size << 12);
767 i, ttotal[i] << 12, tused[i] << 12, tfree[i] << 12);
768 }
769} 763}
770 764
771const struct ttm_mem_type_manager_func nouveau_vram_manager = { 765const struct ttm_mem_type_manager_func nouveau_vram_manager = {
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c
index cdbb11eb701b..8844b50c3e54 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.c
@@ -48,175 +48,76 @@ region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size)
48 48
49 b->offset = a->offset; 49 b->offset = a->offset;
50 b->length = size; 50 b->length = size;
51 b->free = a->free;
52 b->type = a->type; 51 b->type = a->type;
53 a->offset += size; 52 a->offset += size;
54 a->length -= size; 53 a->length -= size;
55 list_add_tail(&b->nl_entry, &a->nl_entry); 54 list_add_tail(&b->nl_entry, &a->nl_entry);
56 if (b->free) 55 if (b->type == 0)
57 list_add_tail(&b->fl_entry, &a->fl_entry); 56 list_add_tail(&b->fl_entry, &a->fl_entry);
58 return b; 57 return b;
59} 58}
60 59
61static struct nouveau_mm_node * 60#define node(root, dir) ((root)->nl_entry.dir == &rmm->nodes) ? NULL : \
62nouveau_mm_merge(struct nouveau_mm *rmm, struct nouveau_mm_node *this) 61 list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
63{
64 struct nouveau_mm_node *prev, *next;
65
66 /* try to merge with free adjacent entries of same type */
67 prev = list_entry(this->nl_entry.prev, struct nouveau_mm_node, nl_entry);
68 if (this->nl_entry.prev != &rmm->nodes) {
69 if (prev->free && prev->type == this->type) {
70 prev->length += this->length;
71 region_put(rmm, this);
72 this = prev;
73 }
74 }
75
76 next = list_entry(this->nl_entry.next, struct nouveau_mm_node, nl_entry);
77 if (this->nl_entry.next != &rmm->nodes) {
78 if (next->free && next->type == this->type) {
79 next->offset = this->offset;
80 next->length += this->length;
81 region_put(rmm, this);
82 this = next;
83 }
84 }
85
86 return this;
87}
88 62
89void 63void
90nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this) 64nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this)
91{ 65{
92 u32 block_s, block_l; 66 struct nouveau_mm_node *prev = node(this, prev);
67 struct nouveau_mm_node *next = node(this, next);
93 68
94 this->free = true;
95 list_add(&this->fl_entry, &rmm->free); 69 list_add(&this->fl_entry, &rmm->free);
96 this = nouveau_mm_merge(rmm, this); 70 this->type = 0;
97
98 /* any entirely free blocks now? we'll want to remove typing
99 * on them now so they can be use for any memory allocation
100 */
101 block_s = roundup(this->offset, rmm->block_size);
102 if (block_s + rmm->block_size > this->offset + this->length)
103 return;
104 71
105 /* split off any still-typed region at the start */ 72 if (prev && prev->type == 0) {
106 if (block_s != this->offset) { 73 prev->length += this->length;
107 if (!region_split(rmm, this, block_s - this->offset)) 74 region_put(rmm, this);
108 return; 75 this = prev;
109 } 76 }
110 77
111 /* split off the soon-to-be-untyped block(s) */ 78 if (next && next->type == 0) {
112 block_l = rounddown(this->length, rmm->block_size); 79 next->offset = this->offset;
113 if (block_l != this->length) { 80 next->length += this->length;
114 this = region_split(rmm, this, block_l); 81 region_put(rmm, this);
115 if (!this)
116 return;
117 } 82 }
118
119 /* mark as having no type, and retry merge with any adjacent
120 * untyped blocks
121 */
122 this->type = 0;
123 nouveau_mm_merge(rmm, this);
124} 83}
125 84
126int 85int
127nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, 86nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc,
128 u32 align, struct nouveau_mm_node **pnode) 87 u32 align, struct nouveau_mm_node **pnode)
129{ 88{
130 struct nouveau_mm_node *this, *tmp, *next; 89 struct nouveau_mm_node *prev, *this, *next;
131 u32 splitoff, avail, alloc; 90 u32 min = size_nc ? size_nc : size;
132 91 u32 align_mask = align - 1;
133 list_for_each_entry_safe(this, tmp, &rmm->free, fl_entry) { 92 u32 splitoff;
134 next = list_entry(this->nl_entry.next, struct nouveau_mm_node, nl_entry); 93 u32 s, e;
135 if (this->nl_entry.next == &rmm->nodes) 94
136 next = NULL; 95 list_for_each_entry(this, &rmm->free, fl_entry) {
137 96 e = this->offset + this->length;
138 /* skip wrongly typed blocks */ 97 s = this->offset;
139 if (this->type && this->type != type) 98
99 prev = node(this, prev);
100 if (prev && prev->type != type)
101 s = roundup(s, rmm->block_size);
102
103 next = node(this, next);
104 if (next && next->type != type)
105 e = rounddown(e, rmm->block_size);
106
107 s = (s + align_mask) & ~align_mask;
108 e &= ~align_mask;
109 if (s > e || e - s < min)
140 continue; 110 continue;
141 111
142 /* account for alignment */ 112 splitoff = s - this->offset;
143 splitoff = this->offset & (align - 1); 113 if (splitoff && !region_split(rmm, this, splitoff))
144 if (splitoff) 114 return -ENOMEM;
145 splitoff = align - splitoff;
146
147 if (this->length <= splitoff)
148 continue;
149
150 /* determine total memory available from this, and
151 * the next block (if appropriate)
152 */
153 avail = this->length;
154 if (next && next->free && (!next->type || next->type == type))
155 avail += next->length;
156
157 avail -= splitoff;
158
159 /* determine allocation size */
160 if (size_nc) {
161 alloc = min(avail, size);
162 alloc = rounddown(alloc, size_nc);
163 if (alloc == 0)
164 continue;
165 } else {
166 alloc = size;
167 if (avail < alloc)
168 continue;
169 }
170
171 /* untyped block, split off a chunk that's a multiple
172 * of block_size and type it
173 */
174 if (!this->type) {
175 u32 block = roundup(alloc + splitoff, rmm->block_size);
176 if (this->length < block)
177 continue;
178
179 this = region_split(rmm, this, block);
180 if (!this)
181 return -ENOMEM;
182
183 this->type = type;
184 }
185
186 /* stealing memory from adjacent block */
187 if (alloc > this->length) {
188 u32 amount = alloc - (this->length - splitoff);
189
190 if (!next->type) {
191 amount = roundup(amount, rmm->block_size);
192
193 next = region_split(rmm, next, amount);
194 if (!next)
195 return -ENOMEM;
196
197 next->type = type;
198 }
199
200 this->length += amount;
201 next->offset += amount;
202 next->length -= amount;
203 if (!next->length) {
204 list_del(&next->nl_entry);
205 list_del(&next->fl_entry);
206 kfree(next);
207 }
208 }
209
210 if (splitoff) {
211 if (!region_split(rmm, this, splitoff))
212 return -ENOMEM;
213 }
214 115
215 this = region_split(rmm, this, alloc); 116 this = region_split(rmm, this, min(size, e - s));
216 if (this == NULL) 117 if (!this)
217 return -ENOMEM; 118 return -ENOMEM;
218 119
219 this->free = false; 120 this->type = type;
220 list_del(&this->fl_entry); 121 list_del(&this->fl_entry);
221 *pnode = this; 122 *pnode = this;
222 return 0; 123 return 0;
@@ -234,7 +135,6 @@ nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block)
234 heap = kzalloc(sizeof(*heap), GFP_KERNEL); 135 heap = kzalloc(sizeof(*heap), GFP_KERNEL);
235 if (!heap) 136 if (!heap)
236 return -ENOMEM; 137 return -ENOMEM;
237 heap->free = true;
238 heap->offset = roundup(offset, block); 138 heap->offset = roundup(offset, block);
239 heap->length = rounddown(offset + length, block) - heap->offset; 139 heap->length = rounddown(offset + length, block) - heap->offset;
240 140
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h
index af3844933036..798eaf39691c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.h
@@ -30,9 +30,7 @@ struct nouveau_mm_node {
30 struct list_head fl_entry; 30 struct list_head fl_entry;
31 struct list_head rl_entry; 31 struct list_head rl_entry;
32 32
33 bool free; 33 u8 type;
34 int type;
35
36 u32 offset; 34 u32 offset;
37 u32 length; 35 u32 length;
38}; 36};
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
index 19ef92a0375a..8870d72388c8 100644
--- a/drivers/gpu/drm/nouveau/nv40_graph.c
+++ b/drivers/gpu/drm/nouveau/nv40_graph.c
@@ -451,8 +451,7 @@ nv40_graph_register(struct drm_device *dev)
451 NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */ 451 NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */
452 452
453 /* curie */ 453 /* curie */
454 if (dev_priv->chipset >= 0x60 || 454 if (nv44_graph_class(dev))
455 0x00005450 & (1 << (dev_priv->chipset & 0x0f)))
456 NVOBJ_CLASS(dev, 0x4497, GR); 455 NVOBJ_CLASS(dev, 0x4497, GR);
457 else 456 else
458 NVOBJ_CLASS(dev, 0x4097, GR); 457 NVOBJ_CLASS(dev, 0x4097, GR);
diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/nv40_grctx.c
index ce585093264e..f70447d131d7 100644
--- a/drivers/gpu/drm/nouveau/nv40_grctx.c
+++ b/drivers/gpu/drm/nouveau/nv40_grctx.c
@@ -118,17 +118,6 @@
118 */ 118 */
119 119
120static int 120static int
121nv40_graph_4097(struct drm_device *dev)
122{
123 struct drm_nouveau_private *dev_priv = dev->dev_private;
124
125 if ((dev_priv->chipset & 0xf0) == 0x60)
126 return 0;
127
128 return !!(0x0baf & (1 << dev_priv->chipset));
129}
130
131static int
132nv40_graph_vs_count(struct drm_device *dev) 121nv40_graph_vs_count(struct drm_device *dev)
133{ 122{
134 struct drm_nouveau_private *dev_priv = dev->dev_private; 123 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -219,7 +208,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
219 gr_def(ctx, 0x4009dc, 0x80000000); 208 gr_def(ctx, 0x4009dc, 0x80000000);
220 } else { 209 } else {
221 cp_ctx(ctx, 0x400840, 20); 210 cp_ctx(ctx, 0x400840, 20);
222 if (!nv40_graph_4097(ctx->dev)) { 211 if (nv44_graph_class(ctx->dev)) {
223 for (i = 0; i < 8; i++) 212 for (i = 0; i < 8; i++)
224 gr_def(ctx, 0x400860 + (i * 4), 0x00000001); 213 gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
225 } 214 }
@@ -228,7 +217,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
228 gr_def(ctx, 0x400888, 0x00000040); 217 gr_def(ctx, 0x400888, 0x00000040);
229 cp_ctx(ctx, 0x400894, 11); 218 cp_ctx(ctx, 0x400894, 11);
230 gr_def(ctx, 0x400894, 0x00000040); 219 gr_def(ctx, 0x400894, 0x00000040);
231 if (nv40_graph_4097(ctx->dev)) { 220 if (!nv44_graph_class(ctx->dev)) {
232 for (i = 0; i < 8; i++) 221 for (i = 0; i < 8; i++)
233 gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000); 222 gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
234 } 223 }
@@ -546,7 +535,7 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
546static void 535static void
547nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx) 536nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
548{ 537{
549 int len = nv40_graph_4097(ctx->dev) ? 0x0684 : 0x0084; 538 int len = nv44_graph_class(ctx->dev) ? 0x0084 : 0x0684;
550 539
551 cp_out (ctx, 0x300000); 540 cp_out (ctx, 0x300000);
552 cp_lsr (ctx, len - 4); 541 cp_lsr (ctx, len - 4);
@@ -582,11 +571,11 @@ nv40_graph_construct_shader(struct nouveau_grctx *ctx)
582 } else { 571 } else {
583 b0_offset = 0x1d40/4; /* 2200 */ 572 b0_offset = 0x1d40/4; /* 2200 */
584 b1_offset = 0x3f40/4; /* 0b00 : 0a40 */ 573 b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
585 vs_len = nv40_graph_4097(dev) ? 0x4a40/4 : 0x4980/4; 574 vs_len = nv44_graph_class(dev) ? 0x4980/4 : 0x4a40/4;
586 } 575 }
587 576
588 cp_lsr(ctx, vs_len * vs_nr + 0x300/4); 577 cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
589 cp_out(ctx, nv40_graph_4097(dev) ? 0x800041 : 0x800029); 578 cp_out(ctx, nv44_graph_class(dev) ? 0x800029 : 0x800041);
590 579
591 offset = ctx->ctxvals_pos; 580 offset = ctx->ctxvals_pos;
592 ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len)); 581 ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c
index e4e72c12ab6a..03c0d4c3f355 100644
--- a/drivers/gpu/drm/nouveau/nv40_mc.c
+++ b/drivers/gpu/drm/nouveau/nv40_mc.c
@@ -6,27 +6,17 @@
6int 6int
7nv40_mc_init(struct drm_device *dev) 7nv40_mc_init(struct drm_device *dev)
8{ 8{
9 struct drm_nouveau_private *dev_priv = dev->dev_private;
10 uint32_t tmp;
11
12 /* Power up everything, resetting each individual unit will 9 /* Power up everything, resetting each individual unit will
13 * be done later if needed. 10 * be done later if needed.
14 */ 11 */
15 nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); 12 nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
16 13
17 switch (dev_priv->chipset) { 14 if (nv44_graph_class(dev)) {
18 case 0x44: 15 u32 tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
19 case 0x46: /* G72 */
20 case 0x4e:
21 case 0x4c: /* C51_G7X */
22 tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
23 nv_wr32(dev, NV40_PMC_1700, tmp); 16 nv_wr32(dev, NV40_PMC_1700, tmp);
24 nv_wr32(dev, NV40_PMC_1704, 0); 17 nv_wr32(dev, NV40_PMC_1704, 0);
25 nv_wr32(dev, NV40_PMC_1708, 0); 18 nv_wr32(dev, NV40_PMC_1708, 0);
26 nv_wr32(dev, NV40_PMC_170C, tmp); 19 nv_wr32(dev, NV40_PMC_170C, tmp);
27 break;
28 default:
29 break;
30 } 20 }
31 21
32 return 0; 22 return 0;
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index 2e1b1cd19a4b..ea0041810ae3 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -332,8 +332,11 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
332 gpuobj->vinst = node->vram->offset; 332 gpuobj->vinst = node->vram->offset;
333 333
334 if (gpuobj->flags & NVOBJ_FLAG_VM) { 334 if (gpuobj->flags & NVOBJ_FLAG_VM) {
335 ret = nouveau_vm_get(dev_priv->chan_vm, size, 12, 335 u32 flags = NV_MEM_ACCESS_RW;
336 NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, 336 if (!(gpuobj->flags & NVOBJ_FLAG_VM_USER))
337 flags |= NV_MEM_ACCESS_SYS;
338
339 ret = nouveau_vm_get(dev_priv->chan_vm, size, 12, flags,
337 &node->chan_vma); 340 &node->chan_vma);
338 if (ret) { 341 if (ret) {
339 vram->put(dev, &node->vram); 342 vram->put(dev, &node->vram);
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
index 5feacd5d5fa4..e6ea7d83187f 100644
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
@@ -105,7 +105,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
105 if (ret) 105 if (ret)
106 return ret; 106 return ret;
107 107
108 ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096, NVOBJ_FLAG_VM, 108 ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096,
109 NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER,
109 &grch->unk418810); 110 &grch->unk418810);
110 if (ret) 111 if (ret)
111 return ret; 112 return ret;
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c
index 4b9251bb0ff4..e4e83c2caf5b 100644
--- a/drivers/gpu/drm/nouveau/nvc0_vm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c
@@ -48,8 +48,8 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
48 phys >>= 8; 48 phys >>= 8;
49 49
50 phys |= 0x00000001; /* present */ 50 phys |= 0x00000001; /* present */
51// if (vma->access & NV_MEM_ACCESS_SYS) 51 if (vma->access & NV_MEM_ACCESS_SYS)
52// phys |= 0x00000002; 52 phys |= 0x00000002;
53 53
54 phys |= ((u64)target << 32); 54 phys |= ((u64)target << 32);
55 phys |= ((u64)memtype << 36); 55 phys |= ((u64)memtype << 36);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 7fe8ebdcdc0e..a8973acb3987 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3002,31 +3002,6 @@ int evergreen_copy_blit(struct radeon_device *rdev,
3002 return 0; 3002 return 0;
3003} 3003}
3004 3004
3005static bool evergreen_card_posted(struct radeon_device *rdev)
3006{
3007 u32 reg;
3008
3009 /* first check CRTCs */
3010 if (rdev->flags & RADEON_IS_IGP)
3011 reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
3012 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
3013 else
3014 reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
3015 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
3016 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
3017 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
3018 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
3019 RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
3020 if (reg & EVERGREEN_CRTC_MASTER_EN)
3021 return true;
3022
3023 /* then check MEM_SIZE, in case the crtcs are off */
3024 if (RREG32(CONFIG_MEMSIZE))
3025 return true;
3026
3027 return false;
3028}
3029
3030/* Plan is to move initialization in that function and use 3005/* Plan is to move initialization in that function and use
3031 * helper function so that radeon_device_init pretty much 3006 * helper function so that radeon_device_init pretty much
3032 * do nothing more than calling asic specific function. This 3007 * do nothing more than calling asic specific function. This
@@ -3063,7 +3038,7 @@ int evergreen_init(struct radeon_device *rdev)
3063 if (radeon_asic_reset(rdev)) 3038 if (radeon_asic_reset(rdev))
3064 dev_warn(rdev->dev, "GPU reset failed !\n"); 3039 dev_warn(rdev->dev, "GPU reset failed !\n");
3065 /* Post card if necessary */ 3040 /* Post card if necessary */
3066 if (!evergreen_card_posted(rdev)) { 3041 if (!radeon_card_posted(rdev)) {
3067 if (!rdev->bios) { 3042 if (!rdev->bios) {
3068 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 3043 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
3069 return -EINVAL; 3044 return -EINVAL;
@@ -3158,6 +3133,9 @@ static void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
3158{ 3133{
3159 u32 link_width_cntl, speed_cntl; 3134 u32 link_width_cntl, speed_cntl;
3160 3135
3136 if (radeon_pcie_gen2 == 0)
3137 return;
3138
3161 if (rdev->flags & RADEON_IS_IGP) 3139 if (rdev->flags & RADEON_IS_IGP)
3162 return; 3140 return;
3163 3141
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index f637595b14e1..46da5142b131 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2086,12 +2086,13 @@ int r100_asic_reset(struct radeon_device *rdev)
2086{ 2086{
2087 struct r100_mc_save save; 2087 struct r100_mc_save save;
2088 u32 status, tmp; 2088 u32 status, tmp;
2089 int ret = 0;
2089 2090
2090 r100_mc_stop(rdev, &save);
2091 status = RREG32(R_000E40_RBBM_STATUS); 2091 status = RREG32(R_000E40_RBBM_STATUS);
2092 if (!G_000E40_GUI_ACTIVE(status)) { 2092 if (!G_000E40_GUI_ACTIVE(status)) {
2093 return 0; 2093 return 0;
2094 } 2094 }
2095 r100_mc_stop(rdev, &save);
2095 status = RREG32(R_000E40_RBBM_STATUS); 2096 status = RREG32(R_000E40_RBBM_STATUS);
2096 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 2097 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
2097 /* stop CP */ 2098 /* stop CP */
@@ -2131,11 +2132,11 @@ int r100_asic_reset(struct radeon_device *rdev)
2131 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { 2132 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
2132 dev_err(rdev->dev, "failed to reset GPU\n"); 2133 dev_err(rdev->dev, "failed to reset GPU\n");
2133 rdev->gpu_lockup = true; 2134 rdev->gpu_lockup = true;
2134 return -1; 2135 ret = -1;
2135 } 2136 } else
2137 dev_info(rdev->dev, "GPU reset succeed\n");
2136 r100_mc_resume(rdev, &save); 2138 r100_mc_resume(rdev, &save);
2137 dev_info(rdev->dev, "GPU reset succeed\n"); 2139 return ret;
2138 return 0;
2139} 2140}
2140 2141
2141void r100_set_common_regs(struct radeon_device *rdev) 2142void r100_set_common_regs(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index fae5e709f270..cf862ca580bf 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -405,12 +405,13 @@ int r300_asic_reset(struct radeon_device *rdev)
405{ 405{
406 struct r100_mc_save save; 406 struct r100_mc_save save;
407 u32 status, tmp; 407 u32 status, tmp;
408 int ret = 0;
408 409
409 r100_mc_stop(rdev, &save);
410 status = RREG32(R_000E40_RBBM_STATUS); 410 status = RREG32(R_000E40_RBBM_STATUS);
411 if (!G_000E40_GUI_ACTIVE(status)) { 411 if (!G_000E40_GUI_ACTIVE(status)) {
412 return 0; 412 return 0;
413 } 413 }
414 r100_mc_stop(rdev, &save);
414 status = RREG32(R_000E40_RBBM_STATUS); 415 status = RREG32(R_000E40_RBBM_STATUS);
415 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 416 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
416 /* stop CP */ 417 /* stop CP */
@@ -451,11 +452,11 @@ int r300_asic_reset(struct radeon_device *rdev)
451 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { 452 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
452 dev_err(rdev->dev, "failed to reset GPU\n"); 453 dev_err(rdev->dev, "failed to reset GPU\n");
453 rdev->gpu_lockup = true; 454 rdev->gpu_lockup = true;
454 return -1; 455 ret = -1;
455 } 456 } else
457 dev_info(rdev->dev, "GPU reset succeed\n");
456 r100_mc_resume(rdev, &save); 458 r100_mc_resume(rdev, &save);
457 dev_info(rdev->dev, "GPU reset succeed\n"); 459 return ret;
458 return 0;
459} 460}
460 461
461/* 462/*
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 6b50716267c0..aca2236268fa 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2358,24 +2358,6 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
2358 /* FIXME: implement */ 2358 /* FIXME: implement */
2359} 2359}
2360 2360
2361
2362bool r600_card_posted(struct radeon_device *rdev)
2363{
2364 uint32_t reg;
2365
2366 /* first check CRTCs */
2367 reg = RREG32(D1CRTC_CONTROL) |
2368 RREG32(D2CRTC_CONTROL);
2369 if (reg & CRTC_EN)
2370 return true;
2371
2372 /* then check MEM_SIZE, in case the crtcs are off */
2373 if (RREG32(CONFIG_MEMSIZE))
2374 return true;
2375
2376 return false;
2377}
2378
2379int r600_startup(struct radeon_device *rdev) 2361int r600_startup(struct radeon_device *rdev)
2380{ 2362{
2381 int r; 2363 int r;
@@ -2536,7 +2518,7 @@ int r600_init(struct radeon_device *rdev)
2536 if (r) 2518 if (r)
2537 return r; 2519 return r;
2538 /* Post card if necessary */ 2520 /* Post card if necessary */
2539 if (!r600_card_posted(rdev)) { 2521 if (!radeon_card_posted(rdev)) {
2540 if (!rdev->bios) { 2522 if (!rdev->bios) {
2541 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 2523 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2542 return -EINVAL; 2524 return -EINVAL;
@@ -3658,6 +3640,9 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
3658 u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; 3640 u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp;
3659 u16 link_cntl2; 3641 u16 link_cntl2;
3660 3642
3643 if (radeon_pcie_gen2 == 0)
3644 return;
3645
3661 if (rdev->flags & RADEON_IS_IGP) 3646 if (rdev->flags & RADEON_IS_IGP)
3662 return; 3647 return;
3663 3648
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e9486630a467..71d2a554bbe6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -92,6 +92,7 @@ extern int radeon_tv;
92extern int radeon_audio; 92extern int radeon_audio;
93extern int radeon_disp_priority; 93extern int radeon_disp_priority;
94extern int radeon_hw_i2c; 94extern int radeon_hw_i2c;
95extern int radeon_pcie_gen2;
95 96
96/* 97/*
97 * Copy from radeon_drv.h so we don't have to include both and have conflicting 98 * Copy from radeon_drv.h so we don't have to include both and have conflicting
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index be5cb4f28c29..d5680a0c87af 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -104,6 +104,7 @@ int radeon_tv = 1;
104int radeon_audio = 1; 104int radeon_audio = 1;
105int radeon_disp_priority = 0; 105int radeon_disp_priority = 0;
106int radeon_hw_i2c = 0; 106int radeon_hw_i2c = 0;
107int radeon_pcie_gen2 = 0;
107 108
108MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 109MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
109module_param_named(no_wb, radeon_no_wb, int, 0444); 110module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -147,6 +148,9 @@ module_param_named(disp_priority, radeon_disp_priority, int, 0444);
147MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); 148MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
148module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); 149module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
149 150
151MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)");
152module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444);
153
150static int radeon_suspend(struct drm_device *dev, pm_message_t state) 154static int radeon_suspend(struct drm_device *dev, pm_message_t state)
151{ 155{
152 drm_radeon_private_t *dev_priv = dev->dev_private; 156 drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index ac40fd39d787..9177f9191837 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -439,7 +439,7 @@ evergreen 0x9400
4390x000286EC SPI_COMPUTE_NUM_THREAD_X 4390x000286EC SPI_COMPUTE_NUM_THREAD_X
4400x000286F0 SPI_COMPUTE_NUM_THREAD_Y 4400x000286F0 SPI_COMPUTE_NUM_THREAD_Y
4410x000286F4 SPI_COMPUTE_NUM_THREAD_Z 4410x000286F4 SPI_COMPUTE_NUM_THREAD_Z
4420x000286F8 GDS_ADDR_SIZE 4420x00028724 GDS_ADDR_SIZE
4430x00028780 CB_BLEND0_CONTROL 4430x00028780 CB_BLEND0_CONTROL
4440x00028784 CB_BLEND1_CONTROL 4440x00028784 CB_BLEND1_CONTROL
4450x00028788 CB_BLEND2_CONTROL 4450x00028788 CB_BLEND2_CONTROL
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index b4192acaab5f..5afe294ed51f 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -339,16 +339,16 @@ void rs600_bm_disable(struct radeon_device *rdev)
339 339
340int rs600_asic_reset(struct radeon_device *rdev) 340int rs600_asic_reset(struct radeon_device *rdev)
341{ 341{
342 u32 status, tmp;
343
344 struct rv515_mc_save save; 342 struct rv515_mc_save save;
343 u32 status, tmp;
344 int ret = 0;
345 345
346 /* Stops all mc clients */
347 rv515_mc_stop(rdev, &save);
348 status = RREG32(R_000E40_RBBM_STATUS); 346 status = RREG32(R_000E40_RBBM_STATUS);
349 if (!G_000E40_GUI_ACTIVE(status)) { 347 if (!G_000E40_GUI_ACTIVE(status)) {
350 return 0; 348 return 0;
351 } 349 }
350 /* Stops all mc clients */
351 rv515_mc_stop(rdev, &save);
352 status = RREG32(R_000E40_RBBM_STATUS); 352 status = RREG32(R_000E40_RBBM_STATUS);
353 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 353 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
354 /* stop CP */ 354 /* stop CP */
@@ -392,11 +392,11 @@ int rs600_asic_reset(struct radeon_device *rdev)
392 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { 392 if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
393 dev_err(rdev->dev, "failed to reset GPU\n"); 393 dev_err(rdev->dev, "failed to reset GPU\n");
394 rdev->gpu_lockup = true; 394 rdev->gpu_lockup = true;
395 return -1; 395 ret = -1;
396 } 396 } else
397 dev_info(rdev->dev, "GPU reset succeed\n");
397 rv515_mc_resume(rdev, &save); 398 rv515_mc_resume(rdev, &save);
398 dev_info(rdev->dev, "GPU reset succeed\n"); 399 return ret;
399 return 0;
400} 400}
401 401
402/* 402/*
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 3a264aa3a79a..491dc9000655 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1268,7 +1268,7 @@ int rv770_init(struct radeon_device *rdev)
1268 if (r) 1268 if (r)
1269 return r; 1269 return r;
1270 /* Post card if necessary */ 1270 /* Post card if necessary */
1271 if (!r600_card_posted(rdev)) { 1271 if (!radeon_card_posted(rdev)) {
1272 if (!rdev->bios) { 1272 if (!rdev->bios) {
1273 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 1273 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
1274 return -EINVAL; 1274 return -EINVAL;
@@ -1372,6 +1372,9 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
1372 u32 link_width_cntl, lanes, speed_cntl, tmp; 1372 u32 link_width_cntl, lanes, speed_cntl, tmp;
1373 u16 link_cntl2; 1373 u16 link_cntl2;
1374 1374
1375 if (radeon_pcie_gen2 == 0)
1376 return;
1377
1375 if (rdev->flags & RADEON_IS_IGP) 1378 if (rdev->flags & RADEON_IS_IGP)
1376 return; 1379 return;
1377 1380