All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qiang Yu <yuq825@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Simon Shields <simon@lineageos.org>, Marek Vasut <marex@denx.de>,
	Connor Abbott <cwabbott0@gmail.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Andrei Paulau <7134956@gmail.com>,
	Vasily Khoruzhick <anarsoul@gmail.com>,
	Qiang Yu <yuq825@gmail.com>, Erico Nunes <nunes.erico@gmail.com>
Subject: [PATCH RFC 18/24] drm/lima: add TTM subsystem functions
Date: Sat, 19 May 2018 14:52:37 +0800	[thread overview]
Message-ID: <20180519065243.27600-19-yuq825@gmail.com> (raw)
In-Reply-To: <20180519065243.27600-1-yuq825@gmail.com>

Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
 drivers/gpu/drm/lima/lima_ttm.c | 409 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/lima/lima_ttm.h |  44 ++++
 2 files changed, 453 insertions(+)
 create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
 create mode 100644 drivers/gpu/drm/lima/lima_ttm.h

diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c
new file mode 100644
index 000000000000..5325f3f48ae7
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/mm.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+#include "lima_drv.h"
+#include "lima_device.h"
+#include "lima_object.h"
+
+
+static int lima_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+	return ttm_mem_global_init(ref->object);
+}
+
+static void lima_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+	ttm_mem_global_release(ref->object);
+}
+
+static int lima_ttm_global_init(struct lima_device *dev)
+{
+	struct drm_global_reference *global_ref;
+	int err;
+
+	dev->mman.mem_global_referenced = false;
+	global_ref = &dev->mman.mem_global_ref;
+	global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+	global_ref->size = sizeof(struct ttm_mem_global);
+	global_ref->init = &lima_ttm_mem_global_init;
+	global_ref->release = &lima_ttm_mem_global_release;
+
+	err = drm_global_item_ref(global_ref);
+	if (err != 0) {
+		dev_err(dev->dev, "Failed setting up TTM memory accounting "
+			"subsystem.\n");
+		return err;
+	}
+
+	dev->mman.bo_global_ref.mem_glob =
+		dev->mman.mem_global_ref.object;
+	global_ref = &dev->mman.bo_global_ref.ref;
+	global_ref->global_type = DRM_GLOBAL_TTM_BO;
+	global_ref->size = sizeof(struct ttm_bo_global);
+	global_ref->init = &ttm_bo_global_init;
+	global_ref->release = &ttm_bo_global_release;
+	err = drm_global_item_ref(global_ref);
+	if (err != 0) {
+		dev_err(dev->dev, "Failed setting up TTM BO subsystem.\n");
+		drm_global_item_unref(&dev->mman.mem_global_ref);
+		return err;
+	}
+
+	dev->mman.mem_global_referenced = true;
+	return 0;
+}
+
+static void lima_ttm_global_fini(struct lima_device *dev)
+{
+	if (dev->mman.mem_global_referenced) {
+		drm_global_item_unref(&dev->mman.bo_global_ref.ref);
+		drm_global_item_unref(&dev->mman.mem_global_ref);
+		dev->mman.mem_global_referenced = false;
+	}
+}
+
+struct lima_tt_mgr {
+	spinlock_t lock;
+	unsigned long available;
+};
+
+static int lima_ttm_bo_man_init(struct ttm_mem_type_manager *man,
+				unsigned long p_size)
+{
+	struct lima_tt_mgr *mgr;
+
+	mgr = kmalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return -ENOMEM;
+
+	spin_lock_init(&mgr->lock);
+	mgr->available = p_size;
+	man->priv = mgr;
+	return 0;
+}
+
+static int lima_ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
+{
+	struct lima_tt_mgr *mgr = man->priv;
+
+	kfree(mgr);
+	man->priv = NULL;
+	return 0;
+}
+
+static int lima_ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
+				    struct ttm_buffer_object *bo,
+				    const struct ttm_place *place,
+				    struct ttm_mem_reg *mem)
+{
+	struct lima_tt_mgr *mgr = man->priv;
+
+	/* don't exceed the mem limit */
+	spin_lock(&mgr->lock);
+	if (mgr->available < mem->num_pages) {
+		spin_unlock(&mgr->lock);
+		return 0;
+	}
+	mgr->available -= mem->num_pages;
+	spin_unlock(&mgr->lock);
+
+	/* just fake a non-null pointer to tell caller success */
+	mem->mm_node = (void *)1;
+	return 0;
+}
+
+static void lima_ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
+				     struct ttm_mem_reg *mem)
+{
+	struct lima_tt_mgr *mgr = man->priv;
+
+	spin_lock(&mgr->lock);
+	mgr->available += mem->num_pages;
+	spin_unlock(&mgr->lock);
+
+	mem->mm_node = NULL;
+}
+
+static void lima_ttm_bo_man_debug(struct ttm_mem_type_manager *man,
+				  struct drm_printer *printer)
+{
+}
+
+static const struct ttm_mem_type_manager_func lima_bo_manager_func = {
+	.init = lima_ttm_bo_man_init,
+	.takedown = lima_ttm_bo_man_takedown,
+	.get_node = lima_ttm_bo_man_get_node,
+	.put_node = lima_ttm_bo_man_put_node,
+	.debug = lima_ttm_bo_man_debug
+};
+
+static int lima_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+			      struct ttm_mem_type_manager *man)
+{
+	struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		/* System memory */
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case TTM_PL_TT:
+		man->func = &lima_bo_manager_func;
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	default:
+		dev_err(dev->dev, "Unsupported memory type %u\n",
+			(unsigned int)type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int lima_ttm_backend_bind(struct ttm_tt *ttm,
+				 struct ttm_mem_reg *bo_mem)
+{
+	return 0;
+}
+
+static int lima_ttm_backend_unbind(struct ttm_tt *ttm)
+{
+	return 0;
+}
+
+static void lima_ttm_backend_destroy(struct ttm_tt *ttm)
+{
+	struct lima_ttm_tt *tt = (void *)ttm;
+
+	ttm_dma_tt_fini(&tt->ttm);
+	kfree(tt);
+}
+
+static struct ttm_backend_func lima_ttm_backend_func = {
+	.bind = &lima_ttm_backend_bind,
+	.unbind = &lima_ttm_backend_unbind,
+	.destroy = &lima_ttm_backend_destroy,
+};
+
+static struct ttm_tt *lima_ttm_tt_create(struct ttm_buffer_object *bo,
+					 uint32_t page_flags)
+{
+	struct lima_ttm_tt *tt;
+
+	tt = kzalloc(sizeof(struct lima_ttm_tt), GFP_KERNEL);
+	if (tt == NULL)
+		return NULL;
+
+	tt->ttm.ttm.func = &lima_ttm_backend_func;
+
+	if (ttm_sg_tt_init(&tt->ttm, bo, page_flags)) {
+		kfree(tt);
+		return NULL;
+	}
+
+	return &tt->ttm.ttm;
+}
+
+static int lima_ttm_tt_populate(struct ttm_tt *ttm,
+				struct ttm_operation_ctx *ctx)
+{
+	struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+	struct lima_ttm_tt *tt = (void *)ttm;
+	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+	if (slave) {
+		drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
+						 tt->ttm.dma_address,
+						 ttm->num_pages);
+		ttm->state = tt_unbound;
+		return 0;
+	}
+
+	return ttm_populate_and_map_pages(dev->dev, &tt->ttm, ctx);
+}
+
+static void lima_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+	struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+	struct lima_ttm_tt *tt = (void *)ttm;
+	bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+	if (slave)
+		return;
+
+	ttm_unmap_and_unpopulate_pages(dev->dev, &tt->ttm);
+}
+
+static int lima_invalidate_caches(struct ttm_bo_device *bdev,
+				  uint32_t flags)
+{
+	struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+	dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+	return 0;
+}
+
+static void lima_evict_flags(struct ttm_buffer_object *tbo,
+			     struct ttm_placement *placement)
+{
+	struct lima_bo *bo = ttm_to_lima_bo(tbo);
+	struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+	dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static int lima_verify_access(struct ttm_buffer_object *tbo,
+			      struct file *filp)
+{
+	struct lima_bo *bo = ttm_to_lima_bo(tbo);
+
+	return drm_vma_node_verify_access(&bo->gem.vma_node,
+					  filp->private_data);
+}
+
+static int lima_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
+				   struct ttm_mem_reg *mem)
+{
+	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+
+	mem->bus.addr = NULL;
+	mem->bus.offset = 0;
+	mem->bus.size = mem->num_pages << PAGE_SHIFT;
+	mem->bus.base = 0;
+	mem->bus.is_iomem = false;
+
+	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+		return -EINVAL;
+
+	switch (mem->mem_type) {
+	case TTM_PL_SYSTEM:
+	case TTM_PL_TT:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void lima_ttm_io_mem_free(struct ttm_bo_device *bdev,
+				 struct ttm_mem_reg *mem)
+{
+
+}
+
+static void lima_bo_move_notify(struct ttm_buffer_object *tbo, bool evict,
+				struct ttm_mem_reg *new_mem)
+{
+	struct lima_bo *bo = ttm_to_lima_bo(tbo);
+	struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+	if (evict)
+		dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static void lima_bo_swap_notify(struct ttm_buffer_object *tbo)
+{
+	struct lima_bo *bo = ttm_to_lima_bo(tbo);
+	struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+	dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static struct ttm_bo_driver lima_bo_driver = {
+	.ttm_tt_create = lima_ttm_tt_create,
+	.ttm_tt_populate = lima_ttm_tt_populate,
+	.ttm_tt_unpopulate = lima_ttm_tt_unpopulate,
+	.invalidate_caches = lima_invalidate_caches,
+	.init_mem_type = lima_init_mem_type,
+	.eviction_valuable = ttm_bo_eviction_valuable,
+	.evict_flags = lima_evict_flags,
+	.verify_access = lima_verify_access,
+	.io_mem_reserve = lima_ttm_io_mem_reserve,
+	.io_mem_free = lima_ttm_io_mem_free,
+	.move_notify = lima_bo_move_notify,
+	.swap_notify = lima_bo_swap_notify,
+};
+
+int lima_ttm_init(struct lima_device *dev)
+{
+	int err;
+	bool need_dma32;
+	u64 gtt_size;
+
+	err = lima_ttm_global_init(dev);
+	if (err)
+		return err;
+
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
+	need_dma32 = false;
+#else
+	need_dma32 = true;
+#endif
+
+	err = ttm_bo_device_init(&dev->mman.bdev,
+				 dev->mman.bo_global_ref.ref.object,
+				 &lima_bo_driver,
+				 dev->ddev->anon_inode->i_mapping,
+				 DRM_FILE_PAGE_OFFSET,
+				 need_dma32);
+	if (err) {
+		dev_err(dev->dev, "failed initializing buffer object "
+			"driver(%d).\n", err);
+		goto err_out0;
+	}
+
+	if (lima_max_mem < 0) {
+		struct sysinfo si;
+		si_meminfo(&si);
+		/* TODO: better to have lower 32 mem size */
+		gtt_size = min(((u64)si.totalram * si.mem_unit * 3/4),
+			       0x100000000ULL);
+	}
+	else
+		gtt_size = (u64)lima_max_mem << 20;
+
+	err = ttm_bo_init_mm(&dev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
+	if (err) {
+		dev_err(dev->dev, "Failed initializing GTT heap.\n");
+		goto err_out1;
+	}
+	return 0;
+
+err_out1:
+	ttm_bo_device_release(&dev->mman.bdev);
+err_out0:
+	lima_ttm_global_fini(dev);
+	return err;
+}
+
+void lima_ttm_fini(struct lima_device *dev)
+{
+	ttm_bo_device_release(&dev->mman.bdev);
+	lima_ttm_global_fini(dev);
+	dev_info(dev->dev, "ttm finalized\n");
+}
diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h
new file mode 100644
index 000000000000..1d36d06a47a3
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_TTM_H__
+#define __LIMA_TTM_H__
+
+#include <drm/ttm/ttm_bo_driver.h>
+
+struct lima_mman {
+	struct ttm_bo_global_ref bo_global_ref;
+	struct drm_global_reference mem_global_ref;
+	struct ttm_bo_device bdev;
+	bool mem_global_referenced;
+};
+
+struct lima_ttm_tt {
+	struct ttm_dma_tt ttm;
+};
+
+struct lima_device;
+struct lima_bo;
+
+int lima_ttm_init(struct lima_device *dev);
+void lima_ttm_fini(struct lima_device *dev);
+
+#endif
-- 
2.17.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2018-05-19  6:54 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-19  6:52 [PATCH RFC 00/24] Lima DRM driver Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 01/24] ARM: dts: add gpu node to exynos4 Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 02/24] dt-bindings: add switch-delay property for mali-utgard Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 03/24] arm64/dts: add switch-delay for meson mali Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 04/24] " Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 05/24] Revert "drm: Nerf the preclose callback for modern drivers" Qiang Yu
2018-05-21 19:37   ` Eric Anholt
2018-05-22  1:04     ` Qiang Yu
2018-05-23  9:04       ` Daniel Vetter
2018-05-23 12:59         ` Qiang Yu
2018-05-23 20:31           ` Daniel Vetter
2018-05-24  1:18             ` Qiang Yu
2018-05-24  7:51               ` Daniel Vetter
2018-05-24  8:55                 ` Qiang Yu
2018-05-30 18:13                   ` Eric Anholt
2018-05-31 14:04                     ` Qiang Yu
2018-05-31 17:51                       ` Eric Anholt
2018-05-31 18:04                         ` Keith Packard
2018-06-01  2:03                           ` Qiang Yu
2018-06-01  1:58                         ` Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 06/24] drm/lima: add lima uapi header Qiang Yu
2018-05-21 19:51   ` Eric Anholt
2018-05-22  1:33     ` Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 07/24] drm/lima: add mali 4xx GPU hardware regs Qiang Yu
2018-05-19 11:20   ` Marek Vasut
2018-05-19  6:52 ` [PATCH RFC 08/24] drm/lima: add lima core driver Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 09/24] drm/lima: add GPU device functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 10/24] drm/lima: add PMU related functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 11/24] drm/lima: add L2 cache functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 12/24] drm/lima: add GP related functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 13/24] drm/lima: add PP " Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 14/24] drm/lima: add MMU " Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 15/24] drm/lima: add BCAST related function Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 16/24] drm/lima: add DLBU related functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 17/24] drm/lima: add GPU virtual memory space handing Qiang Yu
2018-05-19  6:52 ` Qiang Yu [this message]
2018-05-19  6:52 ` [PATCH RFC 19/24] drm/lima: add buffer object functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 20/24] drm/lima: add GEM related functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 21/24] drm/lima: add GEM Prime " Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 22/24] drm/lima: add GPU schedule using DRM_SCHED Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 23/24] drm/lima: add context related functions Qiang Yu
2018-05-19  6:52 ` [PATCH RFC 24/24] drm/lima: add makefile and kconfig Qiang Yu
  -- strict thread matches above, loose matches on Subject: below --
2018-05-18  9:27 [PATCH RFC 00/24] Lima DRM driver Qiang Yu
2018-05-18  9:28 ` [PATCH RFC 18/24] drm/lima: add TTM subsystem functions Qiang Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180519065243.27600-19-yuq825@gmail.com \
    --to=yuq825@gmail.com \
    --cc=7134956@gmail.com \
    --cc=anarsoul@gmail.com \
    --cc=cwabbott0@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=marex@denx.de \
    --cc=narmstrong@baylibre.com \
    --cc=nunes.erico@gmail.com \
    --cc=simon@lineageos.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.