Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gtt.c
Go to the documentation of this file.
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 <[email protected]>
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 
38 static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
39 {
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 
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 
83 static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
84 {
85  u32 __iomem *gtt_slot;
86  u32 pte;
87  struct page **pages;
88  int i;
89 
90  if (r->pages == NULL) {
91  WARN_ON(1);
92  return -EINVAL;
93  }
94 
95  WARN_ON(r->stolen); /* refcount these maybe ? */
96 
97  gtt_slot = psb_gtt_entry(dev, r);
98  pages = r->pages;
99 
100  /* Make sure changes are visible to the GPU */
101  set_pages_array_wc(pages, r->npage);
102 
103  /* Write our page entries into the GTT itself */
104  for (i = r->roll; i < r->npage; i++) {
105  pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
106  iowrite32(pte, gtt_slot++);
107  }
108  for (i = 0; i < r->roll; i++) {
109  pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
110  iowrite32(pte, gtt_slot++);
111  }
112  /* Make sure all the entries are set before we return */
113  ioread32(gtt_slot - 1);
114 
115  return 0;
116 }
117 
127 static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
128 {
129  struct drm_psb_private *dev_priv = dev->dev_private;
130  u32 __iomem *gtt_slot;
131  u32 pte;
132  int i;
133 
134  WARN_ON(r->stolen);
135 
136  gtt_slot = psb_gtt_entry(dev, r);
137  pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
138 
139  for (i = 0; i < r->npage; i++)
140  iowrite32(pte, gtt_slot++);
141  ioread32(gtt_slot - 1);
143 }
144 
155 void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
156 {
157  u32 __iomem *gtt_slot;
158  u32 pte;
159  int i;
160 
161  if (roll >= r->npage) {
162  WARN_ON(1);
163  return;
164  }
165 
166  r->roll = roll;
167 
168  /* Not currently in the GTT - no worry we will write the mapping at
169  the right position when it gets pinned */
170  if (!r->stolen && !r->in_gart)
171  return;
172 
173  gtt_slot = psb_gtt_entry(dev, r);
174 
175  for (i = r->roll; i < r->npage; i++) {
176  pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
177  iowrite32(pte, gtt_slot++);
178  }
179  for (i = 0; i < r->roll; i++) {
180  pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
181  iowrite32(pte, gtt_slot++);
182  }
183  ioread32(gtt_slot - 1);
184 }
185 
194 static int psb_gtt_attach_pages(struct gtt_range *gt)
195 {
196  struct inode *inode;
197  struct address_space *mapping;
198  int i;
199  struct page *p;
200  int pages = gt->gem.size / PAGE_SIZE;
201 
202  WARN_ON(gt->pages);
203 
204  /* This is the shared memory object that backs the GEM resource */
205  inode = gt->gem.filp->f_path.dentry->d_inode;
206  mapping = inode->i_mapping;
207 
208  gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
209  if (gt->pages == NULL)
210  return -ENOMEM;
211  gt->npage = pages;
212 
213  for (i = 0; i < pages; i++) {
214  p = shmem_read_mapping_page(mapping, i);
215  if (IS_ERR(p))
216  goto err;
217  gt->pages[i] = p;
218  }
219  return 0;
220 
221 err:
222  while (i--)
223  page_cache_release(gt->pages[i]);
224  kfree(gt->pages);
225  gt->pages = NULL;
226  return PTR_ERR(p);
227 }
228 
238 static void psb_gtt_detach_pages(struct gtt_range *gt)
239 {
240  int i;
241  for (i = 0; i < gt->npage; i++) {
242  /* FIXME: do we need to force dirty */
243  set_page_dirty(gt->pages[i]);
244  page_cache_release(gt->pages[i]);
245  }
246  kfree(gt->pages);
247  gt->pages = NULL;
248 }
249 
260 int psb_gtt_pin(struct gtt_range *gt)
261 {
262  int ret = 0;
263  struct drm_device *dev = gt->gem.dev;
264  struct drm_psb_private *dev_priv = dev->dev_private;
265 
266  mutex_lock(&dev_priv->gtt_mutex);
267 
268  if (gt->in_gart == 0 && gt->stolen == 0) {
269  ret = psb_gtt_attach_pages(gt);
270  if (ret < 0)
271  goto out;
272  ret = psb_gtt_insert(dev, gt);
273  if (ret < 0) {
274  psb_gtt_detach_pages(gt);
275  goto out;
276  }
277  }
278  gt->in_gart++;
279 out:
280  mutex_unlock(&dev_priv->gtt_mutex);
281  return ret;
282 }
283 
295 void psb_gtt_unpin(struct gtt_range *gt)
296 {
297  struct drm_device *dev = gt->gem.dev;
298  struct drm_psb_private *dev_priv = dev->dev_private;
299 
300  mutex_lock(&dev_priv->gtt_mutex);
301 
302  WARN_ON(!gt->in_gart);
303 
304  gt->in_gart--;
305  if (gt->in_gart == 0 && gt->stolen == 0) {
306  psb_gtt_remove(dev, gt);
307  psb_gtt_detach_pages(gt);
308  }
309  mutex_unlock(&dev_priv->gtt_mutex);
310 }
311 
312 /*
313  * GTT resource allocator - allocate and manage GTT address space
314  */
315 
330 struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
331  const char *name, int backed)
332 {
333  struct drm_psb_private *dev_priv = dev->dev_private;
334  struct gtt_range *gt;
335  struct resource *r = dev_priv->gtt_mem;
336  int ret;
337  unsigned long start, end;
338 
339  if (backed) {
340  /* The start of the GTT is the stolen pages */
341  start = r->start;
342  end = r->start + dev_priv->gtt.stolen_size - 1;
343  } else {
344  /* The rest we will use for GEM backed objects */
345  start = r->start + dev_priv->gtt.stolen_size;
346  end = r->end;
347  }
348 
349  gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
350  if (gt == NULL)
351  return NULL;
352  gt->resource.name = name;
353  gt->stolen = backed;
354  gt->in_gart = backed;
355  gt->roll = 0;
356  /* Ensure this is set for non GEM objects */
357  gt->gem.dev = dev;
358  ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
359  len, start, end, PAGE_SIZE, NULL, NULL);
360  if (ret == 0) {
361  gt->offset = gt->resource.start - r->start;
362  return gt;
363  }
364  kfree(gt);
365  return NULL;
366 }
367 
376 void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
377 {
378  /* Undo the mmap pin if we are destroying the object */
379  if (gt->mmapping) {
380  psb_gtt_unpin(gt);
381  gt->mmapping = 0;
382  }
383  WARN_ON(gt->in_gart && !gt->stolen);
385  kfree(gt);
386 }
387 
388 static void psb_gtt_alloc(struct drm_device *dev)
389 {
390  struct drm_psb_private *dev_priv = dev->dev_private;
391  init_rwsem(&dev_priv->gtt.sem);
392 }
393 
394 void psb_gtt_takedown(struct drm_device *dev)
395 {
396  struct drm_psb_private *dev_priv = dev->dev_private;
397 
398  if (dev_priv->gtt_map) {
399  iounmap(dev_priv->gtt_map);
400  dev_priv->gtt_map = NULL;
401  }
402  if (dev_priv->gtt_initialized) {
403  pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
404  dev_priv->gmch_ctrl);
405  PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
407  }
408  if (dev_priv->vram_addr)
409  iounmap(dev_priv->gtt_map);
410 }
411 
412 int psb_gtt_init(struct drm_device *dev, int resume)
413 {
414  struct drm_psb_private *dev_priv = dev->dev_private;
415  unsigned gtt_pages;
416  unsigned long stolen_size, vram_stolen_size;
417  unsigned i, num_pages;
418  unsigned pfn_base;
419  struct psb_gtt *pg;
420 
421  int ret = 0;
422  uint32_t pte;
423 
424  mutex_init(&dev_priv->gtt_mutex);
425 
426  psb_gtt_alloc(dev);
427  pg = &dev_priv->gtt;
428 
429  /* Enable the GTT */
430  pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
431  pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
432  dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
433 
434  dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
437 
438  /* The root resource we allocate address space from */
439  dev_priv->gtt_initialized = 1;
440 
441  pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
442 
443  /*
444  * The video mmu has a hw bug when accessing 0x0D0000000.
445  * Make gatt start at 0x0e000,0000. This doesn't actually
446  * matter for us but may do if the video acceleration ever
447  * gets opened up.
448  */
449  pg->mmu_gatt_start = 0xE0000000;
450 
452  gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
453  >> PAGE_SHIFT;
454  /* CDV doesn't report this. In which case the system has 64 gtt pages */
455  if (pg->gtt_start == 0 || gtt_pages == 0) {
456  dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n");
457  gtt_pages = 64;
458  pg->gtt_start = dev_priv->pge_ctl;
459  }
460 
463  >> PAGE_SHIFT;
464  dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
465 
466  if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
467  static struct resource fudge; /* Preferably peppermint */
468  /* This can occur on CDV systems. Fudge it in this case.
469  We really don't care what imaginary space is being allocated
470  at this point */
471  dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n");
472  pg->gatt_start = 0x40000000;
473  pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
474  /* This is a little confusing but in fact the GTT is providing
475  a view from the GPU into memory and not vice versa. As such
476  this is really allocating space that is not the same as the
477  CPU address space on CDV */
478  fudge.start = 0x40000000;
479  fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
480  fudge.name = "fudge";
481  fudge.flags = IORESOURCE_MEM;
482  dev_priv->gtt_mem = &fudge;
483  }
484 
485  pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
486  vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
487  - PAGE_SIZE;
488 
489  stolen_size = vram_stolen_size;
490 
491  dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n",
492  dev_priv->stolen_base, vram_stolen_size / 1024);
493 
494  if (resume && (gtt_pages != pg->gtt_pages) &&
495  (stolen_size != pg->stolen_size)) {
496  dev_err(dev->dev, "GTT resume error.\n");
497  ret = -EINVAL;
498  goto out_err;
499  }
500 
501  pg->gtt_pages = gtt_pages;
502  pg->stolen_size = stolen_size;
503  dev_priv->vram_stolen_size = vram_stolen_size;
504 
505  /*
506  * Map the GTT and the stolen memory area
507  */
508  dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
509  gtt_pages << PAGE_SHIFT);
510  if (!dev_priv->gtt_map) {
511  dev_err(dev->dev, "Failure to map gtt.\n");
512  ret = -ENOMEM;
513  goto out_err;
514  }
515 
516  dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
517  if (!dev_priv->vram_addr) {
518  dev_err(dev->dev, "Failure to map stolen base.\n");
519  ret = -ENOMEM;
520  goto out_err;
521  }
522 
523  /*
524  * Insert vram stolen pages into the GTT
525  */
526 
527  pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
528  num_pages = vram_stolen_size >> PAGE_SHIFT;
529  dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
530  num_pages, pfn_base << PAGE_SHIFT, 0);
531  for (i = 0; i < num_pages; ++i) {
532  pte = psb_gtt_mask_pte(pfn_base + i, 0);
533  iowrite32(pte, dev_priv->gtt_map + i);
534  }
535 
536  /*
537  * Init rest of GTT to the scratch page to avoid accidents or scribbles
538  */
539 
540  pfn_base = page_to_pfn(dev_priv->scratch_page);
541  pte = psb_gtt_mask_pte(pfn_base, 0);
542  for (; i < gtt_pages; ++i)
543  iowrite32(pte, dev_priv->gtt_map + i);
544 
545  (void) ioread32(dev_priv->gtt_map + i - 1);
546  return 0;
547 
548 out_err:
549  psb_gtt_takedown(dev);
550  return ret;
551 }