summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/qxl/qxl_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_gem.c')
-rw-r--r--drivers/gpu/drm/qxl/qxl_gem.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c
new file mode 100644
index 00000000000..7ef7b6f1963
--- /dev/null
+++ b/drivers/gpu/drm/qxl/qxl_gem.c
@@ -0,0 +1,155 @@
+#include "drmP.h"
+#include "drm.h"
+#include "qxl_drm.h"
+#include "qxl_drv.h"
+#include "qxl_object.h"
+
+int qxl_gem_object_init(struct drm_gem_object *obj)
+{
+ /* we do nothings here */
+ return 0;
+}
+
+void qxl_gem_object_free(struct drm_gem_object *gobj)
+{
+ struct qxl_bo *qobj = gem_to_qxl_bo(gobj);
+
+ if (qobj) {
+ /* or unref? */
+ qxl_bo_free(qobj);
+ }
+}
+
+int qxl_gem_object_create(struct qxl_device *qdev, int size,
+ int alignment, int initial_domain,
+ bool discardable, bool kernel,
+ struct drm_gem_object **obj)
+{
+ struct qxl_bo *qbo;
+ int r;
+
+ *obj = NULL;
+ /* At least align on page size */
+ if (alignment < PAGE_SIZE)
+ alignment = PAGE_SIZE;
+ r = qxl_bo_create(qdev, size, kernel, initial_domain, &qbo);
+ if (r) {
+ if (r != -ERESTARTSYS)
+ DRM_ERROR(
+ "Failed to allocate GEM object (%d, %d, %u, %d)\n",
+ size, initial_domain, alignment, r);
+ return r;
+ }
+ *obj = &qbo->gem_base;
+
+ mutex_lock(&qbo->qdev->gem.mutex);
+ list_add_tail(&qbo->list, &qdev->gem.objects);
+ mutex_unlock(&qbo->qdev->gem.mutex);
+
+ return 0;
+}
+
+int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
+ struct drm_file *file_priv,
+ u32 domain,
+ size_t size,
+ struct qxl_bo **qobj,
+ uint32_t *handle)
+{
+ struct drm_gem_object *gobj;
+ int r;
+
+ BUG_ON(!qobj);
+ BUG_ON(!handle);
+
+ r = qxl_gem_object_create(qdev, size, 0,
+ domain,
+ false, false,
+ &gobj);
+ if (r)
+ return -ENOMEM;
+ r = drm_gem_handle_create(file_priv, gobj, handle);
+ if (r)
+ return r;
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(gobj);
+ *qobj = gem_to_qxl_bo(gobj);
+ qxl_bo_kmap(*qobj, NULL);
+ return 0;
+}
+
+int qxl_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
+ uint64_t *gpu_addr)
+{
+ struct qxl_bo *qobj = obj->driver_private;
+ int r;
+
+ r = qxl_bo_reserve(qobj, false);
+ if (unlikely(r != 0))
+ return r;
+ r = qxl_bo_pin(qobj, pin_domain, gpu_addr);
+ qxl_bo_unreserve(qobj);
+ return r;
+}
+
+void qxl_gem_object_unpin(struct drm_gem_object *obj)
+{
+ struct qxl_bo *qobj = obj->driver_private;
+ int r;
+
+ r = qxl_bo_reserve(qobj, false);
+ if (likely(r == 0)) {
+ qxl_bo_unpin(qobj);
+ qxl_bo_unreserve(qobj);
+ }
+}
+
+int qxl_gem_set_domain(struct drm_gem_object *gobj,
+ uint32_t rdomain, uint32_t wdomain)
+{
+ struct qxl_bo *qobj;
+ uint32_t domain;
+ int r;
+
+ /* FIXME: reeimplement */
+ qobj = gobj->driver_private;
+ /* work out where to validate the buffer to */
+ domain = wdomain;
+ if (!domain)
+ domain = rdomain;
+ if (!domain) {
+ /* Do nothings */
+ pr_warn("Set domain withou domain !\n");
+ return 0;
+ }
+ if (domain == QXL_GEM_DOMAIN_CPU) {
+ /* Asking for cpu access wait for object idle */
+ r = qxl_bo_wait(qobj, NULL, false);
+ if (r) {
+ pr_err("Failed to wait for object !\n");
+ return r;
+ }
+ }
+ return 0;
+}
+
+int qxl_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv)
+{
+ return 0;
+}
+
+void qxl_gem_object_close(struct drm_gem_object *obj,
+ struct drm_file *file_priv)
+{
+}
+
+int qxl_gem_init(struct qxl_device *qdev)
+{
+ INIT_LIST_HEAD(&qdev->gem.objects);
+ return 0;
+}
+
+void qxl_gem_fini(struct qxl_device *qdev)
+{
+ qxl_bo_force_delete(qdev);
+}