drivers/gpu/drm/gma500/gem.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/gma500/gem.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/gma500/gem.c
Extension
.c
Size
10487 bytes
Lines
433
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err < 0) {
			dev_err(dev->dev, "gma500: pin failed: %d\n", err);
			ret = vmf_error(err);
			goto fail;
		}
		pobj->mmapping = 1;
	}

	/* Page relative to the VMA start - we must calculate this ourselves
	   because vmf->pgoff is the fake GEM offset */
	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;

	/* CPU view of the page, don't go via the GART for CPU writes */
	if (pobj->stolen)
		pfn = (dev_priv->stolen_base + pobj->offset) >> PAGE_SHIFT;
	else
		pfn = page_to_pfn(pobj->pages[page_offset]);
	ret = vmf_insert_pfn(vma, vmf->address, pfn);
fail:
	mutex_unlock(&dev_priv->mmap_mutex);

	return ret;
}

/*
 * Memory management
 */

/* Insert vram stolen pages into the GTT. */
static void psb_gem_mm_populate_stolen(struct drm_psb_private *pdev)
{
	struct drm_device *dev = &pdev->dev;
	unsigned int pfn_base;
	unsigned int i, num_pages;
	uint32_t pte;

	pfn_base = pdev->stolen_base >> PAGE_SHIFT;
	num_pages = pdev->vram_stolen_size >> PAGE_SHIFT;

	drm_dbg(dev, "Set up %u stolen pages starting at 0x%08x, GTT offset %dK\n",
		num_pages, pfn_base << PAGE_SHIFT, 0);

	for (i = 0; i < num_pages; ++i) {
		pte = psb_gtt_mask_pte(pfn_base + i, PSB_MMU_CACHED_MEMORY);
		iowrite32(pte, pdev->gtt_map + i);
	}

	(void)ioread32(pdev->gtt_map + i - 1);
}

int psb_gem_mm_init(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
	struct pci_dev *pdev = to_pci_dev(dev->dev);
	unsigned long stolen_size, vram_stolen_size;
	struct psb_gtt *pg;
	int ret;

	mutex_init(&dev_priv->mmap_mutex);

	pg = &dev_priv->gtt;

	pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base);
	vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;

	stolen_size = vram_stolen_size;

	dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
		dev_priv->stolen_base, vram_stolen_size / 1024);

	pg->stolen_size = stolen_size;
	dev_priv->vram_stolen_size = vram_stolen_size;

	dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
	if (!dev_priv->vram_addr) {
		dev_err(dev->dev, "Failure to map stolen base.\n");
		ret = -ENOMEM;
		goto err_mutex_destroy;
	}

	psb_gem_mm_populate_stolen(dev_priv);

	return 0;

err_mutex_destroy:
	mutex_destroy(&dev_priv->mmap_mutex);
	return ret;
}

void psb_gem_mm_fini(struct drm_device *dev)

Annotation

Implementation Notes