Subversion Repositories Kolibri OS

Rev

Rev 4560 | Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4560 Rev 5060
Line 71... Line 71...
71
#endif
71
#endif
72
	}
72
	}
Line 73... Line 73...
73
 
73
 
74
	if (base == 0)
74
	if (base == 0)
-
 
75
		return 0;
-
 
76
 
-
 
77
	/* make sure we don't clobber the GTT if it's within stolen memory */
-
 
78
	if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) {
-
 
79
		struct {
-
 
80
			u32 start, end;
-
 
81
		} stolen[2] = {
-
 
82
			{ .start = base, .end = base + dev_priv->gtt.stolen_size, },
-
 
83
			{ .start = base, .end = base + dev_priv->gtt.stolen_size, },
-
 
84
		};
-
 
85
		u64 gtt_start, gtt_end;
-
 
86
 
-
 
87
		gtt_start = I915_READ(PGTBL_CTL);
-
 
88
		if (IS_GEN4(dev))
-
 
89
			gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) |
-
 
90
				(gtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
-
 
91
		else
-
 
92
			gtt_start &= PGTBL_ADDRESS_LO_MASK;
-
 
93
		gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4;
-
 
94
 
-
 
95
		if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end)
-
 
96
			stolen[0].end = gtt_start;
-
 
97
		if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end)
-
 
98
			stolen[1].start = gtt_end;
-
 
99
 
-
 
100
		/* pick the larger of the two chunks */
-
 
101
		if (stolen[0].end - stolen[0].start >
-
 
102
		    stolen[1].end - stolen[1].start) {
-
 
103
			base = stolen[0].start;
-
 
104
			dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start;
-
 
105
		} else {
-
 
106
			base = stolen[1].start;
-
 
107
			dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start;
-
 
108
		}
-
 
109
 
-
 
110
		if (stolen[0].start != stolen[1].start ||
-
 
111
		    stolen[0].end != stolen[1].end) {
-
 
112
			DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
-
 
113
				      (unsigned long long) gtt_start,
-
 
114
				      (unsigned long long) gtt_end - 1);
-
 
115
			DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n",
-
 
116
				      base, base + (u32) dev_priv->gtt.stolen_size - 1);
-
 
117
		}
-
 
118
	}
75
		return 0;
119
 
-
 
120
#if 0
76
#if 0
121
 
77
	/* Verify that nothing else uses this physical address. Stolen
122
	/* Verify that nothing else uses this physical address. Stolen
78
	 * memory should be reserved by the BIOS and hidden from the
123
	 * memory should be reserved by the BIOS and hidden from the
79
	 * kernel. So if the region is already marked as busy, something
124
	 * kernel. So if the region is already marked as busy, something
80
	 * is seriously wrong.
125
	 * is seriously wrong.
Line 88... Line 133...
88
	}
133
	}
89
#endif
134
#endif
90
	return base;
135
	return base;
91
}
136
}
Line 92... Line 137...
92
 
137
 
-
 
138
static int find_compression_threshold(struct drm_device *dev,
-
 
139
				      struct drm_mm_node *node,
-
 
140
				      int size,
93
static int i915_setup_compression(struct drm_device *dev, int size)
141
				      int fb_cpp)
94
{
142
{
95
	struct drm_i915_private *dev_priv = dev->dev_private;
143
	struct drm_i915_private *dev_priv = dev->dev_private;
96
	struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
144
	int compression_threshold = 1;
Line 97... Line 145...
97
	int ret;
145
	int ret;
98
 
146
 
-
 
147
	/* HACK: This code depends on what we will do in *_enable_fbc. If that
-
 
148
	 * code changes, this code needs to change as well.
-
 
149
	 *
99
	compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL);
150
	 * The enable_fbc code will attempt to use one of our 2 compression
Line 100... Line 151...
100
	if (!compressed_fb)
151
	 * thresholds, therefore, in that case, we only have 1 resort.
101
		goto err_llb;
152
	 */
102
 
153
 
103
	/* Try to over-allocate to reduce reallocations and fragmentation */
154
	/* Try to over-allocate to reduce reallocations and fragmentation. */
-
 
155
	ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
-
 
156
				 size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT);
-
 
157
	if (ret == 0)
-
 
158
		return compression_threshold;
-
 
159
 
-
 
160
again:
-
 
161
	/* HW's ability to limit the CFB is 1:4 */
-
 
162
	if (compression_threshold > 4 ||
104
	ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
163
	    (fb_cpp == 2 && compression_threshold == 2))
105
				 size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT);
164
		return 0;
106
	if (ret)
165
 
-
 
166
	ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
-
 
167
					 size >>= 1, 4096,
-
 
168
					 DRM_MM_SEARCH_DEFAULT);
-
 
169
	if (ret && INTEL_INFO(dev)->gen <= 4) {
-
 
170
		return 0;
-
 
171
	} else if (ret) {
-
 
172
		compression_threshold <<= 1;
-
 
173
		goto again;
-
 
174
	} else {
-
 
175
		return compression_threshold;
-
 
176
	}
-
 
177
}
-
 
178
 
-
 
179
static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp)
-
 
180
{
-
 
181
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
182
	struct drm_mm_node *uninitialized_var(compressed_llb);
-
 
183
	int ret;
107
		ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
184
 
108
					 size >>= 1, 4096,
185
	ret = find_compression_threshold(dev, &dev_priv->fbc.compressed_fb,
-
 
186
					 size, fb_cpp);
-
 
187
	if (!ret)
-
 
188
		goto err_llb;
-
 
189
	else if (ret > 1) {
-
 
190
		DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
-
 
191
 
Line 109... Line 192...
109
					 DRM_MM_SEARCH_DEFAULT);
192
	}
110
	if (ret)
193
 
111
		goto err_llb;
194
	dev_priv->fbc.threshold = ret;
112
 
195
 
113
	if (HAS_PCH_SPLIT(dev))
196
	if (HAS_PCH_SPLIT(dev))
114
		I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
197
		I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
115
	else if (IS_GM45(dev)) {
198
	else if (IS_GM45(dev)) {
116
		I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
199
		I915_WRITE(DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
Line 125... Line 208...
125
			goto err_fb;
208
			goto err_fb;
Line 126... Line 209...
126
 
209
 
Line 127... Line 210...
127
		dev_priv->fbc.compressed_llb = compressed_llb;
210
		dev_priv->fbc.compressed_llb = compressed_llb;
128
 
211
 
129
		I915_WRITE(FBC_CFB_BASE,
212
		I915_WRITE(FBC_CFB_BASE,
130
			   dev_priv->mm.stolen_base + compressed_fb->start);
213
			   dev_priv->mm.stolen_base + dev_priv->fbc.compressed_fb.start);
131
		I915_WRITE(FBC_LL_BASE,
214
		I915_WRITE(FBC_LL_BASE,
Line 132... Line 215...
132
			   dev_priv->mm.stolen_base + compressed_llb->start);
215
			   dev_priv->mm.stolen_base + compressed_llb->start);
133
	}
-
 
Line 134... Line 216...
134
 
216
	}
135
	dev_priv->fbc.compressed_fb = compressed_fb;
217
 
Line 136... Line 218...
136
	dev_priv->fbc.size = size;
218
	dev_priv->fbc.size = size / dev_priv->fbc.threshold;
Line 137... Line 219...
137
 
219
 
138
	DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",
220
	DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",
139
		      size);
221
		      size);
140
 
222
 
141
	return 0;
-
 
142
 
-
 
143
err_fb:
223
	return 0;
144
	kfree(compressed_llb);
224
 
Line 145... Line 225...
145
	drm_mm_remove_node(compressed_fb);
225
err_fb:
146
err_llb:
226
	kfree(compressed_llb);
147
	kfree(compressed_fb);
227
	drm_mm_remove_node(&dev_priv->fbc.compressed_fb);
Line 148... Line 228...
148
//   pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
228
err_llb:
149
	return -ENOSPC;
229
	return -ENOSPC;
Line 160... Line 240...
160
		return 0;
240
		return 0;
Line 161... Line 241...
161
 
241
 
162
	/* Release any current block */
242
	/* Release any current block */
Line 163... Line 243...
163
	i915_gem_stolen_cleanup_compression(dev);
243
	i915_gem_stolen_cleanup_compression(dev);
164
 
244
 
Line 165... Line 245...
165
	return i915_setup_compression(dev, size);
245
	return i915_setup_compression(dev, size, fb_cpp);
166
}
246
}
167
 
247
 
Line 168... Line 248...
168
void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
248
void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
169
{
249
{
Line 170... Line -...
170
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
171
 
250
	struct drm_i915_private *dev_priv = dev->dev_private;
172
	if (dev_priv->fbc.size == 0)
-
 
173
		return;
-
 
Line 174... Line 251...
174
 
251
 
175
	if (dev_priv->fbc.compressed_fb) {
252
	if (dev_priv->fbc.size == 0)
176
		drm_mm_remove_node(dev_priv->fbc.compressed_fb);
253
		return;
177
		kfree(dev_priv->fbc.compressed_fb);
254
 
Line 199... Line 276...
199
int i915_gem_init_stolen(struct drm_device *dev)
276
int i915_gem_init_stolen(struct drm_device *dev)
200
{
277
{
201
	struct drm_i915_private *dev_priv = dev->dev_private;
278
	struct drm_i915_private *dev_priv = dev->dev_private;
202
	int bios_reserved = 0;
279
	int bios_reserved = 0;
Line -... Line 280...
-
 
280
 
-
 
281
#ifdef CONFIG_INTEL_IOMMU
-
 
282
	if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) {
-
 
283
		DRM_INFO("DMAR active, disabling use of stolen memory\n");
-
 
284
		return 0;
-
 
285
	}
-
 
286
#endif
203
 
287
 
204
	if (dev_priv->gtt.stolen_size == 0)
288
	if (dev_priv->gtt.stolen_size == 0)
Line 205... Line 289...
205
		return 0;
289
		return 0;
206
 
290
 
Line 270... Line 354...
270
	/* Should only be called during free */
354
	/* Should only be called during free */
271
	sg_free_table(obj->pages);
355
	sg_free_table(obj->pages);
272
	kfree(obj->pages);
356
	kfree(obj->pages);
273
}
357
}
Line -... Line 358...
-
 
358
 
-
 
359
 
-
 
360
static void
-
 
361
i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
-
 
362
{
-
 
363
	if (obj->stolen) {
-
 
364
		drm_mm_remove_node(obj->stolen);
-
 
365
		kfree(obj->stolen);
-
 
366
		obj->stolen = NULL;
-
 
367
	}
274
 
368
}
275
static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
369
static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
276
	.get_pages = i915_gem_object_get_pages_stolen,
370
	.get_pages = i915_gem_object_get_pages_stolen,
-
 
371
	.put_pages = i915_gem_object_put_pages_stolen,
277
	.put_pages = i915_gem_object_put_pages_stolen,
372
	.release = i915_gem_object_release_stolen,
Line 278... Line 373...
278
};
373
};
279
 
374
 
280
static struct drm_i915_gem_object *
375
static struct drm_i915_gem_object *
Line 430... Line 525...
430
	drm_mm_remove_node(stolen);
525
	drm_mm_remove_node(stolen);
431
	kfree(stolen);
526
	kfree(stolen);
432
	drm_gem_object_unreference(&obj->base);
527
	drm_gem_object_unreference(&obj->base);
433
	return NULL;
528
	return NULL;
434
}
529
}
435
 
-
 
436
void
-
 
437
i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
-
 
438
{
-
 
439
	if (obj->stolen) {
-
 
440
		drm_mm_remove_node(obj->stolen);
-
 
441
		kfree(obj->stolen);
-
 
442
		obj->stolen = NULL;
-
 
443
	}
-
 
444
}
-