xref: /openbmc/linux/drivers/gpu/drm/gma500/gtt.c (revision 5bd8e16d)
1 /*
2  * Copyright (c) 2007, Intel Corporation.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
19  *	    Alan Cox <alan@linux.intel.com>
20  */
21 
22 #include <drm/drmP.h>
23 #include <linux/shmem_fs.h>
24 #include "psb_drv.h"
25 
26 
27 /*
28  *	GTT resource allocator - manage page mappings in GTT space
29  */
30 
31 /**
32  *	psb_gtt_mask_pte	-	generate GTT pte entry
33  *	@pfn: page number to encode
34  *	@type: type of memory in the GTT
35  *
36  *	Set the GTT entry for the appropriate memory type.
37  */
38 static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
39 {
40 	uint32_t mask = PSB_PTE_VALID;
41 
42 	/* Ensure we explode rather than put an invalid low mapping of
43 	   a high mapping page into the gtt */
44 	BUG_ON(pfn & ~(0xFFFFFFFF >> PAGE_SHIFT));
45 
46 	if (type & PSB_MMU_CACHED_MEMORY)
47 		mask |= PSB_PTE_CACHED;
48 	if (type & PSB_MMU_RO_MEMORY)
49 		mask |= PSB_PTE_RO;
50 	if (type & PSB_MMU_WO_MEMORY)
51 		mask |= PSB_PTE_WO;
52 
53 	return (pfn << PAGE_SHIFT) | mask;
54 }
55 
56 /**
57  *	psb_gtt_entry		-	find the GTT entries for a gtt_range
58  *	@dev: our DRM device
59  *	@r: our GTT range
60  *
61  *	Given a gtt_range object return the GTT offset of the page table
62  *	entries for this gtt_range
63  */
64 static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
65 {
66 	struct drm_psb_private *dev_priv = dev->dev_private;
67 	unsigned long offset;
68 
69 	offset = r->resource.start - dev_priv->gtt_mem->start;
70 
71 	return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
72 }
73 
74 /**
75  *	psb_gtt_insert	-	put an object into the GTT
76  *	@dev: our DRM device
77  *	@r: our GTT range
78  *
79  *	Take our preallocated GTT range and insert the GEM object into
80  *	the GTT. This is protected via the gtt mutex which the caller
81  *	must hold.
82  */
83 static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
84 			  int resume)
85 {
86 	u32 __iomem *gtt_slot;
87 	u32 pte;
88 	struct page **pages;
89 	int i;
90 
91 	if (r->pages == NULL) {
92 		WARN_ON(1);
93 		return -EINVAL;
94 	}
95 
96 	WARN_ON(r->stolen);	/* refcount these maybe ? */
97 
98 	gtt_slot = psb_gtt_entry(dev, r);
99 	pages = r->pages;
100 
101 	if (!resume) {
102 		/* Make sure changes are visible to the GPU */
103 		set_pages_array_wc(pages, r->npage);
104 	}
105 
106 	/* Write our page entries into the GTT itself */
107 	for (i = r->roll; i < r->npage; i++) {
108 		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
109 		iowrite32(pte, gtt_slot++);
110 	}
111 	for (i = 0; i < r->roll; i++) {
112 		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
113 		iowrite32(pte, gtt_slot++);
114 	}
115 	/* Make sure all the entries are set before we return */
116 	ioread32(gtt_slot - 1);
117 
118 	return 0;
119 }
120 
121 /**
122  *	psb_gtt_remove	-	remove an object from the GTT
123  *	@dev: our DRM device
124  *	@r: our GTT range
125  *
126  *	Remove a preallocated GTT range from the GTT. Overwrite all the
127  *	page table entries with the dummy page. This is protected via the gtt
128  *	mutex which the caller must hold.
129  */
130 static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
131 {
132 	struct drm_psb_private *dev_priv = dev->dev_private;
133 	u32 __iomem *gtt_slot;
134 	u32 pte;
135 	int i;
136 
137 	WARN_ON(r->stolen);
138 
139 	gtt_slot = psb_gtt_entry(dev, r);
140 	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
141 
142 	for (i = 0; i < r->npage; i++)
143 		iowrite32(pte, gtt_slot++);
144 	ioread32(gtt_slot - 1);
145 	set_pages_array_wb(r->pages, r->npage);
146 }
147 
148 /**
149  *	psb_gtt_roll	-	set scrolling position
150  *	@dev: our DRM device
151  *	@r: the gtt mapping we are using
152  *	@roll: roll offset
153  *
154  *	Roll an existing pinned mapping by moving the pages through the GTT.
155  *	This allows us to implement hardware scrolling on the consoles without
156  *	a 2D engine
157  */
158 void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
159 {
160 	u32 __iomem *gtt_slot;
161 	u32 pte;
162 	int i;
163 
164 	if (roll >= r->npage) {
165 		WARN_ON(1);
166 		return;
167 	}
168 
169 	r->roll = roll;
170 
171 	/* Not currently in the GTT - no worry we will write the mapping at
172 	   the right position when it gets pinned */
173 	if (!r->stolen && !r->in_gart)
174 		return;
175 
176 	gtt_slot = psb_gtt_entry(dev, r);
177 
178 	for (i = r->roll; i < r->npage; i++) {
179 		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
180 		iowrite32(pte, gtt_slot++);
181 	}
182 	for (i = 0; i < r->roll; i++) {
183 		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
184 		iowrite32(pte, gtt_slot++);
185 	}
186 	ioread32(gtt_slot - 1);
187 }
188 
189 /**
190  *	psb_gtt_attach_pages	-	attach and pin GEM pages
191  *	@gt: the gtt range
192  *
193  *	Pin and build an in kernel list of the pages that back our GEM object.
194  *	While we hold this the pages cannot be swapped out. This is protected
195  *	via the gtt mutex which the caller must hold.
196  */
197 static int psb_gtt_attach_pages(struct gtt_range *gt)
198 {
199 	struct page **pages;
200 
201 	WARN_ON(gt->pages);
202 
203 	pages = drm_gem_get_pages(&gt->gem, 0);
204 	if (IS_ERR(pages))
205 		return PTR_ERR(pages);
206 
207 	gt->pages = pages;
208 
209 	return 0;
210 }
211 
212 /**
213  *	psb_gtt_detach_pages	-	attach and pin GEM pages
214  *	@gt: the gtt range
215  *
216  *	Undo the effect of psb_gtt_attach_pages. At this point the pages
217  *	must have been removed from the GTT as they could now be paged out
218  *	and move bus address. This is protected via the gtt mutex which the
219  *	caller must hold.
220  */
221 static void psb_gtt_detach_pages(struct gtt_range *gt)
222 {
223 	drm_gem_put_pages(&gt->gem, gt->pages, true, false);
224 	gt->pages = NULL;
225 }
226 
227 /**
228  *	psb_gtt_pin		-	pin pages into the GTT
229  *	@gt: range to pin
230  *
231  *	Pin a set of pages into the GTT. The pins are refcounted so that
232  *	multiple pins need multiple unpins to undo.
233  *
234  *	Non GEM backed objects treat this as a no-op as they are always GTT
235  *	backed objects.
236  */
237 int psb_gtt_pin(struct gtt_range *gt)
238 {
239 	int ret = 0;
240 	struct drm_device *dev = gt->gem.dev;
241 	struct drm_psb_private *dev_priv = dev->dev_private;
242 
243 	mutex_lock(&dev_priv->gtt_mutex);
244 
245 	if (gt->in_gart == 0 && gt->stolen == 0) {
246 		ret = psb_gtt_attach_pages(gt);
247 		if (ret < 0)
248 			goto out;
249 		ret = psb_gtt_insert(dev, gt, 0);
250 		if (ret < 0) {
251 			psb_gtt_detach_pages(gt);
252 			goto out;
253 		}
254 	}
255 	gt->in_gart++;
256 out:
257 	mutex_unlock(&dev_priv->gtt_mutex);
258 	return ret;
259 }
260 
261 /**
262  *	psb_gtt_unpin		-	Drop a GTT pin requirement
263  *	@gt: range to pin
264  *
265  *	Undoes the effect of psb_gtt_pin. On the last drop the GEM object
266  *	will be removed from the GTT which will also drop the page references
267  *	and allow the VM to clean up or page stuff.
268  *
269  *	Non GEM backed objects treat this as a no-op as they are always GTT
270  *	backed objects.
271  */
272 void psb_gtt_unpin(struct gtt_range *gt)
273 {
274 	struct drm_device *dev = gt->gem.dev;
275 	struct drm_psb_private *dev_priv = dev->dev_private;
276 
277 	mutex_lock(&dev_priv->gtt_mutex);
278 
279 	WARN_ON(!gt->in_gart);
280 
281 	gt->in_gart--;
282 	if (gt->in_gart == 0 && gt->stolen == 0) {
283 		psb_gtt_remove(dev, gt);
284 		psb_gtt_detach_pages(gt);
285 	}
286 	mutex_unlock(&dev_priv->gtt_mutex);
287 }
288 
289 /*
290  *	GTT resource allocator - allocate and manage GTT address space
291  */
292 
293 /**
294  *	psb_gtt_alloc_range	-	allocate GTT address space
295  *	@dev: Our DRM device
296  *	@len: length (bytes) of address space required
297  *	@name: resource name
298  *	@backed: resource should be backed by stolen pages
299  *
300  *	Ask the kernel core to find us a suitable range of addresses
301  *	to use for a GTT mapping.
302  *
303  *	Returns a gtt_range structure describing the object, or NULL on
304  *	error. On successful return the resource is both allocated and marked
305  *	as in use.
306  */
307 struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
308 						const char *name, int backed)
309 {
310 	struct drm_psb_private *dev_priv = dev->dev_private;
311 	struct gtt_range *gt;
312 	struct resource *r = dev_priv->gtt_mem;
313 	int ret;
314 	unsigned long start, end;
315 
316 	if (backed) {
317 		/* The start of the GTT is the stolen pages */
318 		start = r->start;
319 		end = r->start + dev_priv->gtt.stolen_size - 1;
320 	} else {
321 		/* The rest we will use for GEM backed objects */
322 		start = r->start + dev_priv->gtt.stolen_size;
323 		end = r->end;
324 	}
325 
326 	gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
327 	if (gt == NULL)
328 		return NULL;
329 	gt->resource.name = name;
330 	gt->stolen = backed;
331 	gt->in_gart = backed;
332 	gt->roll = 0;
333 	/* Ensure this is set for non GEM objects */
334 	gt->gem.dev = dev;
335 	ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
336 				len, start, end, PAGE_SIZE, NULL, NULL);
337 	if (ret == 0) {
338 		gt->offset = gt->resource.start - r->start;
339 		return gt;
340 	}
341 	kfree(gt);
342 	return NULL;
343 }
344 
345 /**
346  *	psb_gtt_free_range	-	release GTT address space
347  *	@dev: our DRM device
348  *	@gt: a mapping created with psb_gtt_alloc_range
349  *
350  *	Release a resource that was allocated with psb_gtt_alloc_range. If the
351  *	object has been pinned by mmap users we clean this up here currently.
352  */
353 void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
354 {
355 	/* Undo the mmap pin if we are destroying the object */
356 	if (gt->mmapping) {
357 		psb_gtt_unpin(gt);
358 		gt->mmapping = 0;
359 	}
360 	WARN_ON(gt->in_gart && !gt->stolen);
361 	release_resource(&gt->resource);
362 	kfree(gt);
363 }
364 
365 static void psb_gtt_alloc(struct drm_device *dev)
366 {
367 	struct drm_psb_private *dev_priv = dev->dev_private;
368 	init_rwsem(&dev_priv->gtt.sem);
369 }
370 
371 void psb_gtt_takedown(struct drm_device *dev)
372 {
373 	struct drm_psb_private *dev_priv = dev->dev_private;
374 
375 	if (dev_priv->gtt_map) {
376 		iounmap(dev_priv->gtt_map);
377 		dev_priv->gtt_map = NULL;
378 	}
379 	if (dev_priv->gtt_initialized) {
380 		pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
381 				      dev_priv->gmch_ctrl);
382 		PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
383 		(void) PSB_RVDC32(PSB_PGETBL_CTL);
384 	}
385 	if (dev_priv->vram_addr)
386 		iounmap(dev_priv->gtt_map);
387 }
388 
389 int psb_gtt_init(struct drm_device *dev, int resume)
390 {
391 	struct drm_psb_private *dev_priv = dev->dev_private;
392 	unsigned gtt_pages;
393 	unsigned long stolen_size, vram_stolen_size;
394 	unsigned i, num_pages;
395 	unsigned pfn_base;
396 	struct psb_gtt *pg;
397 
398 	int ret = 0;
399 	uint32_t pte;
400 
401 	if (!resume) {
402 		mutex_init(&dev_priv->gtt_mutex);
403 		psb_gtt_alloc(dev);
404 	}
405 
406 	pg = &dev_priv->gtt;
407 
408 	/* Enable the GTT */
409 	pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
410 	pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
411 			      dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
412 
413 	dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
414 	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
415 	(void) PSB_RVDC32(PSB_PGETBL_CTL);
416 
417 	/* The root resource we allocate address space from */
418 	dev_priv->gtt_initialized = 1;
419 
420 	pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
421 
422 	/*
423 	 *	The video mmu has a hw bug when accessing 0x0D0000000.
424 	 *	Make gatt start at 0x0e000,0000. This doesn't actually
425 	 *	matter for us but may do if the video acceleration ever
426 	 *	gets opened up.
427 	 */
428 	pg->mmu_gatt_start = 0xE0000000;
429 
430 	pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
431 	gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
432 								>> PAGE_SHIFT;
433 	/* CDV doesn't report this. In which case the system has 64 gtt pages */
434 	if (pg->gtt_start == 0 || gtt_pages == 0) {
435 		dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n");
436 		gtt_pages = 64;
437 		pg->gtt_start = dev_priv->pge_ctl;
438 	}
439 
440 	pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
441 	pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
442 								>> PAGE_SHIFT;
443 	dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
444 
445 	if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
446 		static struct resource fudge;	/* Preferably peppermint */
447 		/* This can occur on CDV systems. Fudge it in this case.
448 		   We really don't care what imaginary space is being allocated
449 		   at this point */
450 		dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n");
451 		pg->gatt_start = 0x40000000;
452 		pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
453 		/* This is a little confusing but in fact the GTT is providing
454 		   a view from the GPU into memory and not vice versa. As such
455 		   this is really allocating space that is not the same as the
456 		   CPU address space on CDV */
457 		fudge.start = 0x40000000;
458 		fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
459 		fudge.name = "fudge";
460 		fudge.flags = IORESOURCE_MEM;
461 		dev_priv->gtt_mem = &fudge;
462 	}
463 
464 	pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
465 	vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
466 								- PAGE_SIZE;
467 
468 	stolen_size = vram_stolen_size;
469 
470 	dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
471 			dev_priv->stolen_base, vram_stolen_size / 1024);
472 
473 	if (resume && (gtt_pages != pg->gtt_pages) &&
474 	    (stolen_size != pg->stolen_size)) {
475 		dev_err(dev->dev, "GTT resume error.\n");
476 		ret = -EINVAL;
477 		goto out_err;
478 	}
479 
480 	pg->gtt_pages = gtt_pages;
481 	pg->stolen_size = stolen_size;
482 	dev_priv->vram_stolen_size = vram_stolen_size;
483 
484 	/*
485 	 *	Map the GTT and the stolen memory area
486 	 */
487 	if (!resume)
488 		dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
489 						gtt_pages << PAGE_SHIFT);
490 	if (!dev_priv->gtt_map) {
491 		dev_err(dev->dev, "Failure to map gtt.\n");
492 		ret = -ENOMEM;
493 		goto out_err;
494 	}
495 
496 	if (!resume)
497 		dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base,
498 						 stolen_size);
499 	if (!dev_priv->vram_addr) {
500 		dev_err(dev->dev, "Failure to map stolen base.\n");
501 		ret = -ENOMEM;
502 		goto out_err;
503 	}
504 
505 	/*
506 	 * Insert vram stolen pages into the GTT
507 	 */
508 
509 	pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
510 	num_pages = vram_stolen_size >> PAGE_SHIFT;
511 	dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
512 		num_pages, pfn_base << PAGE_SHIFT, 0);
513 	for (i = 0; i < num_pages; ++i) {
514 		pte = psb_gtt_mask_pte(pfn_base + i, 0);
515 		iowrite32(pte, dev_priv->gtt_map + i);
516 	}
517 
518 	/*
519 	 * Init rest of GTT to the scratch page to avoid accidents or scribbles
520 	 */
521 
522 	pfn_base = page_to_pfn(dev_priv->scratch_page);
523 	pte = psb_gtt_mask_pte(pfn_base, 0);
524 	for (; i < gtt_pages; ++i)
525 		iowrite32(pte, dev_priv->gtt_map + i);
526 
527 	(void) ioread32(dev_priv->gtt_map + i - 1);
528 	return 0;
529 
530 out_err:
531 	psb_gtt_takedown(dev);
532 	return ret;
533 }
534 
535 int psb_gtt_restore(struct drm_device *dev)
536 {
537 	struct drm_psb_private *dev_priv = dev->dev_private;
538 	struct resource *r = dev_priv->gtt_mem->child;
539 	struct gtt_range *range;
540 	unsigned int restored = 0, total = 0, size = 0;
541 
542 	/* On resume, the gtt_mutex is already initialized */
543 	mutex_lock(&dev_priv->gtt_mutex);
544 	psb_gtt_init(dev, 1);
545 
546 	while (r != NULL) {
547 		range = container_of(r, struct gtt_range, resource);
548 		if (range->pages) {
549 			psb_gtt_insert(dev, range, 1);
550 			size += range->resource.end - range->resource.start;
551 			restored++;
552 		}
553 		r = r->sibling;
554 		total++;
555 	}
556 	mutex_unlock(&dev_priv->gtt_mutex);
557 	DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored,
558 			 total, (size / 1024));
559 
560 	return 0;
561 }
562