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