2 * Copyright (c) 2007, Intel Corporation.
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.
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
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.
18 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
23 #include "psb_pvr_glue.h"
25 static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
27 uint32_t mask = PSB_PTE_VALID;
29 if (type & PSB_MMU_CACHED_MEMORY)
30 mask |= PSB_PTE_CACHED;
31 if (type & PSB_MMU_RO_MEMORY)
33 if (type & PSB_MMU_WO_MEMORY)
36 return (pfn << PAGE_SHIFT) | mask;
39 struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
41 struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
46 init_rwsem(&tmp->sem);
52 void psb_gtt_takedown(struct psb_gtt *pg, int free)
54 struct drm_psb_private *dev_priv = pg->dev->dev_private;
63 if (pg->initialized) {
64 pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
66 PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
67 (void) PSB_RVDC32(PSB_PGETBL_CTL);
73 int psb_gtt_init(struct psb_gtt *pg, int resume)
75 struct drm_device *dev = pg->dev;
76 struct drm_psb_private *dev_priv = dev->dev_private;
78 unsigned long stolen_size, vram_stolen_size, ci_stolen_size;
79 unsigned i, num_pages;
81 uint32_t ci_pages, vram_pages;
83 uint32_t *ttm_gtt_map;
84 uint32_t dvmt_mode = 0;
89 pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
90 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
91 pg->gmch_ctrl | _PSB_GMCH_ENABLED);
93 pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
94 PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
95 (void) PSB_RVDC32(PSB_PGETBL_CTL);
99 pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK;
101 pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
102 /* fix me: video mmu has hw bug to access 0x0D0000000,
103 * then make gatt start at 0x0e000,0000 */
104 pg->mmu_gatt_start = PSB_MEM_TT_START;
105 pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
107 pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
108 pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
111 pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
112 vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
114 /* CI is not included in the stolen size since the TOPAZ MMU bug */
115 ci_stolen_size = dev_priv->ci_region_size;
116 /* Don't add CI & RAR share buffer space
117 * managed by TTM to stolen_size */
118 stolen_size = vram_stolen_size;
120 printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
121 pg->gatt_start, pg->gatt_pages/256);
122 printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
123 pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
124 printk(KERN_INFO "Stole memory information\n");
125 printk(KERN_INFO " base in RAM: 0x%x\n", pg->stolen_base);
126 printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
127 vram_stolen_size/1024);
128 dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7;
129 printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n",
130 (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
132 if (ci_stolen_size > 0)
133 printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n",
134 dev_priv->ci_region_start,
135 ci_stolen_size / 1024 / 1024);
137 if (resume && (gtt_pages != pg->gtt_pages) &&
138 (stolen_size != pg->stolen_size)) {
139 DRM_ERROR("GTT resume error.\n");
144 pg->gtt_pages = gtt_pages;
145 pg->stolen_size = stolen_size;
146 pg->vram_stolen_size = vram_stolen_size;
147 pg->ci_stolen_size = ci_stolen_size;
149 ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
151 DRM_ERROR("Failure to map gtt.\n");
156 pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size);
157 if (!pg->vram_addr) {
158 DRM_ERROR("Failure to map stolen base.\n");
163 DRM_DEBUG("%s: vram kernel virtual address %p\n", pg->vram_addr);
165 tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
166 (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
168 ttm_gtt_map = pg->gtt_map + tt_pages / 2;
171 * insert vram stolen pages.
174 pfn_base = pg->stolen_base >> PAGE_SHIFT;
175 vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
176 printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
177 num_pages, pfn_base, 0);
178 for (i = 0; i < num_pages; ++i) {
179 pte = psb_gtt_mask_pte(pfn_base + i, 0);
180 iowrite32(pte, pg->gtt_map + i);
184 * Init rest of gtt managed by IMG.
186 pfn_base = page_to_pfn(dev_priv->scratch_page);
187 pte = psb_gtt_mask_pte(pfn_base, 0);
188 for (; i < tt_pages / 2 - 1; ++i)
189 iowrite32(pte, pg->gtt_map + i);
192 * insert CI stolen pages
195 pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT;
196 ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT;
197 printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n",
198 num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4);
199 for (i = 0; i < num_pages; ++i) {
200 pte = psb_gtt_mask_pte(pfn_base + i, 0);
201 iowrite32(pte, ttm_gtt_map + i);
205 * Init rest of gtt managed by TTM.
208 pfn_base = page_to_pfn(dev_priv->scratch_page);
209 pte = psb_gtt_mask_pte(pfn_base, 0);
210 PSB_DEBUG_INIT("Initializing the rest of a total "
211 "of %d gtt pages.\n", pg->gatt_pages);
213 for (; i < pg->gatt_pages - tt_pages / 2; ++i)
214 iowrite32(pte, ttm_gtt_map + i);
215 (void) ioread32(pg->gtt_map + i - 1);
220 psb_gtt_takedown(pg, 0);
224 int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
225 unsigned offset_pages, unsigned num_pages,
226 unsigned desired_tile_stride,
227 unsigned hw_tile_stride, int type)
234 uint32_t *cur_page = NULL;
238 rows = num_pages / desired_tile_stride;
240 desired_tile_stride = num_pages;
242 add = desired_tile_stride;
243 row_add = hw_tile_stride;
246 for (i = 0; i < rows; ++i) {
247 cur_page = pg->gtt_map + offset_pages;
248 for (j = 0; j < desired_tile_stride; ++j) {
250 psb_gtt_mask_pte(page_to_pfn(*pages++), type);
251 iowrite32(pte, cur_page++);
255 (void) ioread32(cur_page - 1);
261 int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, dma_addr_t *pPhysFrames,
262 unsigned offset_pages, unsigned num_pages, int type)
265 uint32_t *cur_page = NULL;
270 cur_page = pg->gtt_map + offset_pages;
271 for (j = 0; j < num_pages; ++j) {
273 pte = psb_gtt_mask_pte(ba >> PAGE_SHIFT, type);
274 iowrite32(pte, cur_page++);
276 (void) ioread32(cur_page - 1);
281 int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
282 unsigned num_pages, unsigned desired_tile_stride,
283 unsigned hw_tile_stride, int rc_prot)
285 struct drm_psb_private *dev_priv = pg->dev->dev_private;
291 uint32_t *cur_page = NULL;
292 unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
293 uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
296 rows = num_pages / desired_tile_stride;
298 desired_tile_stride = num_pages;
300 add = desired_tile_stride;
301 row_add = hw_tile_stride;
305 for (i = 0; i < rows; ++i) {
306 cur_page = pg->gtt_map + offset_pages;
307 for (j = 0; j < desired_tile_stride; ++j)
308 iowrite32(pte, cur_page++);
312 (void) ioread32(cur_page - 1);
319 int psb_gtt_mm_init(struct psb_gtt *pg)
321 struct psb_gtt_mm *gtt_mm;
322 struct drm_psb_private *dev_priv = pg->dev->dev_private;
323 struct drm_open_hash *ht;
329 if (!pg || !pg->initialized) {
330 DRM_DEBUG("Invalid gtt struct\n");
334 gtt_mm = kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL);
338 spin_lock_init(>t_mm->lock);
341 ret = drm_ht_create(ht, 20);
343 DRM_DEBUG("Create hash table failed(%d)\n", ret);
347 tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
348 tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages;
349 tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
350 (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
354 /*will use tt_start ~ 128M for IMG TT buffers*/
355 ret = drm_mm_init(mm, tt_start, ((tt_size / 2) - tt_start));
357 DRM_DEBUG("drm_mm_int error(%d)\n", ret);
363 dev_priv->gtt_mm = gtt_mm;
365 DRM_INFO("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n",
366 (unsigned long)tt_start,
367 (unsigned long)((tt_size / 2) - tt_start));
378 * Delete all hash entries;
380 void psb_gtt_mm_takedown(void)
385 static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm,
387 struct psb_gtt_hash_entry **hentry)
389 struct drm_hash_item *entry;
390 struct psb_gtt_hash_entry *psb_entry;
393 ret = drm_ht_find_item(&mm->hash, tgid, &entry);
395 DRM_DEBUG("Cannot find entry pid=%ld\n", tgid);
399 psb_entry = container_of(entry, struct psb_gtt_hash_entry, item);
401 DRM_DEBUG("Invalid entry");
410 static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm,
412 struct psb_gtt_hash_entry *hentry)
414 struct drm_hash_item *item;
418 DRM_DEBUG("Invalid parameters\n");
422 item = &hentry->item;
426 * NOTE: drm_ht_insert_item will perform such a check
427 ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp);
429 DRM_DEBUG("Entry already exists for pid %ld\n", tgid);
434 /*Insert the given entry*/
435 ret = drm_ht_insert_item(&mm->hash, item);
437 DRM_DEBUG("Insert failure\n");
446 static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm,
448 struct psb_gtt_hash_entry **entry)
450 struct psb_gtt_hash_entry *hentry;
453 /*if the hentry for this tgid exists, just get it and return*/
454 spin_lock(&mm->lock);
455 ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
457 DRM_DEBUG("Entry for tgid %ld exist, hentry %p\n",
460 spin_unlock(&mm->lock);
463 spin_unlock(&mm->lock);
465 DRM_DEBUG("Entry for tgid %ld doesn't exist, will create it\n", tgid);
467 hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL);
469 DRM_DEBUG("Kmalloc failled\n");
473 ret = drm_ht_create(&hentry->ht, 20);
475 DRM_DEBUG("Create hash table failed\n");
479 spin_lock(&mm->lock);
480 ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry);
481 spin_unlock(&mm->lock);
489 static struct psb_gtt_hash_entry *
490 psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
492 struct psb_gtt_hash_entry *tmp;
495 ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp);
497 DRM_DEBUG("Cannot find entry pid %ld\n", tgid);
501 /*remove it from ht*/
502 drm_ht_remove_item(&mm->hash, &tmp->item);
509 static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
511 struct psb_gtt_hash_entry *entry;
513 entry = psb_gtt_mm_remove_ht_locked(mm, tgid);
516 DRM_DEBUG("Invalid entry");
521 drm_ht_remove(&entry->ht);
529 psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht,
531 struct psb_gtt_mem_mapping **hentry)
533 struct drm_hash_item *entry;
534 struct psb_gtt_mem_mapping *mapping;
537 ret = drm_ht_find_item(ht, key, &entry);
539 DRM_DEBUG("Cannot find key %ld\n", key);
543 mapping = container_of(entry, struct psb_gtt_mem_mapping, item);
545 DRM_DEBUG("Invalid entry\n");
554 psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht,
556 struct psb_gtt_mem_mapping *hentry)
558 struct drm_hash_item *item;
559 struct psb_gtt_hash_entry *entry;
563 DRM_DEBUG("hentry is NULL\n");
567 item = &hentry->item;
570 ret = drm_ht_insert_item(ht, item);
572 DRM_DEBUG("insert_item failed\n");
576 entry = container_of(ht, struct psb_gtt_hash_entry, ht);
584 psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm,
585 struct drm_open_hash *ht,
587 struct drm_mm_node *node,
588 struct psb_gtt_mem_mapping **entry)
590 struct psb_gtt_mem_mapping *mapping;
594 DRM_DEBUG("parameter error\n");
598 /*try to get this mem_map */
599 spin_lock(&mm->lock);
600 ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping);
602 DRM_DEBUG("mapping entry for key %ld exists, entry %p\n",
605 spin_unlock(&mm->lock);
608 spin_unlock(&mm->lock);
610 DRM_DEBUG("Mapping entry for key %ld doesn't exist, will create it\n",
613 mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL);
615 DRM_DEBUG("kmalloc failed\n");
619 mapping->node = node;
621 spin_lock(&mm->lock);
622 ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping);
623 spin_unlock(&mm->lock);
631 static struct psb_gtt_mem_mapping *
632 psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key)
634 struct psb_gtt_mem_mapping *tmp;
635 struct psb_gtt_hash_entry *entry;
638 ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp);
640 DRM_DEBUG("Cannot find key %ld\n", key);
644 drm_ht_remove_item(ht, &tmp->item);
646 entry = container_of(ht, struct psb_gtt_hash_entry, ht);
653 static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht,
655 struct drm_mm_node **node)
657 struct psb_gtt_mem_mapping *entry;
659 entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key);
661 DRM_DEBUG("entry is NULL\n");
671 static int psb_gtt_add_node(struct psb_gtt_mm *mm,
674 struct drm_mm_node *node,
675 struct psb_gtt_mem_mapping **entry)
677 struct psb_gtt_hash_entry *hentry;
678 struct psb_gtt_mem_mapping *mapping;
681 ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry);
683 DRM_DEBUG("alloc_insert failed\n");
687 ret = psb_gtt_mm_alloc_insert_mem_mapping(mm,
693 DRM_DEBUG("mapping alloc_insert failed\n");
702 static int psb_gtt_remove_node(struct psb_gtt_mm *mm,
705 struct drm_mm_node **node)
707 struct psb_gtt_hash_entry *hentry;
708 struct drm_mm_node *tmp;
711 spin_lock(&mm->lock);
712 ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
714 DRM_DEBUG("Cannot find entry for pid %ld\n", tgid);
715 spin_unlock(&mm->lock);
718 spin_unlock(&mm->lock);
720 /*remove mapping entry*/
721 spin_lock(&mm->lock);
722 ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht,
726 DRM_DEBUG("remove_free failed\n");
727 spin_unlock(&mm->lock);
733 /*check the count of mapping entry*/
734 if (!hentry->count) {
735 DRM_DEBUG("count of mapping entry is zero, tgid=%ld\n", tgid);
736 psb_gtt_mm_remove_free_ht_locked(mm, tgid);
739 spin_unlock(&mm->lock);
744 static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm,
747 struct drm_mm_node **node)
749 struct drm_mm_node *tmp_node;
753 ret = drm_mm_pre_get(&mm->base);
755 DRM_DEBUG("drm_mm_pre_get error\n");
759 spin_lock(&mm->lock);
760 tmp_node = drm_mm_search_free(&mm->base, pages, align, 1);
761 if (unlikely(!tmp_node)) {
762 DRM_DEBUG("No free node found\n");
763 spin_unlock(&mm->lock);
767 tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align);
768 spin_unlock(&mm->lock);
772 DRM_DEBUG("Node allocation failed\n");
780 static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node)
782 spin_lock(&mm->lock);
783 drm_mm_put_block(node);
784 spin_unlock(&mm->lock);
787 int psb_gtt_map_meminfo(struct drm_device *dev,
788 void *hKernelMemInfo,
794 struct drm_psb_private *dev_priv
795 = (struct drm_psb_private *)dev->dev_private;
796 void *psKernelMemInfo;
797 struct psb_gtt_mm *mm = dev_priv->gtt_mm;
798 struct psb_gtt *pg = dev_priv->pg;
799 uint32_t size, pages, offset_pages;
801 struct drm_mm_node *node;
802 struct page **page_list;
803 struct psb_gtt_mem_mapping *mapping = NULL;
806 ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
808 DRM_DEBUG("Cannot find kernelMemInfo handle %ld\n",
813 DRM_DEBUG("Got psKernelMemInfo %p for handle %lx\n",
814 psKernelMemInfo, (u32)hKernelMemInfo);
815 size = psKernelMemInfo->ui32AllocSize;
816 kmem = psKernelMemInfo->pvLinAddrKM;
817 pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
819 DRM_DEBUG("KerMemInfo size %ld, cpuVadr %lx, pages %ld, osMemHdl %lx\n",
820 size, kmem, pages, psKernelMemInfo->sMemBlk.hOSMemHandle);
823 DRM_DEBUG("kmem is NULL");
826 ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle,
829 DRM_DEBUG("get pages error\n");
833 DRM_DEBUG("get %ld pages\n", pages);
835 /*alloc memory in TT apeture*/
836 ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node);
838 DRM_DEBUG("alloc TT memory error\n");
839 goto failed_pages_alloc;
842 /*update psb_gtt_mm*/
843 ret = psb_gtt_add_node(mm,
844 task_tgid_nr(current),
849 DRM_DEBUG("add_node failed");
850 goto failed_add_node;
853 node = mapping->node;
854 offset_pages = node->start;
856 DRM_DEBUG("get free node for %ld pages, offset %ld pages",
857 pages, offset_pages);
860 psb_gtt_insert_pages(pg, page_list,
861 (unsigned)offset_pages,
867 *offset = offset_pages;
871 psb_gtt_mm_free_mem(mm, node);
878 int psb_gtt_unmap_meminfo(struct drm_device *dev, void * hKernelMemInfo)
880 struct drm_psb_private *dev_priv
881 = (struct drm_psb_private *)dev->dev_private;
882 struct psb_gtt_mm *mm = dev_priv->gtt_mm;
883 struct psb_gtt *pg = dev_priv->pg;
884 uint32_t pages, offset_pages;
885 struct drm_mm_node *node;
888 ret = psb_gtt_remove_node(mm,
889 task_tgid_nr(current),
893 DRM_DEBUG("remove node failed\n");
897 /*remove gtt entries*/
898 offset_pages = node->start;
901 psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
906 psb_gtt_mm_free_mem(mm, node);
910 int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
911 struct drm_file *file_priv)
913 struct psb_gtt_mapping_arg *arg
914 = (struct psb_gtt_mapping_arg *)data;
915 uint32_t *offset_pages = &arg->offset_pages;
919 return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages);
922 int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
923 struct drm_file *file_priv)
926 struct psb_gtt_mapping_arg *arg
927 = (struct psb_gtt_mapping_arg *)data;
931 return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo);
934 int psb_gtt_map_pvr_memory(struct drm_device *dev, unsigned int hHandle,
935 unsigned int ui32TaskId, dma_addr_t *pPages,
936 unsigned int ui32PagesNum, unsigned int *ui32Offset)
938 struct drm_psb_private *dev_priv = dev->dev_private;
939 struct psb_gtt_mm *mm = dev_priv->gtt_mm;
940 struct psb_gtt *pg = dev_priv->pg;
941 uint32_t size, pages, offset_pages;
942 struct drm_mm_node *node = NULL;
943 struct psb_gtt_mem_mapping *mapping = NULL;
946 size = ui32PagesNum * PAGE_SIZE;
949 /*alloc memory in TT apeture*/
950 ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node);
952 DRM_DEBUG("alloc TT memory error\n");
953 goto failed_pages_alloc;
956 /*update psb_gtt_mm*/
957 ret = psb_gtt_add_node(mm,
963 DRM_DEBUG("add_node failed");
964 goto failed_add_node;
967 node = mapping->node;
968 offset_pages = node->start;
970 DRM_DEBUG("get free node for %ld pages, offset %ld pages",
971 pages, offset_pages);
974 psb_gtt_insert_phys_addresses(pg, pPages, (unsigned)offset_pages,
975 (unsigned)ui32PagesNum, 0);
977 *ui32Offset = offset_pages;
981 psb_gtt_mm_free_mem(mm, node);
987 int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle,
988 unsigned int ui32TaskId)
990 struct drm_psb_private *dev_priv = dev->dev_private;
991 struct psb_gtt_mm *mm = dev_priv->gtt_mm;
992 struct psb_gtt *pg = dev_priv->pg;
993 uint32_t pages, offset_pages;
994 struct drm_mm_node *node;
997 ret = psb_gtt_remove_node(mm, (u32)ui32TaskId, (u32)hHandle, &node);
999 printk(KERN_ERR "remove node failed\n");
1003 /*remove gtt entries*/
1004 offset_pages = node->start;
1007 psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
1010 psb_gtt_mm_free_mem(mm, node);