15718399fSFrançois Tigeot /************************************************************************** 25718399fSFrançois Tigeot * 35718399fSFrançois Tigeot * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA 45718399fSFrançois Tigeot * All Rights Reserved. 55718399fSFrançois Tigeot * 65718399fSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 75718399fSFrançois Tigeot * copy of this software and associated documentation files (the 85718399fSFrançois Tigeot * "Software"), to deal in the Software without restriction, including 95718399fSFrançois Tigeot * without limitation the rights to use, copy, modify, merge, publish, 105718399fSFrançois Tigeot * distribute, sub license, and/or sell copies of the Software, and to 115718399fSFrançois Tigeot * permit persons to whom the Software is furnished to do so, subject to 125718399fSFrançois Tigeot * the following conditions: 135718399fSFrançois Tigeot * 145718399fSFrançois Tigeot * The above copyright notice and this permission notice (including the 155718399fSFrançois Tigeot * next paragraph) shall be included in all copies or substantial portions 165718399fSFrançois Tigeot * of the Software. 175718399fSFrançois Tigeot * 185718399fSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 195718399fSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 205718399fSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 215718399fSFrançois Tigeot * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 225718399fSFrançois Tigeot * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 235718399fSFrançois Tigeot * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 245718399fSFrançois Tigeot * USE OR OTHER DEALINGS IN THE SOFTWARE. 255718399fSFrançois Tigeot * 265718399fSFrançois Tigeot **************************************************************************/ 275718399fSFrançois Tigeot /* 285718399fSFrançois Tigeot * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 295718399fSFrançois Tigeot * Keith Packard. 305718399fSFrançois Tigeot * 315718399fSFrançois Tigeot * $FreeBSD: head/sys/dev/drm2/ttm/ttm_agp_backend.c 247835 2013-03-05 09:49:34Z kib $ 325718399fSFrançois Tigeot */ 335718399fSFrançois Tigeot 34c19c6249SFrançois Tigeot #define pr_fmt(fmt) "[TTM] " fmt 35c19c6249SFrançois Tigeot 36216f7a2cSFrançois Tigeot #include <drm/ttm/ttm_module.h> 37216f7a2cSFrançois Tigeot #include <drm/ttm/ttm_bo_driver.h> 38216f7a2cSFrançois Tigeot #include <drm/ttm/ttm_page_alloc.h> 395718399fSFrançois Tigeot #ifdef TTM_HAS_AGP 40216f7a2cSFrançois Tigeot #include <drm/ttm/ttm_placement.h> 415718399fSFrançois Tigeot 425718399fSFrançois Tigeot struct ttm_agp_backend { 435718399fSFrançois Tigeot struct ttm_tt ttm; 445718399fSFrançois Tigeot struct agp_memory *mem; 455718399fSFrançois Tigeot device_t bridge; 465718399fSFrançois Tigeot }; 475718399fSFrançois Tigeot 485718399fSFrançois Tigeot static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) 495718399fSFrançois Tigeot { 505718399fSFrançois Tigeot struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm); 515718399fSFrançois Tigeot struct drm_mm_node *node = bo_mem->mm_node; 525718399fSFrançois Tigeot struct agp_memory *mem; 535718399fSFrançois Tigeot int ret, cached = (bo_mem->placement & TTM_PL_FLAG_CACHED); 545718399fSFrançois Tigeot unsigned i; 555718399fSFrançois Tigeot 565718399fSFrançois Tigeot mem = agp_alloc_memory(agp_be->bridge, AGP_USER_MEMORY, ttm->num_pages); 575718399fSFrançois Tigeot if (unlikely(mem == NULL)) 585718399fSFrançois Tigeot return -ENOMEM; 595718399fSFrançois Tigeot 605718399fSFrançois Tigeot mem->page_count = 0; 615718399fSFrançois Tigeot for (i = 0; i < ttm->num_pages; i++) { 625718399fSFrançois Tigeot vm_page_t page = ttm->pages[i]; 635718399fSFrançois Tigeot 645718399fSFrançois Tigeot if (!page) 655718399fSFrançois Tigeot page = ttm->dummy_read_page; 665718399fSFrançois Tigeot 675718399fSFrançois Tigeot mem->pages[mem->page_count++] = page; 685718399fSFrançois Tigeot } 695718399fSFrançois Tigeot agp_be->mem = mem; 705718399fSFrançois Tigeot 715718399fSFrançois Tigeot mem->is_flushed = 1; 725718399fSFrançois Tigeot mem->type = (cached) ? AGP_USER_CACHED_MEMORY : AGP_USER_MEMORY; 735718399fSFrançois Tigeot 745718399fSFrançois Tigeot ret = agp_bind_memory(mem, node->start); 755718399fSFrançois Tigeot if (ret) 765718399fSFrançois Tigeot pr_err("AGP Bind memory failed\n"); 775718399fSFrançois Tigeot 785718399fSFrançois Tigeot return ret; 795718399fSFrançois Tigeot } 805718399fSFrançois Tigeot 815718399fSFrançois Tigeot static int ttm_agp_unbind(struct ttm_tt *ttm) 825718399fSFrançois Tigeot { 835718399fSFrançois Tigeot struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm); 845718399fSFrançois Tigeot 855718399fSFrançois Tigeot if (agp_be->mem) { 865718399fSFrançois Tigeot if (agp_be->mem->is_bound) 875718399fSFrançois Tigeot return agp_unbind_memory(agp_be->mem); 885718399fSFrançois Tigeot agp_free_memory(agp_be->mem); 895718399fSFrançois Tigeot agp_be->mem = NULL; 905718399fSFrançois Tigeot } 915718399fSFrançois Tigeot return 0; 925718399fSFrançois Tigeot } 935718399fSFrançois Tigeot 945718399fSFrançois Tigeot static void ttm_agp_destroy(struct ttm_tt *ttm) 955718399fSFrançois Tigeot { 965718399fSFrançois Tigeot struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm); 975718399fSFrançois Tigeot 985718399fSFrançois Tigeot if (agp_be->mem) 995718399fSFrançois Tigeot ttm_agp_unbind(ttm); 1005718399fSFrançois Tigeot ttm_tt_fini(ttm); 101*175896dfSzrj kfree(agp_be); 1025718399fSFrançois Tigeot } 1035718399fSFrançois Tigeot 1045718399fSFrançois Tigeot static struct ttm_backend_func ttm_agp_func = { 1055718399fSFrançois Tigeot .bind = ttm_agp_bind, 1065718399fSFrançois Tigeot .unbind = ttm_agp_unbind, 1075718399fSFrançois Tigeot .destroy = ttm_agp_destroy, 1085718399fSFrançois Tigeot }; 1095718399fSFrançois Tigeot 1105718399fSFrançois Tigeot struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev, 1115718399fSFrançois Tigeot device_t bridge, 1125718399fSFrançois Tigeot unsigned long size, uint32_t page_flags, 1135718399fSFrançois Tigeot vm_page_t dummy_read_page) 1145718399fSFrançois Tigeot { 1155718399fSFrançois Tigeot struct ttm_agp_backend *agp_be; 1165718399fSFrançois Tigeot 1175a3b77d5SFrançois Tigeot agp_be = kmalloc(sizeof(*agp_be), M_DRM, M_WAITOK | M_ZERO); 118c19c6249SFrançois Tigeot if (!agp_be) 119c19c6249SFrançois Tigeot return NULL; 1205718399fSFrançois Tigeot 1215718399fSFrançois Tigeot agp_be->mem = NULL; 1225718399fSFrançois Tigeot agp_be->bridge = bridge; 1235718399fSFrançois Tigeot agp_be->ttm.func = &ttm_agp_func; 1245718399fSFrançois Tigeot 1255718399fSFrançois Tigeot if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) { 1263e260345SSascha Wildner kfree(agp_be); 1275718399fSFrançois Tigeot return NULL; 1285718399fSFrançois Tigeot } 1295718399fSFrançois Tigeot 1305718399fSFrançois Tigeot return &agp_be->ttm; 1315718399fSFrançois Tigeot } 132c19c6249SFrançois Tigeot EXPORT_SYMBOL(ttm_agp_tt_create); 1335718399fSFrançois Tigeot 1345718399fSFrançois Tigeot int ttm_agp_tt_populate(struct ttm_tt *ttm) 1355718399fSFrançois Tigeot { 1365718399fSFrançois Tigeot if (ttm->state != tt_unpopulated) 1375718399fSFrançois Tigeot return 0; 1385718399fSFrançois Tigeot 1395718399fSFrançois Tigeot return ttm_pool_populate(ttm); 1405718399fSFrançois Tigeot } 141c19c6249SFrançois Tigeot EXPORT_SYMBOL(ttm_agp_tt_populate); 1425718399fSFrançois Tigeot 1435718399fSFrançois Tigeot void ttm_agp_tt_unpopulate(struct ttm_tt *ttm) 1445718399fSFrançois Tigeot { 1455718399fSFrançois Tigeot ttm_pool_unpopulate(ttm); 1465718399fSFrançois Tigeot } 147c19c6249SFrançois Tigeot EXPORT_SYMBOL(ttm_agp_tt_unpopulate); 1485718399fSFrançois Tigeot 1495718399fSFrançois Tigeot #endif 150