Path: blob/21.2-virgl/src/etnaviv/drm/etnaviv_device.c
4564 views
/*1* Copyright (C) 2014 Etnaviv Project2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Christian Gmeiner <[email protected]>24*/2526#include "util/hash_table.h"27#include "util/os_file.h"2829#include "etnaviv_priv.h"30#include "etnaviv_drmif.h"3132struct etna_device *etna_device_new(int fd)33{34struct etna_device *dev = calloc(sizeof(*dev), 1);35struct drm_etnaviv_param req = {36.param = ETNAVIV_PARAM_SOFTPIN_START_ADDR,37};38int ret;3940if (!dev)41return NULL;4243p_atomic_set(&dev->refcnt, 1);44dev->fd = fd;45dev->handle_table = _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);46dev->name_table = _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);47etna_bo_cache_init(&dev->bo_cache);4849ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_GET_PARAM, &req, sizeof(req));50if (!ret && req.value != ~0ULL) {51const uint64_t _4GB = 1ull << 32;5253util_vma_heap_init(&dev->address_space, req.value, _4GB - req.value);54dev->use_softpin = 1;55}5657return dev;58}5960/* like etna_device_new() but creates it's own private dup() of the fd61* which is close()d when the device is finalized. */62struct etna_device *etna_device_new_dup(int fd)63{64int dup_fd = os_dupfd_cloexec(fd);65struct etna_device *dev = etna_device_new(dup_fd);6667if (dev)68dev->closefd = 1;69else70close(dup_fd);7172return dev;73}7475struct etna_device *etna_device_ref(struct etna_device *dev)76{77p_atomic_inc(&dev->refcnt);7879return dev;80}8182static void etna_device_del_impl(struct etna_device *dev)83{84etna_bo_cache_cleanup(&dev->bo_cache, 0);8586if (dev->use_softpin)87util_vma_heap_finish(&dev->address_space);8889_mesa_hash_table_destroy(dev->handle_table, NULL);90_mesa_hash_table_destroy(dev->name_table, NULL);9192if (dev->closefd)93close(dev->fd);9495free(dev);96}9798void etna_device_del_locked(struct etna_device *dev)99{100simple_mtx_assert_locked(&etna_drm_table_lock);101102if (!p_atomic_dec_zero(&dev->refcnt))103return;104105etna_device_del_impl(dev);106}107108void etna_device_del(struct etna_device *dev)109{110if (!p_atomic_dec_zero(&dev->refcnt))111return;112113simple_mtx_lock(&etna_drm_table_lock);114etna_device_del_impl(dev);115simple_mtx_unlock(&etna_drm_table_lock);116}117118int etna_device_fd(struct etna_device *dev)119{120return dev->fd;121}122123bool etnaviv_device_softpin_capable(struct etna_device *dev)124{125return !!dev->use_softpin;126}127128129