Lines Matching +full:resume +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
19 * GTT resource allocator - manage page mappings in GTT space
23 * psb_gtt_mask_pte - generate GTT pte entry
48 * psb_gtt_entry - find the GTT entries for a gtt_range
52 * Given a gtt_range object return the GTT offset of the page table
57 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_entry()
58 unsigned long offset; in psb_gtt_entry() local
60 offset = r->resource.start - dev_priv->gtt_mem->start; in psb_gtt_entry()
62 return dev_priv->gtt_map + (offset >> PAGE_SHIFT); in psb_gtt_entry()
66 * psb_gtt_insert - put an object into the GTT
69 * @resume: on resume
76 int resume) in psb_gtt_insert() argument
83 if (r->pages == NULL) { in psb_gtt_insert()
85 return -EINVAL; in psb_gtt_insert()
88 WARN_ON(r->stolen); /* refcount these maybe ? */ in psb_gtt_insert()
91 pages = r->pages; in psb_gtt_insert()
93 if (!resume) { in psb_gtt_insert()
95 set_pages_array_wc(pages, r->npage); in psb_gtt_insert()
99 for (i = r->roll; i < r->npage; i++) { in psb_gtt_insert()
100 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), in psb_gtt_insert()
104 for (i = 0; i < r->roll; i++) { in psb_gtt_insert()
105 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), in psb_gtt_insert()
110 ioread32(gtt_slot - 1); in psb_gtt_insert()
116 * psb_gtt_remove - remove an object from the GTT
126 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_remove()
131 WARN_ON(r->stolen); in psb_gtt_remove()
134 pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), in psb_gtt_remove()
137 for (i = 0; i < r->npage; i++) in psb_gtt_remove()
139 ioread32(gtt_slot - 1); in psb_gtt_remove()
140 set_pages_array_wb(r->pages, r->npage); in psb_gtt_remove()
144 * psb_gtt_roll - set scrolling position
147 * @roll: roll offset
159 if (roll >= r->npage) { in psb_gtt_roll()
164 r->roll = roll; in psb_gtt_roll()
166 /* Not currently in the GTT - no worry we will write the mapping at in psb_gtt_roll()
168 if (!r->stolen && !r->in_gart) in psb_gtt_roll()
173 for (i = r->roll; i < r->npage; i++) { in psb_gtt_roll()
174 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), in psb_gtt_roll()
178 for (i = 0; i < r->roll; i++) { in psb_gtt_roll()
179 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), in psb_gtt_roll()
183 ioread32(gtt_slot - 1); in psb_gtt_roll()
187 * psb_gtt_attach_pages - attach and pin GEM pages
198 WARN_ON(gt->pages); in psb_gtt_attach_pages()
200 pages = drm_gem_get_pages(>->gem); in psb_gtt_attach_pages()
204 gt->npage = gt->gem.size / PAGE_SIZE; in psb_gtt_attach_pages()
205 gt->pages = pages; in psb_gtt_attach_pages()
211 * psb_gtt_detach_pages - attach and pin GEM pages
221 drm_gem_put_pages(>->gem, gt->pages, true, false); in psb_gtt_detach_pages()
222 gt->pages = NULL; in psb_gtt_detach_pages()
226 * psb_gtt_pin - pin pages into the GTT
232 * Non GEM backed objects treat this as a no-op as they are always GTT
238 struct drm_device *dev = gt->gem.dev; in psb_gtt_pin()
239 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_pin()
240 u32 gpu_base = dev_priv->gtt.gatt_start; in psb_gtt_pin()
242 mutex_lock(&dev_priv->gtt_mutex); in psb_gtt_pin()
244 if (gt->in_gart == 0 && gt->stolen == 0) { in psb_gtt_pin()
253 psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), in psb_gtt_pin()
254 gt->pages, (gpu_base + gt->offset), in psb_gtt_pin()
255 gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); in psb_gtt_pin()
257 gt->in_gart++; in psb_gtt_pin()
259 mutex_unlock(&dev_priv->gtt_mutex); in psb_gtt_pin()
264 * psb_gtt_unpin - Drop a GTT pin requirement
271 * Non GEM backed objects treat this as a no-op as they are always GTT
276 struct drm_device *dev = gt->gem.dev; in psb_gtt_unpin()
277 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_unpin()
278 u32 gpu_base = dev_priv->gtt.gatt_start; in psb_gtt_unpin()
282 mutex_lock(&dev_priv->gtt_mutex); in psb_gtt_unpin()
291 WARN_ON(!gt->in_gart); in psb_gtt_unpin()
293 gt->in_gart--; in psb_gtt_unpin()
294 if (gt->in_gart == 0 && gt->stolen == 0) { in psb_gtt_unpin()
295 psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), in psb_gtt_unpin()
296 (gpu_base + gt->offset), gt->npage, 0, 0); in psb_gtt_unpin()
302 mutex_unlock(&dev_priv->gtt_mutex); in psb_gtt_unpin()
306 * GTT resource allocator - allocate and manage GTT address space
310 * psb_gtt_alloc_range - allocate GTT address space
327 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_alloc_range()
329 struct resource *r = dev_priv->gtt_mem; in psb_gtt_alloc_range()
335 start = r->start; in psb_gtt_alloc_range()
336 end = r->start + dev_priv->gtt.stolen_size - 1; in psb_gtt_alloc_range()
339 start = r->start + dev_priv->gtt.stolen_size; in psb_gtt_alloc_range()
340 end = r->end; in psb_gtt_alloc_range()
346 gt->resource.name = name; in psb_gtt_alloc_range()
347 gt->stolen = backed; in psb_gtt_alloc_range()
348 gt->in_gart = backed; in psb_gtt_alloc_range()
349 gt->roll = 0; in psb_gtt_alloc_range()
351 gt->gem.dev = dev; in psb_gtt_alloc_range()
352 ret = allocate_resource(dev_priv->gtt_mem, >->resource, in psb_gtt_alloc_range()
355 gt->offset = gt->resource.start - r->start; in psb_gtt_alloc_range()
363 * psb_gtt_free_range - release GTT address space
373 if (gt->mmapping) { in psb_gtt_free_range()
375 gt->mmapping = 0; in psb_gtt_free_range()
377 WARN_ON(gt->in_gart && !gt->stolen); in psb_gtt_free_range()
378 release_resource(>->resource); in psb_gtt_free_range()
384 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_alloc()
385 init_rwsem(&dev_priv->gtt.sem); in psb_gtt_alloc()
390 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_takedown()
392 if (dev_priv->gtt_map) { in psb_gtt_takedown()
393 iounmap(dev_priv->gtt_map); in psb_gtt_takedown()
394 dev_priv->gtt_map = NULL; in psb_gtt_takedown()
396 if (dev_priv->gtt_initialized) { in psb_gtt_takedown()
397 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, in psb_gtt_takedown()
398 dev_priv->gmch_ctrl); in psb_gtt_takedown()
399 PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); in psb_gtt_takedown()
402 if (dev_priv->vram_addr) in psb_gtt_takedown()
403 iounmap(dev_priv->gtt_map); in psb_gtt_takedown()
406 int psb_gtt_init(struct drm_device *dev, int resume) in psb_gtt_init() argument
408 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_init()
418 if (!resume) { in psb_gtt_init()
419 mutex_init(&dev_priv->gtt_mutex); in psb_gtt_init()
420 mutex_init(&dev_priv->mmap_mutex); in psb_gtt_init()
424 pg = &dev_priv->gtt; in psb_gtt_init()
427 pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); in psb_gtt_init()
428 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, in psb_gtt_init()
429 dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); in psb_gtt_init()
431 dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); in psb_gtt_init()
432 PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); in psb_gtt_init()
436 dev_priv->gtt_initialized = 1; in psb_gtt_init()
438 pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; in psb_gtt_init()
446 pg->mmu_gatt_start = 0xE0000000; in psb_gtt_init()
448 pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); in psb_gtt_init()
449 gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) in psb_gtt_init()
452 if (pg->gtt_start == 0 || gtt_pages == 0) { in psb_gtt_init()
453 dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); in psb_gtt_init()
455 pg->gtt_start = dev_priv->pge_ctl; in psb_gtt_init()
458 pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); in psb_gtt_init()
459 pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) in psb_gtt_init()
461 dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE]; in psb_gtt_init()
463 if (pg->gatt_pages == 0 || pg->gatt_start == 0) { in psb_gtt_init()
468 dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n"); in psb_gtt_init()
469 pg->gatt_start = 0x40000000; in psb_gtt_init()
470 pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; in psb_gtt_init()
476 fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; in psb_gtt_init()
479 dev_priv->gtt_mem = &fudge; in psb_gtt_init()
482 pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base); in psb_gtt_init()
483 vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base in psb_gtt_init()
484 - PAGE_SIZE; in psb_gtt_init()
488 dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", in psb_gtt_init()
489 dev_priv->stolen_base, vram_stolen_size / 1024); in psb_gtt_init()
491 if (resume && (gtt_pages != pg->gtt_pages) && in psb_gtt_init()
492 (stolen_size != pg->stolen_size)) { in psb_gtt_init()
493 dev_err(dev->dev, "GTT resume error.\n"); in psb_gtt_init()
494 ret = -EINVAL; in psb_gtt_init()
498 pg->gtt_pages = gtt_pages; in psb_gtt_init()
499 pg->stolen_size = stolen_size; in psb_gtt_init()
500 dev_priv->vram_stolen_size = vram_stolen_size; in psb_gtt_init()
505 if (!resume) in psb_gtt_init()
506 dev_priv->gtt_map = ioremap(pg->gtt_phys_start, in psb_gtt_init()
508 if (!dev_priv->gtt_map) { in psb_gtt_init()
509 dev_err(dev->dev, "Failure to map gtt.\n"); in psb_gtt_init()
510 ret = -ENOMEM; in psb_gtt_init()
514 if (!resume) in psb_gtt_init()
515 dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, in psb_gtt_init()
518 if (!dev_priv->vram_addr) { in psb_gtt_init()
519 dev_err(dev->dev, "Failure to map stolen base.\n"); in psb_gtt_init()
520 ret = -ENOMEM; in psb_gtt_init()
528 pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; in psb_gtt_init()
530 dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", in psb_gtt_init()
534 iowrite32(pte, dev_priv->gtt_map + i); in psb_gtt_init()
541 pfn_base = page_to_pfn(dev_priv->scratch_page); in psb_gtt_init()
544 iowrite32(pte, dev_priv->gtt_map + i); in psb_gtt_init()
546 (void) ioread32(dev_priv->gtt_map + i - 1); in psb_gtt_init()
556 struct drm_psb_private *dev_priv = dev->dev_private; in psb_gtt_restore()
557 struct resource *r = dev_priv->gtt_mem->child; in psb_gtt_restore()
561 /* On resume, the gtt_mutex is already initialized */ in psb_gtt_restore()
562 mutex_lock(&dev_priv->gtt_mutex); in psb_gtt_restore()
567 if (range->pages) { in psb_gtt_restore()
569 size += range->resource.end - range->resource.start; in psb_gtt_restore()
572 r = r->sibling; in psb_gtt_restore()
575 mutex_unlock(&dev_priv->gtt_mutex); in psb_gtt_restore()