block: fix warning with calling smp_processor_id() in preemptible section
[pandora-kernel.git] / drivers / staging / gma500 / psb_gtt.c
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 "psb_drv.h"
24
25
26 /*
27  *      GTT resource allocator - manage page mappings in GTT space
28  */
29
30 /**
31  *      psb_gtt_mask_pte        -       generate GART pte entry
32  *      @pfn: page number to encode
33  *      @type: type of memory in the GART
34  *
35  *      Set the GART entry for the appropriate memory type.
36  */
37 static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
38 {
39         uint32_t mask = PSB_PTE_VALID;
40
41         if (type & PSB_MMU_CACHED_MEMORY)
42                 mask |= PSB_PTE_CACHED;
43         if (type & PSB_MMU_RO_MEMORY)
44                 mask |= PSB_PTE_RO;
45         if (type & PSB_MMU_WO_MEMORY)
46                 mask |= PSB_PTE_WO;
47
48         return (pfn << PAGE_SHIFT) | mask;
49 }
50
51 /**
52  *      psb_gtt_entry           -       find the GART entries for a gtt_range
53  *      @dev: our DRM device
54  *      @r: our GTT range
55  * 
56  *      Given a gtt_range object return the GART offset of the page table
57  *      entries for this gtt_range
58  */
59 u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
60 {
61         struct drm_psb_private *dev_priv = dev->dev_private;
62         unsigned long offset;
63
64         offset = r->resource.start - dev_priv->gtt_mem->start;
65
66         return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
67 }
68
69 /**
70  *      psb_gtt_insert  -       put an object into the GART
71  *      @dev: our DRM device
72  *      @r: our GTT range
73  *
74  *      Take our preallocated GTT range and insert the GEM object into
75  *      the GART.
76  *
77  *      FIXME: gtt lock ?
78  */
79 static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
80 {
81         struct drm_psb_private *dev_priv = dev->dev_private;
82         u32 *gtt_slot, pte;
83         int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
84         struct page **pages;
85         int i;
86
87         if (r->pages == NULL) {
88                 WARN_ON(1);
89                 return -EINVAL;
90         }
91
92         WARN_ON(r->stolen);     /* refcount these maybe ? */
93
94         gtt_slot = psb_gtt_entry(dev, r);
95         pages = r->pages;
96
97         /* Make sure we have no alias present */
98         wbinvd();
99
100         /* Write our page entries into the GART itself */
101         for (i = 0; i < numpages; i++) {
102                 pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
103                 iowrite32(pte, gtt_slot++);
104         }
105         /* Make sure all the entries are set before we return */
106         ioread32(gtt_slot - 1);
107         
108         return 0;
109 }
110
111 /**
112  *      psb_gtt_remove  -       remove an object from the GART
113  *      @dev: our DRM device
114  *      @r: our GTT range
115  *
116  *      Remove a preallocated GTT range from the GART. Overwrite all the
117  *      page table entries with the dummy page
118  */
119
120 static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
121 {
122         struct drm_psb_private *dev_priv = dev->dev_private;
123         u32 *gtt_slot, pte;
124         int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
125         int i;
126
127         WARN_ON(r->stolen);
128
129         gtt_slot = psb_gtt_entry(dev, r);
130         pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
131
132         for (i = 0; i < numpages; i++)
133                 iowrite32(pte, gtt_slot++);
134         ioread32(gtt_slot - 1);
135 }
136
137 /**
138  *      psb_gtt_attach_pages    -       attach and pin GEM pages
139  *      @gt: the gtt range
140  *
141  *      Pin and build an in kernel list of the pages that back our GEM object.
142  *      While we hold this the pages cannot be swapped out
143  *
144  *      FIXME: Do we need to cache flush when we update the GTT
145  */
146 static int psb_gtt_attach_pages(struct gtt_range *gt)
147 {
148         struct inode *inode;
149         struct address_space *mapping;
150         int i;
151         struct page *p;
152         int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
153
154         WARN_ON(gt->pages);
155
156         /* This is the shared memory object that backs the GEM resource */
157         inode = gt->gem.filp->f_path.dentry->d_inode;
158         mapping = inode->i_mapping;
159
160         gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
161         if (gt->pages == NULL)
162                 return -ENOMEM;
163         for (i = 0; i < pages; i++) {
164                 /* FIXME: review flags later */
165                 p = read_cache_page_gfp(mapping, i,
166                                         __GFP_COLD | GFP_KERNEL);
167                 if (IS_ERR(p))
168                         goto err;
169                 gt->pages[i] = p;
170         }
171         return 0;
172
173 err:
174         while (i--)
175                 page_cache_release(gt->pages[i]);
176         kfree(gt->pages);
177         gt->pages = NULL;
178         return PTR_ERR(p);
179 }
180
181 /**
182  *      psb_gtt_detach_pages    -       attach and pin GEM pages
183  *      @gt: the gtt range
184  *
185  *      Undo the effect of psb_gtt_attach_pages. At this point the pages
186  *      must have been removed from the GART as they could now be paged out
187  *      and move bus address.
188  *
189  *      FIXME: Do we need to cache flush when we update the GTT
190  */
191 static void psb_gtt_detach_pages(struct gtt_range *gt)
192 {
193         int i;
194         int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
195
196         for (i = 0; i < pages; i++) {
197                 /* FIXME: do we need to force dirty */
198                 set_page_dirty(gt->pages[i]);
199                 /* Undo the reference we took when populating the table */
200                 page_cache_release(gt->pages[i]);
201         }
202         kfree(gt->pages);
203         gt->pages = NULL;
204 }
205
206 /**
207  *      psb_gtt_pin             -       pin pages into the GTT
208  *      @gt: range to pin
209  *
210  *      Pin a set of pages into the GTT. The pins are refcounted so that
211  *      multiple pins need multiple unpins to undo.
212  *
213  *      Non GEM backed objects treat this as a no-op as they are always GTT
214  *      backed objects.
215  */
216 int psb_gtt_pin(struct gtt_range *gt)
217 {
218         int ret;
219         struct drm_device *dev = gt->gem.dev;
220         struct drm_psb_private *dev_priv = dev->dev_private;
221
222         mutex_lock(&dev_priv->gtt_mutex);
223
224         if (gt->in_gart == 0 && gt->stolen == 0) {
225                 ret = psb_gtt_attach_pages(gt);
226                 if (ret < 0)
227                         goto out;
228                 ret = psb_gtt_insert(dev, gt);
229                 if (ret < 0) {
230                         psb_gtt_detach_pages(gt);
231                         goto out;
232                 }
233         }
234         gt->in_gart++;
235 out:
236         mutex_unlock(&dev_priv->gtt_mutex);
237         return ret;
238 }
239
240 /**
241  *      psb_gtt_unpin           -       Drop a GTT pin requirement
242  *      @gt: range to pin
243  *
244  *      Undoes the effect of psb_gtt_pin. On the last drop the GEM object
245  *      will be removed from the GTT which will also drop the page references
246  *      and allow the VM to clean up or page stuff.
247  *
248  *      Non GEM backed objects treat this as a no-op as they are always GTT
249  *      backed objects.
250  */
251 void psb_gtt_unpin(struct gtt_range *gt)
252 {
253         struct drm_device *dev = gt->gem.dev;
254         struct drm_psb_private *dev_priv = dev->dev_private;
255
256         mutex_lock(&dev_priv->gtt_mutex);
257
258         WARN_ON(!gt->in_gart);
259
260         gt->in_gart--;
261         if (gt->in_gart == 0 && gt->stolen == 0) {
262                 psb_gtt_remove(dev, gt);
263                 psb_gtt_detach_pages(gt);
264         }
265         mutex_unlock(&dev_priv->gtt_mutex);
266 }
267         
268 /*
269  *      GTT resource allocator - allocate and manage GTT address space
270  */
271
272 /**
273  *      psb_gtt_alloc_range     -       allocate GTT address space
274  *      @dev: Our DRM device
275  *      @len: length (bytes) of address space required
276  *      @name: resource name
277  *      @backed: resource should be backed by stolen pages
278  *
279  *      Ask the kernel core to find us a suitable range of addresses
280  *      to use for a GTT mapping.
281  *
282  *      Returns a gtt_range structure describing the object, or NULL on
283  *      error. On successful return the resource is both allocated and marked
284  *      as in use.
285  */
286 struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
287                                                 const char *name, int backed)
288 {
289         struct drm_psb_private *dev_priv = dev->dev_private;
290         struct gtt_range *gt;
291         struct resource *r = dev_priv->gtt_mem;
292         int ret;
293         unsigned long start, end;
294         
295         if (backed) {
296                 /* The start of the GTT is the stolen pages */
297                 start = r->start;
298                 end = r->start + dev_priv->pg->stolen_size - 1;
299         } else {
300                 /* The rest we will use for GEM backed objects */
301                 start = r->start + dev_priv->pg->stolen_size;
302                 end = r->end;
303         }
304
305         gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
306         if (gt == NULL)
307                 return NULL;
308         gt->resource.name = name;
309         gt->stolen = backed;
310         gt->in_gart = backed;
311         /* Ensure this is set for non GEM objects */
312         gt->gem.dev = dev;
313         kref_init(&gt->kref);
314
315         ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
316                                 len, start, end, PAGE_SIZE, NULL, NULL);
317         if (ret == 0) {
318                 gt->offset = gt->resource.start - r->start;
319                 return gt;
320         }
321         kfree(gt);
322         return NULL;
323 }
324
325 /**
326  *      psb_gtt_destroy         -       final free up of a gtt
327  *      @kref: the kref of the gtt
328  *
329  *      Called from the kernel kref put when the final reference to our
330  *      GTT object is dropped. At that point we can free up the resources.
331  *
332  *      For now we handle mmap clean up here to work around limits in GEM
333  */
334 static void psb_gtt_destroy(struct kref *kref)
335 {
336         struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
337
338         /* Undo the mmap pin if we are destroying the object */
339         if (gt->mmapping) {
340                 psb_gtt_unpin(gt);
341                 gt->mmapping = 0;
342         }
343         WARN_ON(gt->in_gart && !gt->stolen);
344         release_resource(&gt->resource);
345         kfree(gt);
346 }
347
348 /**
349  *      psb_gtt_kref_put        -       drop reference to a GTT object
350  *      @gt: the GT being dropped
351  *
352  *      Drop a reference to a psb gtt
353  */
354 void psb_gtt_kref_put(struct gtt_range *gt)
355 {
356         kref_put(&gt->kref, psb_gtt_destroy);
357 }
358
359 /**
360  *      psb_gtt_free_range      -       release GTT address space
361  *      @dev: our DRM device
362  *      @gt: a mapping created with psb_gtt_alloc_range
363  *
364  *      Release a resource that was allocated with psb_gtt_alloc_range
365  */
366 void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
367 {
368         psb_gtt_kref_put(gt);
369 }
370
371
372 struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
373 {
374         struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
375
376         if (!tmp)
377                 return NULL;
378
379         init_rwsem(&tmp->sem);
380         tmp->dev = dev;
381
382         return tmp;
383 }
384
385 void psb_gtt_takedown(struct drm_device *dev)
386 {
387         struct drm_psb_private *dev_priv = dev->dev_private;
388
389         /* FIXME: iounmap dev_priv->vram_addr etc */
390         if (dev_priv->gtt_map) {
391                 iounmap(dev_priv->gtt_map);
392                 dev_priv->gtt_map = NULL;
393         }
394         if (dev_priv->gtt_initialized) {
395                 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
396                                       dev_priv->gmch_ctrl);
397                 PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
398                 (void) PSB_RVDC32(PSB_PGETBL_CTL);
399         }
400         kfree(dev_priv->pg);
401         dev_priv->pg = NULL;
402 }
403
404 int psb_gtt_init(struct drm_device *dev, int resume)
405 {
406         struct drm_psb_private *dev_priv = dev->dev_private;
407         unsigned gtt_pages;
408         unsigned long stolen_size, vram_stolen_size;
409         unsigned i, num_pages;
410         unsigned pfn_base;
411         uint32_t vram_pages;
412         uint32_t tt_pages;
413         uint32_t *ttm_gtt_map;
414         uint32_t dvmt_mode = 0;
415         struct psb_gtt *pg;
416
417         int ret = 0;
418         uint32_t pte;
419
420         mutex_init(&dev_priv->gtt_mutex);
421
422         dev_priv->pg = pg = psb_gtt_alloc(dev);
423         if (pg == NULL)
424                 return -ENOMEM;
425
426         pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
427         pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
428                               dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
429
430         dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
431         PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
432         (void) PSB_RVDC32(PSB_PGETBL_CTL);
433
434         /* The root resource we allocate address space from */
435         dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
436
437         dev_priv->gtt_initialized = 1;
438
439         pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
440
441         pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
442         /* fix me: video mmu has hw bug to access 0x0D0000000,
443          * then make gatt start at 0x0e000,0000 */
444         pg->mmu_gatt_start = 0xE0000000;
445         pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
446         gtt_pages =
447             pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
448         pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
449             >> PAGE_SHIFT;
450
451         pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
452         vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
453
454         stolen_size = vram_stolen_size;
455
456         printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
457                 pg->gatt_start, pg->gatt_pages/256);
458         printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
459                 pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
460         printk(KERN_INFO "Stolen memory information\n");
461         printk(KERN_INFO "       base in RAM: 0x%x\n", dev_priv->stolen_base);
462         printk(KERN_INFO "       size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
463                 vram_stolen_size/1024);
464         dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
465         printk(KERN_INFO "      the correct size should be: %dM(dvmt mode=%d)\n",
466                 (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
467
468         if (resume && (gtt_pages != pg->gtt_pages) &&
469             (stolen_size != pg->stolen_size)) {
470                 DRM_ERROR("GTT resume error.\n");
471                 ret = -EINVAL;
472                 goto out_err;
473         }
474
475         pg->gtt_pages = gtt_pages;
476         pg->stolen_size = stolen_size;
477         dev_priv->vram_stolen_size = vram_stolen_size;
478         dev_priv->gtt_map =
479             ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
480         if (!dev_priv->gtt_map) {
481                 DRM_ERROR("Failure to map gtt.\n");
482                 ret = -ENOMEM;
483                 goto out_err;
484         }
485
486         dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
487         if (!dev_priv->vram_addr) {
488                 DRM_ERROR("Failure to map stolen base.\n");
489                 ret = -ENOMEM;
490                 goto out_err;
491         }
492
493         DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr);
494
495         tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
496                 (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
497
498         ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2;
499
500         /*
501          * insert vram stolen pages.
502          */
503
504         pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
505         vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
506         printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
507                 num_pages, pfn_base, 0);
508         for (i = 0; i < num_pages; ++i) {
509                 pte = psb_gtt_mask_pte(pfn_base + i, 0);
510                 iowrite32(pte, dev_priv->gtt_map + i);
511         }
512
513         /*
514          * Init rest of gtt managed by IMG.
515          */
516         pfn_base = page_to_pfn(dev_priv->scratch_page);
517         pte = psb_gtt_mask_pte(pfn_base, 0);
518         for (; i < tt_pages / 2 - 1; ++i)
519                 iowrite32(pte, dev_priv->gtt_map + i);
520
521         /*
522          * Init rest of gtt managed by TTM.
523          */
524
525         pfn_base = page_to_pfn(dev_priv->scratch_page);
526         pte = psb_gtt_mask_pte(pfn_base, 0);
527         PSB_DEBUG_INIT("Initializing the rest of a total "
528                        "of %d gtt pages.\n", pg->gatt_pages);
529
530         for (; i < pg->gatt_pages - tt_pages / 2; ++i)
531                 iowrite32(pte, ttm_gtt_map + i);
532         (void) ioread32(dev_priv->gtt_map + i - 1);
533
534         return 0;
535
536 out_err:
537         psb_gtt_takedown(dev);
538         return ret;
539 }