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